[AI 수학적 기초]텐서연산(아다마르 곱, 기초연산)

OasisGorilla·2024년 10월 8일
0

기초적인 텐서 연산에 대해 공부했다.
곱, 더하기, 아마다르 곱, 리덕션, 내적을 배웠으며
실제 사용되는 텐서연산은 보다 다양한 종류가 있다고 한다.

텐서의 곱

여기서 말하는 곱은 텐서끼리의 곱이 아닌, 텐서와 스칼라의 곱이다.
스칼라는 텐서의 모양을 유지하면서 모든 요소에 더해지거나 곱해진다.

X = np.array([[25, 2], [5, 26], [3, 7]])
X_pt = torch.tensor(X)
X_pt2 = torch.tensor([[25, 2], [5, 26], [3, 7]])

# 스칼라는 텐서의 모양을 유지하면서 모든 요소에 더해지거나 곱해진다.
print(X * 2)

print(X + 2)

print(X * 2 + 2)

print(X_pt)
print(X_pt2)

print(X_pt * 2 + 2) # 파이썬의 *, + 연산자가 오버로드된다. 
print(torch.add(torch.mul(X_pt, 2), 2)) # 위 코드랑 같은 코드

위와 같이 *나 +연산자를 사용하여 간단하게 텐서연산을 사용할 수 있으며,
이게 가능한 이유는 위 연산자가 파이썬에서 오버로드되기 때문에
텐서와 스칼라 연산에 맞게 그 기능이 변경되어서 그렇다고 한다.
겉보기엔 그냥 곱하기와 더하기 기호지만 torch.add()나 torch.mul()과 같은 기능을 하고 있다는 것이다.

아다마르 곱(Hadamard product)

동일한 크기의 텐서끼리 각 위치에 대응하는 원소를 곱해주는 연산.

위 코드에서 이어서 아래와 같이 작성해서 테스트했다.

A = X + 2

print(A + X)

print(A * X) # 아다마르 곱 연산, 행렬의 각 원소끼리의 곱

A_pt = X_pt + 2

print(A_pt * X_pt) # PyTorch에서의 아다마르 곱 연산

위 코드를 보면 X와 shape가 같은 A를 만들어서 *연산자로 둘을 곱해준다.
그러면 numpy에서 둘의 모양이 같은 것을 인식하고 아다마르 곱 기능을 오버라이드 하는 것으로 보인다.

shape가 다르면 애초에 오류가 뜬다.
그러나 이전에 numpy 배열에 대해 공부했던 글에서 알아본 broadcasting 기술이 여기서 사용될 수 있다.

(1, 3)shape의 텐서 A와 (3, 1)shape의 텐서 B를 * 연산자로 곱해주면 아래와 같은 결과가 나온다.

C = np.array([[1, 2, 3]]) # (1, 3)
D = np.array([[4], [5], [6]]) # (3, 1)

print(f"* 결과 : \n{C * D}")

"""
* 결과 :
[[ 4  8 12]
[ 5 10 15]
[ 6 12 18]]
"""

모양이 달라도 broadcasting 조건을 충족하기 때문에 stretched 되어서 배열 모양이 자동으로 맞춰진 것이다.
C는 [[1, 2, 3], [1, 2, 3], [1, 2, 3]]으로
D는 [[4, 4, 4], [5, 5, 5], [6, 6, 6]]으로 brocasting 되어
같은 모양이 됐으므로 아다마르 곱이 가능해진다.

이 또한 NumPy님의 은혜겠지요...

0개의 댓글