반응형

1. 텐서 안의 기본연산

우선 코드를 실행하기 위한 PyTorch를 불러온다. 실행한 환경은 Google Colab에서 아래와 같은 버전의 Python과 PyTorch를 사용했다.

 

import torch
import sys
print("Python version : ", sys.version)
print("PyTorch version : ", torch.__version__)

 

>>> Python version : 3.10.12

>>> PyTorch version : 2.3.1.+cu121

1.1.  요소들의 합

텐서를 이루는 요소들의 합을 구하기 위해서는 torch.sum(Tensor, dim) 또는 Tensor.sum(dim)를 사용할 수 있다. dim에 특별한 값을 넣지 않은 경우 전체 요소들의 계산 값을 반환한다. 

 

a = torch.tensor([[1, 2], [3, 4]])
print(torch.sum(a))
print(torch.sum(a, dim=0))
print(torch.sum(a, dim=1))
print(a.sum())
print(a.sum(dim=0))
print(a.sum(dim=1))

 

1.2.  요소들의 곱

텐서를 이루는 요소들의 곱을 구하기 위해서는 torch.prod(Tensor, dim) 또는 Tensor.prod(dim)를 사용할 수 있다. dim에 특별한 값을 넣지 않은 경우 전체 요소들의 계산 값을 반환한다. 

 

a = torch.tensor([[1, 2], [3, 4]])
print(torch.prod(a))
print(torch.prod(a, dim=0))
print(torch.prod(a, dim=1))
print(a.prod())
print(a.prod(dim=0))
print(a.prod(dim=1))

 

1.3.  요소들의 평균 

텐서를 이루는 요소들의 평균을 구하기 위해서는 torch.mean(Tensor, dim) 또는 Tensor.mean(dim)를 사용할 수 있다. dim에 특별한 값을 넣지 않은 경우 전체 요소들의 계산 값을 반환한다. 

 

a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
print(torch.mean(a))
print(torch.mean(a, dim=0))
print(torch.mean(a, dim=1))
print(a.mean())
print(a.mean(dim=0))
print(a.mean(dim=1))

.

 

1.4.  요소들의 표준편차, 분산 

텐서를 이루는 요소들의 표준편차와 분산을 구하기 위해서 앞에서와 동일하게 메서드(var, std)를 사용할 수 있다. dim에 특별한 값을 넣지 않은 경우 전체 요소들의 계산 값을 반환한다. 표준편차와 분산에서 알아둘 것은 표본(텐서)을 대상으로 계산한다. ([1] & [2])

 

a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
print(torch.std(a))
print(a.std())
print(torch.var(a))
print(a.var())

 

 

1.5.  요소들의 최대, 최소 

텐서를 이루는 요소들의 최대값과 을 구하기 위해서는 앞선 연산들과 동일한 방식으로 메서드(max, min)를 사용하면 된다. dim에 특별한 값을 넣지 않은 경우 전체 요소들의 계산 값을 반환한다. 

 

a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
print(torch.max(a))
print(a.max())
print(torch.min(a))
print(a.min())

 

 

2. 텐서 간 연산

텐서끼리 연산은 산술연산( +, -, x ), 요소 간 비교(<, >, ==), 행렬곱이 있다. 각각 연산에 대해 세부적으로 연산 결과가 어떻게 되는지 살펴보려고 한다. 

 

2.1. 산술연산

텐서 사이에서 덧셈, 뺄셈, 곱셈, 나눗셈, 거듭제곱 등을 지원한다. 파이썬의 기본연산(+, -, *,  /)도 가능하지만, torch 메서드를 통해서도 지원하고 있다. 차원이 다른 스칼라나 벡터들에 대해서도 Broadcasting을 통해 계산이 가능하다. 

 

a = torch.arange(1,5).reshape(2,2)
b = torch.arange(5,9).reshape(2,2)
c = 3
d = torch.tensor([1, 2])
print(a+b)
print(torch.add(a, b))
print(torch.add(a, c))
print(torch.add(a, d))

 

 

또한, 연산에서 알아둬야 할 것 중에 하나는 in-place 알고리즘(제자리 연산)이다. 명칭처럼 메모리를 추가로 할당하지 않고, 기존 메모리에서 제자리 연산을 수행한다는 점이다. in-place 연산은 메서드에 언더바( _ )를 추가하면서 수행할 수 있다. [3]

  

 

제자리 알고리즘 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 과학에서 제자리(in-place) 알고리즘은 자료 구조를 추가로 사용하지 않고 입력을 변환하는 알고리즘이다. 그러나 보통 추가적인 변수를 위해 약간의 추

ko.wikipedia.org

in-place 연산 수행 방법은 Tensor.add(Tensor) 형태로 수행 가능하다. 여기서 알아둘 점은 in-place 연산은 추가 할당이 없어 메모리 효율적이지만, 후에 배울 autograd와 호환 문제가 발생할 수 있어서 실제 사용에서는 주의가 필요하다.

a = torch.arange(1,5).reshape(2,2)
b = torch.arange(5,9).reshape(2,2)
print(id(a))
print("address(a) : ", id(a))
print("address(in-place addition) : ", id(a.add_(b)))

 

 

더하기 메서드인 add 이외에도, 빼기(sub), 곱하기(mul), 나누기(div), 제곱(pow)를 통해 계산이 가능하며, 또한 in-place 연산 지원을 위해 sub_, mul_, div_, pow_ 역시 가능하다. 

 

2.2. 비교연산 

텐서는 각각 요소들을 비교하는 연산도 존재한다. torch의 메서드(eq, ne, gt, ge, lt, le)를 활용하며, 결과는 Boolean Tensor를 출력한다. 

 

# 비교연산
a = torch.tensor([1, 2, 3, 4])
b = torch.tensor([1, 3, 3, 5])
# == (equal)
print(torch.eq(a, b))
# != (not equal)
print(torch.ne(a, b))
# > (greater than)
print(torch.gt(a, b))
# >= (greater than or equal)
print(torch.ge(a, b))
# < (less than)
print(torch.lt(a, b))
# <= (less than or equal)
print(torch.le(a, b))

 

 

2.3. 논리연산 

텐서 요소들의 Boolean 값을 계산하는 논리연산도 지원한다. 논리연산의 기본은 and, or, not, xor, not을 지원하고 있으며, 이러한 논리연산을 잘 조합하면 NAND, NOR 같은 연산도 만들 수 있다. 참고로 논리연산의 결과값인 진리표를 참고하여 논리연산을 만들면 될 것이다. [4]

 

# 논리연산
x = torch.tensor([True, True, False, False])
y = torch.tensor([True, False, True, False])

print(torch.logical_and(x, y)) # AND
print(torch.logical_or(x,y)) # OR
print(torch.logical_xor(x,y)) # XOR
print(torch.logical_not(x)) # NOT
print(torch.logical_and(x,y).logical_not()) # NAND

 

 

2.4. 행렬 곱

앞에서 수행했던 스칼라 곱이나, element-wise 곱과 다르게 행렬의 일반적인 곱셈은 다르다. [5] 이러한 행렬 곱을 지원하는 방법은 tensor.matmul(Tensor1, Tensor2), Tensor1.matmul(Tensor2), @ 를 통해 가능하다. 

 

# Matrix Multiplication
X = torch.randn(2,3)
Y = torch.randn(3,4)
print(torch.matmul(X, Y))
print(X.matmul(Y))
print(X @ Y)

 

 

3. 텐서의 노름(norm)

수학에서 노름(Norm, 정확한 발음은 아니지만 통상적으로 많이 쓰이는 표현인 '노름' 사용)은 벡터들이 모인 공간에서의 거리를 말한다. 벡터들이 모인 공간에서 차원에 따라 거리의 정의는 다르게 표현되는데, 표현 방식은 아래 위키 링크를 통해 확인하는 것으로 충분할 것 같다.

 

 

Norm (mathematics) - Wikipedia

From Wikipedia, the free encyclopedia Length in a vector space In mathematics, a norm is a function from a real or complex vector space to the non-negative real numbers that behaves in certain ways like the distance from the origin: it commutes with scalin

en.wikipedia.org

 

PyTorch에서 노름은 매우 쉽게 계산할 수 있는데, torch.norm(Tensor, p)의 형태로 계산이 가능하다. 

a = torch.tensor([1, 2, 3, 4], dtype=torch.float32)
# L1 norm
print(torch.norm(a, p=1))
# L2 norm
print(torch.norm(a, p=2))
# L∞ norm
print(torch.norm(a, p=float('inf')))

 

 

4. 참고문헌

[1] https://pytorch.org/docs/stable/generated/torch.std.html

[2] https://pytorch.org/docs/stable/generated/torch.var.html

[3] https://en.wikipedia.org/wiki/In-place_algorithm

[4] https://en.wikipedia.org/wiki/Truth_table

[5] https://ko.wikipedia.org/wiki/%ED%96%89%EB%A0%AC_%EA%B3%B1%EC%85%88

[6] https://en.wikipedia.org/wiki/Norm_(mathematics)

 

 

 

 

 

반응형