[이론 정리] Pytorch

2023. 3. 13. 14:41AI/이론 정리

PyTorch

PyTorch란 개발자가 파이썬을 활용하여 딥러닝 모델을 만들고 학습시킬 수 있는 오픈 소스 머신 러닝 프레임워크이다. PyTorch는 디버깅과 효율적인 모델 생성을 쉽게 해주는 동적 계산 그래프(dynamic computational graph)를 제공한다. 또한 데이터 로딩, 전처리, 시각화와 같은 광범위한 도구와 라이브러리를 제공한다. 특히, 컴퓨터 비전, NLP, 강화학습에 적합하다. (source: https://openai.com)

 

구글에서 개발한 TensorFlow 또한 이와 같은 머신 러닝 프레임워크이다. 두 시스템의 차이는 그래프를 그리는 방식에 있다. PyTorch는 dynamic comuputational graph로 런타임 때 그래프가 생성되기 때문에 학습 중간중간 그래프를 수정할 수 있지만 TensorFlow는 static graph로 그래프를 먼저 정의하고 실행시점에 데이터를 넣어주기 때문에 그래프를 수정하려면 전체 그래프를 처음부터 다시 만들어야 하는 단점이 있다.

 

PyTorch는 논문 작성, 아이디어 구현에 장점이 있으며 TensorFlow는 프로덕션, 클라우드, 멀티 GPU에 장점이 있다.

 

PyTorch = Numpy + AutoGrad + Function

왜 Numpy인가? PyTorch와 numpy에서 사용하는 함수가 대부분 같다.

예시) [1:](slicing), ones_like, flatten, shape, dtype

tensor의 numpy의 차이는 tensor는 GPU에서 사용 가능하다.

 

view와 reshape의 차이

두 함수 모두 tensor의 shape을 재조정한다. 그러나 view의 경우에는 원본 자체를 바꾸지만 reshape의 경우 copy를 새로 만드는 것이기 때문에 원본은 따로 존재하고 바뀌지 않는다.

 

행렬곱셈 연산 함수에는 dot이 아닌 mm과 matmul을 사용한다. 두 함수의 차이점은 mm의 경우 broadcasting을 지원하지 않지만 matmul은 지원한다. Broadcasting이란 서로 다른 shape을 가진 tensor 사이의 연산을 지원하기 위해 shape을 맞추어 주는 기능을 의미한다.

## Broadcasting 예시 ##

import torch

# Create two tensors of different shapes
a = torch.tensor([1, 2, 3])
b = torch.tensor([[4, 5, 6], [7, 8, 9]])

# Add the two tensors
c = a + b

# Print the result
print(c)

# source: https://openai.com

위와 같이 a와 b의 shape이 다를 때 보다 적은 a에 한차원을 더해주어 [1, 2, 3], [1, 2, 3]을 만들어주고 b와 덧셈 연산을 진행한다. 따라서 결과는 다음과 같다.

tensor([[ 5,  7,  9],
        [ 8, 10, 12]])

nn.functional 모듈을 통해 다양한 수식 변환을 지원한다. 

import torch
import torch.nn.functional as F

tensor = torch.FloatTensor([2.0, 1.0, 3.0, 4.0])

## softmax ##
# 1차원 tensor에서 dim = 0이기 때문에 column 별로 softmax를 구함
soft_tensor = F.softmax(tensor, dim=0)

# output: tensor([0.0871, 0.0321, 0.2369, 0.6439])

## onehot vector ##
tensor = torch.LongTensor([1, 2, 4, 4, 5])
# num_classes는 column의 개수
F.one_hot(tensor, num_classes = 6)

# output: tensor([[0, 1, 0, 0, 0, 0],
#        [0, 0, 1, 0, 0, 0],
#        [0, 0, 0, 0, 1, 0],
#        [0, 0, 0, 0, 1, 0],
#        [0, 0, 0, 0, 0, 1]])

 

torch.tensor(array, requires_grad=True)는 자동으로 gradient를 계산한다.

backward의 gradient 인자는 Q 자기 자신에 대한 gradient이다. 따라서 실제 a, b의 gradient는 Q의 gradient에 external_grad를 곱한 값이 된다.

예시)

import torch

a = torch.tensor([2., 3.], requires_grad=True)
b = torch.tensor([6., 4.], requires_grad=True)
Q = 3*a**3 - b**2
external_grad = torch.tensor([1., 1.])
Q.backward(gradient=external_grad)

# output
# a.grad: [36., 81.] 
# b.grad: [-12., -8.]

 

tensor가 2차원일때

dim = 0 : 위에서 아래로

dim = 1 : 왼쪽에서 오른쪽으로