파이토치 딥러닝 알고리즘 구현하기
이번 포스트에는 아주 간단한 딥러닝 알고리즘을 구현하는 포스팅을 해 보겠습니다.
파이토치의 모든 네트워크는 CLASS형태로 개발이 됩니다. 네트워크를 구현하는 클레스는 nn.Module 클래스를 상속하게 되고, __init__ 초기화 부분과 forward의 forward propagation이 진행되는 매서드를 구현하여야 합니다.
아주 귀여운 네트워크입니다. 사실 위와같은 네트워크는 Deep learning이라고 불리기 민망할 정도이지만 한번 살펴 보겠습니다. CuteNetwork는 Linear layer와 ReLU 를 이용한 3층 네트워크입니다. 초기화 부분에서 어떤 layer를 사용할 것인지 self를 통해 인자를 받고, forward부분에서 네트워크의 순서대로 구현을 하게됩니다.
하고자 하는 분류에 따른 마지막 Layer
네트워크를 구축할때 가장 먼저 해야할 일은 다양한 layer중 어떤 layer를 사용하는지 알고 있는것이다. 해결 하려는 문제에 따라서 last layer의 형태가 다르다.
- Regression: 마지막 레이어로 linear layer를 이용한다.
- Binary classification: 마지막 layer로 sigmoid를 사용한다.
- Multi-class classification: 마지막 layer로 softmax를 사용한다.
오차함수 (Loss Function) & 옵티마이저(optimizer)
1. 오차함수
네트워크를 완성하귀 위해서는 위와 같이 구현한 네트워크가 얼마나 하고자 하는 분류에 대해 적합한지 측정하는 것과 가중치를 최적화하는 과정이 남아있다. loss function에 의해 loss가 작아지는 쪽으로 학습을 하게된다.
먼저 Regression 문제에서 일반적으로 사용되는 loss function은 MSE(mean square error)이다.
위 코드를 간단히 설명해 보면, input_example은 평균이 0 이고 분산이 1인 분포를 가지는 3x5 행렬이며 require_grads = True라는 값을 가진다. 여기서 require_grads라는 것은 back progation에서 쓰이는 역전파를 구할때 기울기를 계산한다라는 의미이다.
output 값은 MSE loss function을 이용하여 input_example(예측)과 target_example(정답)간의 loss를 계산하게 된다.
output.backward() 라는 마지막 줄은 Backpropagation을 통해 기울기를 구하는 과정이라고 보면 되겠다.
목적에 따른 loss들을 간단하게 표로 나타내면 아래와 같다.
L! loss | Normalization에 자주 이용된다. |
MSE loss | Regression 문제에서 자주 이용된다. |
CEE loss | Binary, Multi class classification에 이용된다 |
NLL loss | 분류 문제에서 데이터셋 불균형 해소를 위해 사용한다. |
NLL loss2d | 주로 이미지 분할에서 픽셀단위 분류에 사용된다. |
2. 옵티마이저(Optimizer)
위의 loss의 코드에서 마지막 줄인 loss.backward()는 기울기를 구하기만 하였다. 이 기울기를 이용하여 학습에 이용되는 weight들을 loss가 적어지는 방향으로 변화시켜야 한다. 이러한 과정을 학습이라고 한다.
먼저 대략적인 optimizer의 종류는 다음과 같다.
ADADELTA | Adam | Adagrad | SparseAdam | Admax |
RMSProp | ASGD | Rprop | LBFGS | SGD |
너무 많다고 겁먹을 필요는 없다. 가장 대중적으로 쓰이는 optimzier인 SGD와 Adam정도만 숙지하면 큰 문제는 없을 것이다. 이제 Pytorch를 이용해 optimizer까지 구현해 보자.
매우 중요한 부분이니 한줄 한줄 살펴보겠다.
먼저 optimizer를 불러오기 위해 torch.optim을 import를 한다.
optimizer는 SGD(stochastic gradient descent)로 설정을 한후, learning rate를 0.01로 설정하였다. 위는 예제이므로 lr = 0.01으로 설정해 놓은것에 대해 불편함이 없었으면 한다. (general 하게는 SGD를 사용하게 되면, learning rate를 0.1로 설정한다. 그 이유에 대해서는 이후의 포스트에 첨부하겠다.)
이제 for문으로 가보자. 가장 중요한 코드인 optimizer.zero_grad()를 사용하지 않게되면 for문을 돌면서 이전에 optimizer를 호출하는 과정에서 생성된 기울기가 누적되기 때문에 zero_grad()를 잊지 않고 붙여주어야 한다.
마지막 줄에있는 optimizer.step()은 loss.backward에서 기울기를 구한 값을 이용하여 실제 학습되어야 하는 weight, bias 가 학습이 되는 코드이다.
지금까지 아주 기본적인 틀을 살펴 보았다. 다음 포스트 부터는 간단한 이미지 분류에 대해 포스트하겠다.
'Programming' 카테고리의 다른 글
[re] 라이브러리 (0) | 2020.03.21 |
---|---|
[Argparse] 라이브러리 (0) | 2020.03.01 |
Neural Network의 기초 with Pytorch (0) | 2020.02.21 |