일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- nlp
- AI Math
- 2023 현대차·기아 CTO AI 경진대회
- 데이터 구축
- Data Viz
- 현대자동차
- RNN
- N2N
- Bert
- Optimization
- 데이터 시각화
- seaborn
- dataset
- ODQA
- word2vec
- Self-attention
- matplotlib
- GPT
- 기아
- Ai
- N21
- Bart
- KLUE
- mrc
- Attention
- 딥러닝
- AI 경진대회
- Transformer
- passage retrieval
- pyTorch
- Today
- Total
쉬엄쉬엄블로그
PyTorch Basics 본문
이 색깔은 주석이라 무시하셔도 됩니다.
PyTorch Basics
PyTorch Operations
- numpy + AutoGrad
- PyTorch를 공부할 때 numpy만 잘 알아도 쉽게 이해할 수 있음
Tensor
다차원 Arrays를 표현하는 PyTorch 클래스
사실상 numpy의 ndarray와 동일
- 그러므로 TensorFlow의 Tensor와도 동일
Tensor를 생성하는 함수도 거의 동일
numpy - ndarray
import numpy as np n_array = np.arange(10).reshape(2,5) print(n_array) print("ndim :", n_array.ndim, "shape : ", n_array.shape)
pytorch - tensor
import torch t_array = torch.FloatTensor(n_array) print(t_array) print("ndim :", t_array.ndim, "shape : ", t_array.shape)
Array to Tensor
Tensor 생성은 list나 ndarray를 사용 가능
data to tensor
data = [[3, 5], [10, 5]] x_data = torch.tensor(data) x_data # tensor([[ 3, 5], # [10, 5]])
ndarray to tensor
nd_array_ex = np.array(data) tensor_array = torch.from_numpy(nd_array_ex) tensor_array # tensor([[ 3, 5], # [10, 5]])
Tensor data types
- 기본적으로 tensor가 가질 수 있는 data 타입은 numpy와 동일
- GPU를 쓸 수 있게 해주냐 없느냐의 차이가 있음
numpy like operations
기본적으로 pytorch의 대부분의 사용법이 그대로 적용됨
data = [[3, 5, 20], [10, 5, 50], [1, 5, 10]] x_data = torch.tensor(data) x_data[1:] # tensor([[10, 5, 50], # [ 1, 5, 10]]) x_data[:2, 1:] # tensor([[ 5, 20], # [ 5, 50]]) x_data.flatten() # tensor([ 3, 5, 20, 10, 5, 50, 1, 5, 10]) torch.ones_like(x_data) # tensor([[1, 1, 1], # [1, 1, 1], # [1, 1, 1]]) x_data.numpy() # array([[ 3, 5, 20], # [10, 5, 50], # [ 1, 5, 10]]) x_data.shape # torch.Size([3, 3]) x_data.dtype # torch.int64
pytorch의 tensor는 GPU에 올려서 사용가능
x_data.device # device(type='cpu') if torch.cuda.is_available(): x_data_cuda = x_data.to('cuda') x_data_cuda.device # device(type='cuda', index=0)
Tensor handling
view, squeeze, unsqueeze 등으로 tensor 조정가능
view : reshape과 동일하게 tensor의 shape을 변환
- reshape 대신 view를 사용하는 것을 추천
- view는 call by reference처럼 reshape은 call by value처럼 적용되는 듯
squeeze : 차원의 개수가 1인 차원을 삭제 (압축)
unsqueeze : 차원의 개수가 1인 차원을 추가
tensor_ex = torch.rand(size=(2, 3, 2)) tensor_ex # tensor([[[0.2241, 0.7548], # [0.8304, 0.0921], # [0.3622, 0.1289]], # # [[0.3631, 0.0160], # [0.4605, 0.4266], # [0.1298, 0.5042]]]) tensor_ex.view([-1, 6]) # tensor([[0.2241, 0.7548, 0.8304, 0.0921, 0.3622, 0.1289], # [0.3631, 0.0160, 0.4605, 0.4266, 0.1298, 0.5042]]) tensor_ex.reshape([-1,6]) # tensor([[0.2241, 0.7548, 0.8304, 0.0921, 0.3622, 0.1289], # [0.3631, 0.0160, 0.4605, 0.4266, 0.1298, 0.5042]]) a = torch.zeros(3, 2) b = a.view(2, 3) a.fill_(1) # tensor([[1., 1.], # [1., 1.], # [1., 1.]]) a # tensor([[1., 1.], # [1., 1.], # [1., 1.]]) b # tensor([[1., 1., 1.], # [1., 1., 1.]]) a = torch.zeros(3, 2) b = a.t().reshape(6) a.fill_(1) # tensor([[1., 1.], # [1., 1.], # [1., 1.]]) a # tensor([[1., 1.], # [1., 1.], # [1., 1.]]) b # tensor([0., 0., 0., 0., 0., 0.])
squeeze와 unsqueeze
tensor_ex = torch.rand(size=(2, 1, 2)) tensor_ex.squeeze() # tensor([[0.6175, 0.0451], # [0.8196, 0.7854]]) tensor_ex = torch.rand(size=(2, 2)) tensor_ex.unsqueeze(0).shape # torch.Size([1, 2, 2]) tensor_ex.unsqueeze(1).shape # torch.Size([2, 1, 2]) tensor_ex.unsqueeze(2).shape # torch.Size([2, 2, 1])
Tensor operations
기본적인 tensor의 operations는 numpy와 동일
n1 = np.arange(10).reshape(2,5) n2 = np.arange(10).reshape(5,2) t1 = torch.FloatTensor(n1) t2 = torch.FloatTensor(n2) t1 + t1 # tensor([[ 0., 2., 4., 6., 8.], # [10., 12., 14., 16., 18.]]) t1 - t1 # tensor([[0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.]]) t1 + 10 # tensor([[10., 11., 12., 13., 14.], # [15., 16., 17., 18., 19.]]) t1 + t2 --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-32-9ac58c83af08> in <module> ----> 1 t1 + t2 RuntimeError: The size of tensor a (5) must match the size of tensor b (2) at non-singleton dimension 1 ---------------------------------------------------------------------------
행렬곱셈 연산 함수는 dot이 아닌 mm 사용
- 내적을 구할 때는 dot
- 행렬간 연산을 할 때는 mm
n2 = np.arange(10).reshape(5,2) t2 = torch.FloatTensor(n2) t1.mm(t2) # tensor([[ 60., 70.], # [160., 195.]]) t1.dot(t2) --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-37-e9d95797f0ac> in <module> ----> 1 t1.dot(t2) RuntimeError: 1D tensors expected, but got 2D and 2D tensors --------------------------------------------------------------------------- t1.matmul(t2) # tensor([[ 60., 70.], # [160., 195.]]) a = torch.rand(10) b = torch.rand(10) a.dot(b) # tensor(3.7768) a # tensor([0.0551, 0.2704, 0.6091, 0.4992, 0.8537, 0.7814, 0.8016, 0.8468, 0.8652, 0.8580]) a = torch.rand(10) b = torch.rand(10) a.mm(b) --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-41-b53804119df5> in <module> 1 a = torch.rand(10) 2 b = torch.rand(10) ----> 3 a.mm(b) RuntimeError: self must be a matrix --------------------------------------------------------------------------- t1.dot(t2) --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-42-e9d95797f0ac> in <module> ----> 1 t1.dot(t2) RuntimeError: 1D tensors expected, but got 2D and 2D tensors --------------------------------------------------------------------------- t1.matmul(t2) # tensor([[ 60., 70.], # [160., 195.]])
mm은 broadcasting 지원 안함, matmul은 broadcasting 지원 함
a = torch.rand(10) b = torch.rand(10) a.dot(b) # tensor(1.6425) a = torch.rand(10) b = torch.rand(10) a.mm(b) --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-45-b53804119df5> in <module> 1 a = torch.rand(10) 2 b = torch.rand(10) ----> 3 a.mm(b) RuntimeError: self must be a matrix --------------------------------------------------------------------------- a = torch.rand(5, 2, 3) b = torch.rand(5) a.mm(b) --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-46-8eb1e1aa56cc> in <module> 1 a = torch.rand(5,2, 3) 2 b = torch.rand(5) ----> 3 a.mm(b) RuntimeError: self must be a matrix --------------------------------------------------------------------------- a = torch.rand(5, 2, 3) b = torch.rand(3) a.matmul(b) # tensor([[0.8852, 0.5109], # [0.2697, 0.6508], # [0.4165, 0.6240], # [0.9187, 0.3721], # [0.7430, 0.4134]]) a[0].mm(torch.unsqueeze(b,1)).squeeze() # tensor([0.8852, 0.5109]) a[1].mm(torch.unsqueeze(b,1)) # tensor([[0.2697], # [0.6508]]) a[2].mm(torch.unsqueeze(b,1)) # tensor([[0.4165], # [0.6240]]) a[3].mm(torch.unsqueeze(b,1)) # tensor([[0.9187], # [0.3721]]) a[4].mm(torch.unsqueeze(b,1)) # tensor([[0.7430], # [0.4134]])
- broadcasting은 결과를 헷갈리게 만드는 요소가 될 수도 있기 때문에 명확하게 사용하고 싶다면 mm 사용
Tensor operations for ML/DL formula
nn.functional 모듈을 통해 다양한 수식 변환을 지원함
import torch import torch.nn.functional as F tensor = torch.FloatTensor([0.5, 0.7, 0.1]) h_tensor = F.softmax(tensor, dim=0) h_tensor # tensor([0.3458, 0.4224, 0.2318]) y = torch.randint(5, (10,5)) print(y) # tensor([[3, 1, 1, 4, 1], # [3, 0, 0, 4, 2], # [2, 2, 1, 0, 2], # [3, 3, 0, 2, 2], # [0, 1, 2, 3, 3], # [4, 1, 2, 0, 4], # [3, 4, 0, 3, 1], # [1, 1, 3, 0, 3], # [3, 1, 1, 3, 1], # [4, 3, 3, 4, 2]]) y_label = y.argmax(dim=1) y_label # tensor([3, 3, 0, 0, 3, 0, 1, 2, 0, 0]) torch.nn.functional.one_hot(y_label) # tensor([[0, 0, 0, 1], # [0, 0, 0, 1], # [1, 0, 0, 0], # [1, 0, 0, 0], # [0, 0, 0, 1], # [1, 0, 0, 0], # [0, 1, 0, 0], # [0, 0, 1, 0], # [1, 0, 0, 0], # [1, 0, 0, 0]]) import itertools a = [1, 2, 3] b = [4, 5] list(itertools.product(a, b)) # [(1, 4), (1, 5), (2, 4), (2, 5), (3, 4), (3, 5)] tensor_a = torch.tensor(a) tensor_b = torch.tensor(b) torch.cartesian_prod(tensor_a, tensor_b) # tensor([[1, 4], # [1, 5], # [2, 4], # [2, 5], # [3, 4], # [3, 5]])
AutoGrad
PyTorch의 핵심은 자동 미분이 지원 → backward 함수 사용
$y = w^2 \z = 10y + 25 \z = 10w^2 + 25$
w = torch.tensor(2.0, requires_grad=True) y = w**2 z = 10*y + 50 z.backward() z # z식에 w가 2일 때 값이 90 # tensor(90., grad_fn=<AddBackward0>) w.grad # z에 대해서 w로 편미분했을 때 w가 2인 경우에 값이 40 # tensor(40.)
$Q = 3a^3 - b^2$
$\frac{\partial Q}{\partial a} = 9a^2 \ \ \
\frac{\partial Q}{\partial b} = -2b$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) Q # Q식에 a가 [2, 3], b가 [6, 4]일 때 값이 (-12, 65) # tensor([-12., 65.], grad_fn=<SubBackward0>) a.grad # Q식에 대해서 a로 편미분했을 때 a가 [2, 3]인 경우에 값이 (36, 81) # tensor([36., 81.]) b.grad # Q식에 대해서 b로 편미분했을 때 b가 [6, 4]인 경우에 값이 (-12, -8) # tensor([-12., -8.])
출처: 부스트캠프 AI Tech 4기(NAVER Connect Foundation)
'부스트캠프 AI Tech 4기' 카테고리의 다른 글
Custom Model 제작 (0) | 2023.05.13 |
---|---|
PyTorch 프로젝트 구조 이해하기 (0) | 2023.05.12 |
PyTorch 소개 (2) | 2023.05.10 |
RNN 기초 (0) | 2023.05.09 |
CNN 기초 (0) | 2023.05.08 |