Softmax
함수는 Multi Class Classification model
을 만들 때 사용한다.Cross Entropy
는 두 확률 분포 간의 유사도를 계산하는 방법 중 하나이다.
Classification 문제에서는 Cross Entropy가 손실 함수로 자주 사용된다.
이 때, 예측값과 실제값의 분포 간의 차이를 계산하여,
분류 모델이 예측을 잘못한 경우에 높은 손실 값을 나타내고,
예측을 잘한 경우에는 낮은 손실 값을 나타낸다.
- : 입력값
- : 실제값
- : 예측값
PyTorch에서 CrossEntropyLoss는 (LogSoftmax + NLLLoss)로 구현되어 있다.
LogSoftmax
NLLLoss(Negative Log Likelihood Loss)
https://pytorch.org/docs/stable/generated/torch.nn.NLLLoss.html
https://pytorch.org/docs/stable/optim.html
reference : https://pytorch.org/docs/stable/nn.init.html#torch.nn.init.normal_
Hyper Parameter에 따른 Loss Function 값과 accuracy를 구하여 시각화해본다.
LR = 0.1
accuracy = 0.10이 나왔었다
나의 생각 :
Learning Rate를 크게 했기 때문에 Global Minimum에 가지 못하고 발산하여
Local Minimum(2.30x)에 수렴하여 못 빠져나오는 것 같다.
== 잘못 학습된 것 같다.
LR = 0.01
나의 생각 :
Loss값이 빠르게 0으로 수렴하는 것을 알 수 있고,
적절한 Learning Rate를 부여함으로써 학습이 잘 된 것같다.
LR = 0.001
Loss값이 빠르게 0으로 수렴하는 것을 알 수 있고,
적절한 Learning Rate를 부여함으로써 학습이 잘 된 것같다.
LR = 0.01과 굳이 차이를 보자면 좀 더 부드럽게 Loss값이 줄어드는 것을 알 수 있다.
만약 Epoch이 충분히 컸다면 이 차이는 더 명확히 보였을 것 같다.
LR = 0.0001
나의 생각 :
LR = 0.01, 0.001보다 학습이 천천히 진행된 것을 알 수 있다.
하지만 학습이 잘못되지 않은 것은 아니다.
Epoch가 충분히 컸다면 Loss값은 0에 더욱 수렴되어 Accuracy가 더 높았을 것이다.
나의 생각 :
forward 계산과 weight update 과정을 5번만 했기 때문에 제대로된 학습을 하지 못했다.
Epoch을 더 크게 했다면 Loss가 0에 더 수렴해갈 것이다.
나의 생각 :
forward 계산과 weight update 과정을 5번보다는 더 많이 했기 때문에
Epoch=5일 때보다제대로된 학습을 했다.
하지만 여전히 Epoch 수가 부족하기 때문에 Loss가 0에 가까워지기엔 멀다.
Epoch을 더 크게 했다면 Loss가 0에 더 수렴해갈 것이다.
1. Epoch 수를 늘리면 Train Set에 대한 학습이 충분히 되어 Train Set에 대해서 Loss값이 0에 수렴해진다.
2. Epoch 수를 늘리면 Train Set에 대한 Accuracy가 점점 증가하긴 하는데,
증가하는 크기가 점점 감소한다.
(+0.0918 ➡️ +0.009 ➡️ +0.0054 ➡️ ... ➡️ -0.00?)
== Test Set에만 Overfitting되고 있다.
== Epoch 수를 매우 많이 늘린다면 Accuracy 증가가 아니라 감소가 되어 Accuracy가 작아질 수 있다.
3. Epoch이 클수록 학습 시간이 오래 걸린다.
batch size를 10로 했을 때, 15분 53초.
Test Set의 데이터가 60,000개이고 batch size를 10로 했기 때문에
1 Epoch에 6,000번 반복을 수행한다.
batch size를 30로 했을 때, 8분 22초.
Test Set의 데이터가 60,000개이고 batch size를 30로 했기 때문에
1 Epoch에 2,000번 반복을 수행한다.
batch size를 100로 했을 때, 5분 26초.
Test Set의 데이터가 60,000개이고 batch size를 100로 했기 때문에
1 Epoch에 600번 반복을 수행한다.
batch size를 1,000로 했을 때, 5분 26초.
Test Set의 데이터가 60,000개이고 batch size를 1,000로 했기 때문에
1 Epoch에 60번 반복을 수행한다.
따라서 Batch Size가 클수록 빠르다.
Batch Size가 클수록 빠르니까 Batch Size를 크게 하면 되지 않을까?
그러면 반대로 Batch Size를 작게 한다면?
# CNN Model
class CNN(torch.nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.keep_prob = 0.5 # 남겨둘 뉴런 비율
# L1 ImgIn shape=(?, 28, 28, 1)
# Conv -> (?, 28, 28, 32)
# Pool -> (?, 14, 14, 32)
self.layer1 = torch.nn.Sequential(
torch.nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2))
# L2 ImgIn shape=(?, 14, 14, 32)
# Conv ->(?, 14, 14, 64)
# Pool ->(?, 7, 7, 64)
self.layer2 = torch.nn.Sequential(
torch.nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2))
# L3 ImgIn shape=(?, 7, 7, 64)
# Conv ->(?, 7, 7, 128)
# Pool ->(?, 4, 4, 128)
self.layer3 = torch.nn.Sequential(
torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2, padding=1))
# L4 FC 4x4x128 inputs -> 625 outputs
self.fc1 = torch.nn.Linear(4 * 4 * 128, 625, bias=True)
torch.nn.init.xavier_uniform_(self.fc1.weight)
self.layer4 = torch.nn.Sequential(
self.fc1,
torch.nn.ReLU(),
torch.nn.Dropout(p=1 - self.keep_prob)) #임의로 0으로 만들어 overfitting을 방지하는 역할을 합니다. p 인자는 드롭아웃할 뉴런의 비율을 나타냅니다. 1 - self.keep_prob은 남겨둘 뉴런의 비율을 나타냅니다.
# L5 Final FC 625 inputs -> 10 outputs
self.fc2 = torch.nn.Linear(625, 10, bias=True)
torch.nn.init.xavier_uniform_(self.fc2.weight)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = self.layer3(out)
out = out.view(out.size(0), -1) # Flatten them for FC
out = self.layer4(out)
out = self.fc2(out)
return out