[PyTorch] Tensor간 연산

Young·2024년 8월 6일

PyTorch

목록 보기
5/7

1. 산술 연산

  • Matrix의 같은 위치 값(요소)에 대하여 해당 연산 수행
  • 만약 크기가 다를 경우 같은 크기로 확장하여 연산 수행
연산함수In-Place
덧셈torch.add(a, b)a.add_(b)
뺄셈torch.sub(a, b)a.sub_(b)
스칼라곱torch.mul(a, b)a.mul_(b)
나누기torch.div(a, b)a.div_(b)
거듭제곱torch.pow(a, b)a.pow_(b)
거듭제곱근torch.pow(a, 1/n)a.pow_(1/n)

### Example ###

t = torch.tensor([[1, 2], [3, 4]])
u = torch.tensor([[10, 20], [30, 40]])
v = torch.tensor([10, 100])
s = torch.tensor([[10], [20]])

torch.add(t, u) # tensor([[11, 22], [33, 44]])
torch.sub(u, s) # tensor([[0, 10], [10, 20]])
torch.mul(t, v) # tensor([[10, 200], [30, 400]])
torch.div(u, s) # tensor([[1.0, 2.0], [1.5, 2.0]])

나누기 연산에서 발생하는 Runtime Error
RuntimeError: result type Float can't be cast to the desired output type Long
데이터 타입 불일치로 인해 발생. Data Type을 Float로 변경하면 해결 가능.


📖 In-Place

  • 기존 텐서의 내용을 직접 수정하는 연산 방식
  • 장점 : 메모리 효율성, 연산 속도, 변수 재할당 불필요
  • But, Autograd와의 호환성 측면에서 문제가 있을 수 있음
  • ID를 확인하여 연산이 in-place로 수행되었는지 확인 가능

### Example ###

t = torch.tensor([[1, 2], [3, 4]])
u = torch.tensor([[10, 20], [30, 40]])

# in-place 연산
t.add_(u)
print(t) # tensor([[11, 22], [33, 44]])

# id 확인하기
id(t) # 137528900460336



2. 비교 연산

  • Tensor의 요소별 비교 수행
  • 결과는 Boolean Tensor로 출력
  • 브로드캐스팅(Broadcasting)을 지원하여 shape이 다른 텐서 간 비교도 가능
연산의미함수 형태
등호 (Equal)==torch.eq(a, b)
부등호 (Not Equal)!=torch.ne(a, b)
크다 (Greater Than)>torch.gt(a, b)
크거나 같다 (Greater Than or Equal)>=torch.ge(a, b)
작다 (Less Than)<torch.lt(a, b)
작거나 같다 (Less Than or Equal)<=torch.le(a, b)

### Example ###

a = torch.tensor([1, 2, 3])
b = torch.tensor([2, 2, 2])

equal = torch.eq(a, b)  # tensor([False, True, False])
greater = torch.gt(a, b)  # tensor([False, False, True])



3. 논리 연산

Tensor 논리 연산 종류

항목논리곱(AND)논리합(OR)배타적 논리합(XOR)
코드torch.logical_and(x, y)torch.logical_or(x, y)torch.logical_xor(x, y)

배타적 논리합(XOR)

  • 두 명제 중 하나True일 때 True
  • [True, True] / [False, False] 는 는 False
### Example ###

x = torch.tensor([True, True, False, False])
y = torch.tensor([True, False, True, False])

result = torch.logical_xor(x, y)
print(result) # tensor([False, True, True, False])


# 숫자 텐서일 경우 예시
a = torch.tensor([0, 1, 2, 3])
b = torch.tensor([1, 1, 0, 4])

# 0이 아닌 값은 True로 간주
result_numeric = torch.logical_xor(a, b)
print(result_numeric) # tensor([True, False, True, False])



4. 행렬 곱셈 (A @ B)

  • 두 텐서 간의 행렬 곱 도출
    (단, 두 텐서간 차원 호환이 되어야 함)
  • 신경망의 레이어 연산, 어텐션 메커니즘에서 사용
  • 연산 방법 : A.matmul(B) / A.mm(B) / A @ B
    (1) A.matmul(B)
    - 가장 일반적인 방법
    - 다차원 텐서와 벡터 간의 곱셈도 지원
    - 브로드캐스팅 지원
    (2) A.mm(B)
    - 2D 텐서(행렬)에 대해서만 작동
    - 벡터와의 곱셈은 지원하지 않음
    - 브로드캐스팅을 지원하지 않음
    (3) A @ B
    - Python 3.5 이상에서 도입된 행렬 곱셈 연산자
    - matmul과 동일한 기능 제공
    - 가독성이 좋고 간결한 코드 작성 가능
### Example ###

# 1. 벡터-벡터 곱(내적)
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
c = torch.matmul(a, b)
print(c)  # tensor(32)  # 1*4 + 2*5 + 3*6 = 32

# 2. 행렬-벡터 곱
A = torch.tensor([[1, 2], [3, 4]])
x = torch.tensor([5, 6])
y = torch.matmul(A, x)
print(y)  # tensor([17, 39])  # [1*5 + 2*6, 3*5 + 4*6]

# 3. 행렬-행렬 곱
batch_A = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
batch_B = torch.tensor([[[9, 10], [11, 12]], [[13, 14], [15, 16]]])
batch_C = torch.matmul(batch_A, batch_B)
print(batch_C)
# tensor([[[ 31,  34],
#          [ 71,  78]],
#
#         [[167, 182],
#          [231, 252]]])


### Example2 ###

A = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)
B = torch.tensor([[5, 6], [7, 8]], dtype=torch.float)

# 1. A.matmul(B)
result_matmul = A.matmul(B)

# 2. A.mm(B)
result_mm = A.mm(B)

# 3. A @ B
result_at = A @ B

# result
# tensor([[19., 22.],
#         [43., 50.]])

✨ 이미지 좌우 대칭 이동 (행렬 곱셈 응용)

  • 열을 뒤집은 단위 행렬을 활용하면 Matrix로 표현하는 이미지 데이터를 대칭이동 할 수 있음

### Example ###

A = torch.tensor([[1, 2, 3],
                  [4, 5, 6],
                  [7, 8, 9]], dtype=torch.float)

# 3x3 단위 행렬 생성
I = torch.eye(3)
# tensor([[1., 0., 0.],
#         [0., 1., 0.],
#         [0., 0., 1.]])

# 좌우 대칭 이동을 위한 행렬 생성 (단위 행렬의 열을 뒤집음)
flip_matrix = torch.flip(I, [1])
# tensor([[0., 0., 1.],
#         [0., 1., 0.],
#         [1., 0., 0.]])

# 좌우 대칭 이동 수행
A_flipped = torch.matmul(A, flip_matrix)
# tensor([[3., 2., 1.],
#         [6., 5., 4.],
#         [9., 8., 7.]])

0개의 댓글