-
[PyTorch] Deep learning with PyTorch - IntroMachine Learning/PyTorch 2022. 4. 27. 13:12728x90
PyTorch로 딥러닝 하기: 60분 만에 끝장내기의 초간단 정리입니다.
학습 및 정리 과정에서 들었던 의문이나 궁금한 사항에 대한 답도 설명에 추가했습니다.
실습은 구글 코랩(Google Colab) 을 통해 쉽게 따라 하실 수 있습니다.Pytorch
Python 기반의 연산 패키지, 오픈 소스 Machine Learning 프레임워크
- GPU 이용 연산 필요한 경우 사용 (Numpy 대체)
- 신경망 구현에 유용한 라이브러리 제공
- TensorFlow와 양대산맥을 이루는 딥러닝 연구 플랫폼 / 실제 서비스와 프로덕션 배포에도 사용
Tensors
배열이나 행렬과 유사한 자료구조 / Numpy의 ndarray와 유사 / GPU를 사용한 연산 가속 가능
import torch import numpy as np
1) 텐서 초기화
- 데이터로부터 직접(directly) 생성 - 자료형(data type) 자동으로 유추
- torch.tensor()
data = [[1, 2], [3, 4]] x_data = torch.tensor(data)
- NumPy 배열로부터 생성
- torch.from_numpy()
np_array = np.array(data) x_np = torch.from_numpy(np_array)
- 다른 텐서로부터 생성
- torch.ones_like()
- torch.rand_like()
x_ones = torch.ones_like(x_data) # x_data의 속성을 유지합니다. print(f"Ones Tensor: \n {x_ones} \n") x_rand = torch.rand_like(x_data, dtype=torch.float) # x_data의 속성을 덮어씁니다. print(f"Random Tensor: \n {x_rand} \n")
Ones Tensor: tensor([[1, 1], [1, 1]]) Random Tensor: tensor([[0.7803, 0.1358], [0.9131, 0.9045]])
- 무작위(random) 또는 상수(constant) 값 사용
- shape : 텐서의 차원(dimension) 나타내는 튜플
- torch.rand() / torch.ones() / torch.zeros()
shape = (2, 3,) rand_tensor = torch.rand(shape) ones_tensor = torch.ones(shape) zeros_tensor = torch.zeros(shape) print(f"Random Tensor: \n {rand_tensor} \n") print(f"Ones Tensor: \n {ones_tensor} \n") print(f"Zeros Tensor: \n {zeros_tensor}")
Random Tensor: tensor([[0.0607, 0.6287, 0.8601], [0.3853, 0.9052, 0.9199]]) Ones Tensor: tensor([[1., 1., 1.], [1., 1., 1.]]) Zeros Tensor: tensor([[0., 0., 0.], [0., 0., 0.]])
2) 텐서의 속성(Attribute)
- 텐서의 모양(shape), 자료형(datatype) 및 어느 장치에 저장되는지를 나타냄
- variable.shape (=variable.size())
- variable.dtype
- variable.device
tensor = torch.rand(3, 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
3) 텐서 연산(Operation)
- 전치, 인덱싱, 슬라이싱, 수학 계산, 선형 대수, 샘플링 등 많은 연산 - [link]
- 연산들은 GPU(일반적으로 CPU 보다 빠름)에서 실행 가능
- Colab - Edit > Notebook Settings (수정 > 노트 설정)에서 GPU 할당 가능
# GPU가 존재하면 텐서를 이동합니다 if torch.cuda.is_available(): tensor = tensor.to('cuda') print(f"Device tensor is stored on: {tensor.device}")
Device tensor is stored on: cuda:0
- NumPy 식의 표준 인덱싱 및 슬라이싱
tensor = torch.ones(4, 4) tensor[:,1] = 0 print(tensor)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
- 텐서 합치기
- torch.cat()
t0 = torch.cat([tensor, tensor, tensor], dim=0) print(t0) print(t0.shape) t1 = torch.cat([tensor, tensor, tensor], dim=1) print(t1) print(t1.shape)
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.]]) torch.Size([12, 4]) 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.]]) torch.Size([4, 12])
- 텐서 곱하기
tensor[2,2] = 2 tensor[3,3] = 3 # 요소별 곱(element-wise product)을 계산합니다 print(f"tensor.mul(tensor) \n {tensor.mul(tensor)} \n") # 다른 문법: print(f"tensor * tensor \n {tensor * tensor}")
tensor.mul(tensor) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 4., 1.], [1., 0., 1., 9.]]) tensor * tensor tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 4., 1.], [1., 0., 1., 9.]])
- 두 텐서 간의 행렬 곱(matrix multiplication)
- variable.T : 전치
- matmul() (= @ 연산자)
print(f"tensor.matmul(tensor.T) \n {tensor.matmul(tensor.T)} \n") # 다른 문법: print(f"tensor @ tensor.T \n {tensor @ tensor.T}")
tensor.matmul(tensor.T) tensor([[ 3., 3., 4., 5.], [ 3., 3., 4., 5.], [ 4., 4., 6., 6.], [ 5., 5., 6., 11.]]) tensor @ tensor.T tensor([[ 3., 3., 4., 5.], [ 3., 3., 4., 5.], [ 4., 4., 6., 6.], [ 5., 5., 6., 11.]])
- 바꿔치기(in-place) 연산 - '_' 접미사를 갖는 연산들은 in-place 연산
- ex) x.copy_() 나 x.t_()는 x를 변경함
print(tensor, "\n") tensor.add_(5) print(tensor)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 2., 1.], [1., 0., 1., 3.]]) tensor([[6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 7., 6.], [6., 5., 6., 8.]])
주의 : in-place 연산은 메모리를 일부 절약하지만, 기록(history)이 삭제되어 도함수 계산에 문제 발생 가능(권장 x)
4) NumPy 변환(Bridge)
- CPU 상의 텐서와 NumPy 배열은 메모리 공간을 공유하기 때문에, 하나를 변경하면 다른 하나도 변경
- PyTorch의 Tensor로 Numpy의 ndarray 를 대체했을 때 GPU에서 16배 이상의 속도 향상 가능(참고)
4.1) 텐서를 NumPy 배열로 변환
t = torch.ones(5) print(f"t: {t}") n = t.numpy() print(f"n: {n}")
t: tensor([1., 1., 1., 1., 1.]) n: [1. 1. 1. 1. 1.]
- 텐서의 변경 사항이 NumPy 배열에도 반영
t.add_(1) print(f"t: {t}") print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.]) n: [2. 2. 2. 2. 2.]
4.2) NumPy 배열을 텐서로 변환
n = np.ones(5) t = torch.from_numpy(n)
- NumPy 배열의 변경 사항이 텐서에 반영
np.add(n, 1, out=n) print(f"t: {t}") print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64) n: [2. 2. 2. 2. 2.]
5) 추가 유용한 함수
- 크기 변경 : tensor의 크기(size)나 모양(shape)을 변경하고 싶다면 torch.view를 사용
x = torch.ones(4, 4) y = x.view(16) z = x.view(-1, 8) # -1은 다른 차원들을 사용하여 유추 -> torch.Size([2,8]) print("x", x) print("y", y) print("z", z)
x tensor([[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]]) y tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) z tensor([[1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1.]])
- .item() : 하나의 값만 scalar로 추출 가능
x = torch.randn(1) print(x) print(x.item())
tensor([-0.0118]) -0.011786350980401039
랜덤한 값을 가지는 텐서 생성
- 랜덤 값으로 채워진 텐서를 생성하는 명령
- torch.rand() : 0과 1 사이의 숫자를 균등하게 생성
- torch.rand_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
- torch.randn() : 평균이 0이고 표준편차가 1인 가우시안 정규분포를 이용해 생성
- torch.randn_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
- torch.randint() : 주어진 범위 내의 정수를 균등하게 생성, 자료형은 torch.float32
- torch.randint_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
- torch.randperm() : 주어진 범위 내의 정수를 랜덤 하게 생성
- 랜덤 생성에 사용되는 시드(seed)는 torch.manual_seed() 명령으로 설정한다.
torch.manual_seed(0) a = torch.rand(5) b = torch.randn(5) c = torch.randint(10, size=(5,)) d = torch.randperm(5) print(a) print(b) print(c) print(d)
tensor([0.4963, 0.7682, 0.0885, 0.1320, 0.3074]) tensor([ 0.5507, 0.2704, 0.6472, 0.2490, -0.3354]) tensor([8, 4, 3, 6, 9]) tensor([1, 3, 4, 2, 0])
728x90'Machine Learning > PyTorch' 카테고리의 다른 글
[PyTorch/에러] RuntimeError: Error(s) in loading state_dict (0) 2022.12.18