CPU vs GPU
CPU는 높은 clock 속도를 가지지만 GPU는 CPU와 비교할 수 없는 Core 수를 가지고 있다
이러한 GPU를 다루기 쉽도록 최적화된 라이브러리는 아래와 같다
파란색은 CPU, 빨간색은 GPU, 노란색은 최적화한 GPU
CPU와 그냥 GPU를 비교하면 거의 60~70배 정도 차이가 난다
Deep Learning Frameworks
일반적인 유명한 Deep Learning Frameworks로는 Caffe, PyTorch, TensorFlow가 있다.
현업에서는는 TensorFlow을 많이 사용하며 연구에서는 PyTorch를 사용하는 추세이다.
PyTorch
PyTorch에는 3가지 추상화(Abstraction)가 있다
- Tensor : ndarray로, gpu에서 돌아간다
- Variable : computational graph 안에 있는 node 이다. data와 gradient를 가진다.
- Module : layer입니다. learnable weight들을 가지거나 state를 저장한다.
Tensors
PyTorch에서 사용하는 Tensor 사용법 예시
Tensor는 GPU에서 사용하는 array입니다.
먼저 dtype이라는 float type의 tensor를 정의하고 이를 type에 넣어주기만 하면 됩니다.
import torch
dtype = torch.cuda.FloatTensor
N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in).type(dtype)
y = torch.randn(N, D_out).type(dtype)
w1 = torch.randn(D_in, H).type(dtype)
w2 = torch.randn(H, D_out).type(dtype)
Tensors Autograd
Variable은 node 내부의 data를 말한다. 대표적으로 weight와 bias가 있습니다.
Variable은 data와 grad를 가지며 x.grad.data는 tensor의 gradient 값이다.
입력값 (x, y)에 대해서는 gradient(of loss)가 필요없기 때문에 requires_grad=False로 설정합니다.
파라미터 값인 (w1, w2)에 대해서는 gradient가 필요하여 requires_grad=True로 설정한 것을 볼 수 있습니다.
import torch
import torch.autograd import Variable
dtype = torch.cuda.FloatTensor
N, D_in, H, D_out = 64, 1000, 100, 10
x = Variable(torch.randn(N, D_in).type(dtype), requires_grad=False)
y = Variable(torch.randn(N, D_out).type(dtype), requires_grad=False)
w1 = Variable(torch.randn(D_in, H).type(dtype), requires_grad=True)
w2 = Variable(torch.randn(H, D_out).type(dtype), requires_grad=True)
forward 과정
function mm: matrix multiplication의 줄임말, x와 w1를 곱한다
function clamp: min값인 0보다 작은 결과는 0으로, 이외는 그대로 값을 사용하는 relu function
y_pred: 1-hidden NN 의 결과 값
이후 정답과 예측값 간의 Least Minimum Square 값을 계산한다.
learning_rate = 1e-6
for t in range(500):
y_pred = x.mm(w1).clamp(min=0).mm(w2)
loss = (y_pred - y).pow(2).sum()
w1와 w2의 gradient 값을 구하기 위해서 backward를 진행한다.
여기서 pytorch의 variable에 저장된 gradient 값은 초기화 하지 않으면 계속 누적된다.
고로 값이 0이 아닌 경우 w.grad.data.zero_() 함수를 이용하여 값을 0으로 모두 초기화 시켜준 뒤에 loss에 대한 gradient 값을 계산한다.
이후 이 gradient값을 가진 각각의 w1.grad.data 와 w2.grad.data를 learning_rate의 곱 만큼 빼주어 update 과정을 구현했습니다.
Example two Layer Net with PyTorch Tensor
아래는 Pytorch 에서 Tensor를 사용한 two-layer net 예제
- step 1. 데이터와 weight를 random tensor로 생성
- step 2. Forward pass Prediction과 loss 값 계산
- step 3. Backward pass gradient 계산
- step 4. weight 값 업데이트
Example Define New Autograd function
PyTorch는 사용자에 목적에 맞는 새로운 Autograd Function을 정의할 수 있습니다.
대부분 이런 함수들이 이미 구현되어 있으므로 우리는 필요와 목적에 맞는 함수를 불러오면 됩니다.
Example two Layer with PyTorch nn
nn Package를 이용하여 Sequence layer로 model를 구현하는 방법
Example Optimizer
또한 PyTorch는 Optimizer operation을 제공
Example Define new Modules
nn module은 일종의 네트워크 레이어
이 모듈은 다른 모듈이 포함될 수도 있고 학습 가능한 가중치도 포함될 수 있다.
아래 코드는 2-Layer Net을 하나의 모듈로 정의한 코드
TwoLayerNet의 __init__생성자를 보면 2개의 linear1과 linear2가 선언되어 있다.
두 개의 object를 클래스 안에 저장하고 있는 것. 마치 자식 module를 2개 저장하는 것과 같다.
Example DataLoaders
DataLoader는 mini-batch를 관리해줍니다.
학습 도중에 Disk에서 mini-batch를 가져오는 작업을 알아서 관리해줍니다.
dataloader는 dataset를 wrapping 하는 일종의 추상화 객체를 제공해줍니다.
epoch: 전체 training dataset을 총 몇 번 반복할지
Example Pretrained Models
torchvision이라는 라이브러리를 이용하면 alexnet, vgg, resnet등의 pre-trained model를 간편하게 다운받을 수 있다.
Example Visualization
visdom은 tensorflow의 tensorboard와 유사
Static vs Dynamic Graphs
TensorFlow는 static graph, PyTorch는 dynamic Graph
- static graph : define & run
- dynamic graph : running time에 dynamic하게 graph를 바꿀 수 있습니다.
static graph의 큰 장점은 deep learing framework의 layer optimzer를 받을 수 있다는 것이다.
compile 언어와 script 언어의 특징의 차이와 비슷하다.
아래 그림에서 이미 compile시 모델의 전체 구조를 알고 있으므로 Conv와 ReLU를 합친 fused operation으로 최적화 한 것을 볼 수 있다.
static graph는 한번 model이 정해진다면, build code 없이 model를 사용할 수 있다는 장점이 있다.
dynamic graph의 장점은 runtime에서 graph의 변형이 쉽다는 것이다.
간단한 if 문으로 모델을 변경할 수 있다.
하지만 static graph는 이 모든 조건을 미리 graph에 넣어두어야 한다.
dynamic graph는 for문으로 로직을 짜는 것 같이 사용할 수 있지만,
static graph는 functional programming 처럼 미리 기능에 대한 선언을 함수로 해두어야 한다.