What is PyTorch?
PyTorch는 파이썬 기반 패키지로 GPU나 다른 가속장치를 사용하기 위해 NumPy를 대체할 수 있고, neural networks 구현을 위한 자동 미분 라이브러리를 제공한다.
Goal of this tutorial
- PyTorch의 텐서 라이브러리와 neural network를 이해한다.
- 이미지를 분류하기 위해 작은 neural network를 학습시켜본다.
Requirements
https://pytorch.org/get-started/locally/
자신의 OS, 쿠다 버전 등 컴퓨터 사양에 맞는 파이토치 설치
conda install pytorch torchvision torchaudio cudatoolkit=10.2 -c pytorch
Tensors
Tensor는 데이터 구조로 배열이나 행렬과 매우 유사하다.
PyTorch에서 model의 파라미터나 inputs, outputs를 인코딩 할 때 텐서를 사용한다.
Tensor는 NumPy에서의 ndarrays와 유사하며 GPU에서 동작시킬 수 있다.
import torch import numpy as np
Tensor 초기화
텐서를 만드는 방법은 여러가지가 있다.
- 데이터로부터 직접 만들기
data = [[1, 2],[3, 4]] x_data = torch.tensor(data)
2 by 2 텐서를
data
라는 변수에 할당한다.torch.tensor
를 사용하여 array를 PyTorch의 Tensor로 변환한다. type은 자동적으로 결정된다.
- NumPy array로부터 만들기
np_array = np.array(data) #python list -> numpy array x_np = torch.from_numpy(np_array) #numpy array -> pytorch tensor
- 텐서의 형태만 사용하기
기존에 만들어 놓은 텐서 값을 사용하는 것이 아니라 shape만 적용하고 요소 값은 다른 값으로 채워서 텐서를 생성할 수 있다.
x_ones = torch.ones_like(x_data) x_rand = torch.rand_like(x_data, dtype=torch.float)
torch.ones_like()
는 인자로 전달된 값의 shape를 유지한 채로 elements를 1로 채운다.torch.rand_like()
는 인자로 전달된 값의 shape를 유지한 채로 elements를 랜덤한 값으로 채운다. 값의 범위는 [0, 1)이다.
- 랜덤 또는 상수 값 사용하기
shape를 직접 지정하여 텐서를 생성할 수 있다. 텐서 요소들은 함수에 따라 랜덤, 1, 0으로 채울 수 있다.
shape = (2,3,) #2 by 3 rand_tensor = torch.rand(shape) ones_tensor = torch.ones(shape) zeros_tensor = torch.zeros(shape)
torch.rand()
랜덤 값으로 채움. 범위는 [0,1)torch.ones()
요소를 1로 채움.torch.zeros()
요소를 0으로 채움.
Tensor Attributes
텐서는 텐서의 형태, 데이터 타입, 저장된 디바이스(CPU/GPU) 와 같은 속성을 갖는다.
tensor = torch.rand(3,4) # 랜덤하게 채워진 3 by 4 텐서 생성 print(f"Shape of tensor: {tensor.shape}") print(f"Datatype of tensor: {tensor.dtype}") print(f"Device tensor is stored on: {tensor.device}")
Shape of tensor: torch.Size([3, 4]) Datatype of tensor: torch.float32 Device tensor is stored on: cpu
Tensor Operations
변환, 인덱싱, 슬라이싱, 수학적 연산, 선형대수, 랜덤 샘플링 등 100가지 이상의 텐서 연산들을 제공한다. 연산들은 전부 GPU에서 실행할 수 있고, 이를 위해 텐서를 GPU에 저장해야한다.
#GPU에서 실행하길 원할 때, if torch.cuda.is_available(): # CUDA를 사용할 수 있는 경우 tensor = tensor.to('cuda') # 텐서를 GPU에 올림
- NumPy처럼 indexing, slicing 하기
tensor = torch.ones(4,4) # 1로 채워진 4 by 4 tensor tensor[:,1] = 0 # 1번째 column vector 값을 0으로 바꿈 print(tensor)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
- Tensor 붙이기(Concatenate)
t1 = torch.cat([tensor, tensor, tensor], dim=1) # dim이 0이면 세로(vertical)로 붙이고, 1이면 가로(horizontal)로 붙임 print(t1)
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])
- 텐서의 곱셈
*
연산자를 쓰거나 PyTorch의 tensor의 mul 메소드를 사용하면 element-wise 연산이 수행된다.만약 행렬 곱셈을 하고 싶다면,
matmul()
또는@
를 사용해야 한다.# Element-wise print(f"tensor.mul(tensor) \n {tensor.mul(tensor)}\n") # tensor의 mul함수 print(f"tensor * tensor \n {tensor * tensor}") # 연산자로 곱하기
tensor.mul(tensor) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor * tensor tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
# Matix multiplication print(f"tensor.matmul(tensor.T) \n {tensor.matmul(tensor.T)} \n") print(f"tensor @ tensor.T \n {tensor @ tensor.T} \n")
tensor.matmul(tensor.T) tensor([[3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.]]) tensor @ tensor.T tensor([[3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.]])
- In-place 연산 (+=, *= 같은 연산)
print(tensor) tensor.add_(5) # tensor *= 5 또는 tensor = tensor * 5 결과 값이 바로 요소 값으로 적용됨 print(tensor)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor([[6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.]])
Bridge with NumPy
CPU에 있는 tensor와 NumPy arrays는 기본 메모리 위치를 공유할 수 있고, 하나를 변경하는 경우 다른 하나도 함께 변경된다.
- PyTorch의 Tensor를 NumPy array로 변환
t = torch.ones(5) # 1 by 5 의 1로 채워진 행렬 print(f"t: {t}") n = t.numpy() # NumPy array로 변환 print(f"n: {n}")
t: tensor([1., 1., 1., 1., 1.]) n: [1. 1. 1. 1. 1.]
- NumPy array를 PyTorch tensor로 변환
n = np.ones(5) t = torch.from_numpy(n) np.add(n, 1, out = n) # numpy array 값을 변환시키면 t에도 적용이 된다. print(f"t: {t}") print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64) n: [2. 2. 2. 2. 2.]
Uploaded by Notion2Tistory v1.1.0