또한 DataLoader(데이터, batchsize, shuffle)를 이용하여 train_dataloader와 test_dataloader를 설정해준다.
4. 네트워크 및 모델 설계
이번 실습에서 사용할 네트워크는 MLP(Multi Layer Perceptron)이다.
하나의 퍼셉트론이 아닌 hidden layer를 포함한 신경망이라고 생각하면 되겠다.
이때 activation function은 ReLU를 사용한다.
다른 activation function으로는 Sigmoid가 있지만 이 함수는 미분을 계속하게되면 0으로 수렴하는 값을 내기 때문에
gradient vanishing 문제가 발생할 수 있다. 그래서 좀 덜한 ReLU를 사용한다.
각 layer 마다 입력, 출력, batch nomalization, activation function을 지정해줄 수 있다.
입력, 출력에는 특징의 갯수, 즉 차원을 써주면 되고
activation function은 사용할 활성화 함수를 써주면 된다.
batch nomalization은 뭘까?
각 layer를 지날때마다 입력된 분포와 출력된 분포가 달라지고 이에 따라 발생하는 문제를 줄이기 위해 각 mini batch마다 nomalization을 해주는 방법이다. 이 batchnorm은 activation function을 사용하기 전에 사용하는 것이 일반적이라고 한다.
모델을 설계할때는
import torch.nn as nn
model = nn.Sequential(layer, batch_norm, activation_func)
이런 형식으로 설계할 수 있고
model = model.to(device)
이런 형식으로 생성할 수 있다.
device는 gpu 또는 cpu로 설정할 수 있다.
마지막 layer의 activation function은 softmax 함수이다. (현재상황에서는)
하지만 activation_func 자리에 nn.softmax 이런식으로 쓰지않는다.
이유는 6번에서 알려주도록 하겠다.
5. weight initialization
weight initialization은 weight를 0으로 초기화하지 않고 적절한 초기화방법을 이용하여 학습의 성능을 높여줄 수 있다.
방법에는 "Restricted Boltzmann Machine", "Xavier", "He" 초기화 방법이 있는데 RBM은 복잡해서 잘 안쓰이고
간단한 Xavier, He를 쓴다. He는 Xavier의 변형된 방법이다.
import torch.nn as nn
#Xavier를 이용한 초기화
nn.init.xavier_uniform_(layer.weight) #이거 혹은
nn.init.xavier_normal_(layer.weight) #이거
6. loss function, optimizer
딥러닝의 궁극적인 목표는 loss 값을 최소로 하는 모델을 만드는 것이다.
loss function에는 cross entropy loss, binary cross entropy 등등이 있지만 여기서의 출력값이 두가지가 아니기 때문에
cross entropy loss function을 쓰도록 했다.
import torch.nn as nn
criterion = nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
이렇게 쓸 수 있다.
아까 출력 층의 activation function을 써주지 않는 이유를 말하자면
cross entropy loss function이 softmax 기능도 해주기 때문이다!!
optimizer는 gradient를 최적화 해주는 친구이다.
optimizer의 종류에는 Adam, SGD(Stochastic Gradient Descent) 등이 있는데 SGD는 Adam에 비해 느리다고 배웠다..
그래서 Adam을 사용했다. optimizer에게는 모델의 변수들과 학습률을 알려줘야한다. lr는 이미 정해둔 값이다.
7. train
training 시키는 단계이다.
epoch만큼 돌면서 batch size만큼 가져와서 학습을 시킨다.
학습을 시키는 단계는 다음과 같다.
output = model(X) # 예측값 구하기
cost = criterion(output, Y) # loss 값 구하기
optimizer.zero_grad() # 이전 계산된 gradient 초기화
cost.backward() # gradient 계산
optimizer.step() # 모델의 parameter들 학습
8. test
model.eval() # test 하겠다
with torch.no_grad():
블라블라~~
이런식으로 진행한다.
torch.no_grad()는 진행하면서 gradient 학습을 하지 않겠다는 말이다.
당연한 얘기겠지??
이런 단계를 가지고 코드를 짰고
결과는
높은 accuracy를 가지고 잘 진행되었다.
내가 위에 적은 코드는 정말 최소~로 필요한 코드기 때문에 기본기만 훑었다고 생각하면 될 듯 하다.
인공지능에 대해 아무것도 몰랐지만 그래도 부스트코스덕분에 100중에 0.5는 안 것 같다. 설명 진짜 잘하신다!