1. 학습 곡선
본인이 직접 모델을 만든다던가, 논문을 구현하던가, 이미 있는 모델을 조금 바꿔서 훈련시킨다던가 할때 학습 곡선을 보는것은 굉장히 유용합니다. 학습 곡선은 보통 Train set과 Validation(test) set에 대해서 각각 loss와 metric을 훈련 중간중간 마다 체크한 곡선을 말합니다.
위와 같은 사진이 일반적인 학습곡선 입니다. 위 사진은 Loss로 Cross Entropy, Metric으로는 Accuracy를 사용했고 Epoch 마다 계산한 값을 plotting 한 것 입니다.
2. 학습 곡선의 유용성
위 사진 같은 경우는 단순하게 생각하면 loss가 얼마고, metric 수치는 얼마구나를 알 수 있습니다. 숫자로도 볼 수 있지만, 아무래도 사진이 한눈에 들어오니까 편하죠.
학습 곡선은 거의 반드시 사용해야 합니다. 저렇게 loss, metric을 체크하면 지금 모델이 underfit 되고 있는지, overfit 되고 있는지, 또는 그 외의 문제가 있는지를 알 수 있습니다. 이런 문제점을 체크함으로써 모델의 성능을 높이기 위해 데이터를 추가해야 하는지, feature를 늘려야 하는지, 모델의 크기를 늘려야 하는지 다른 문제를 봐야하는지를 알 수 있죠.
3. 오버피팅과 언더피팅
머신러닝, 특히 딥러닝은 오버피팅과의 싸움이라고 하는데 실제 모델링을 처음 진행해보시면 오버피팅 만큼이나 언더피팅을 조심해야 합니다. 아무리 훈련을 시켜도 모델이 성능을 안보여주는 상황인 것이죠. 이럴때 무작정 layer를 늘려서 모델의 사이즈를 키운다던가, 데이터를 막 수집한다고 해결이 되지는 않습니다.
위 사진은 선형모델로써 표현한 underfitting / fit / overfitting 사진 입니다. 언더피팅 모델은 train set의 sample 조차 제대로 모델링 하지 못했고, 오버피팅 모델은 train set의 sample에 지나치게 적합되어서 그 외의 데이터를 표현하지 못합니다. 이런 문제를 일반화가 안되었다고도 합니다.
그리고 어려운 말로 오버피팅 상황을 High Variance(과분산), 언더피팅 상황을 High Bias(과편향) 이라고도 합니다. 머신러닝을 먼저 익히신 분이라면 익숙한 단어일 텐데, 햇갈리기 쉬운 용어기도 합니다.
보통 Bias와 Variance는 서로 tradeoff 관계에 있습니다. 적절한 균형을 맞춰야 모델이 잘 만들어지기 때문에, Bias나 Variance 둘중에 하나가 크게 높아질 경우 언더피팅 또는 오버피팅이 일어나는 것 입니다. 가장 최악은 High Bias, High Variance 상황이겠죠. 이런 문제를 해결하는 것을 정밀하게 수행하는게 쉽지는 않습니다. 다만 학습 곡선을 이용하면 Bias와 Variance 중 무엇을 개선해야 하는지를 어느정도 알 수 있습니다.
4. 학습 곡선 사용 방법
학습 곡선을 보는 방법은, 언더피팅과 오버피팅이 무엇인지에 대해서 생각해보면 알 수 있습니다. 간단하게 말하면 Train set과 Validation set의 loss가 같이 충분히 떨어지는게 좋습니다. Metric으로 Accuracy 등을 사용한다면, Metric 지수도 같이 좋아지는게 바람직하겠죠.
(1) 훈련이 잘 되고 있을 때
위의 사진을 보면 loss는 계속 떨어지고, Accuracy는 높아지고 있죠. 그렇다면 일단 훈련이 잘 진행되고 있고, 언더피팅과 오버피팅이 일어나지 않았구나 라고 알 수 있습니다.
또 위의 사진을 보면 알 수 있는게 있습니다. 아직 loss는 계속 떨어지는 추세 입니다. 이럴 경우 모델이 아직 saturation이 안되었다고 말합니다. 모델이 잘 만들어졌고, 데이터도 적절하다면 훈련을 지속했을때 train set loss와 validation set loss가 같이 떨어지다가, 어느 순간 validation set loss가 상승하는 경우를 볼 수 있습니다. 일반적으로 그 지점에서 훈련을 중단합니다. 그 전에 훈련을 멈추면, 언더피팅인 상태고, 훈련을 더 계속하면 오버피팅 상태로 보는 것이죠. 이런 방식으로 훈련의 시간을 정하는 방식을 Early Stopping이라고도 부릅니다.
물론 딥러닝은 과적합으로써 성능을 보이는 것이고, 따라서 훈련을 더시키거나 덜 시키는 방법을 사용하시는 분들도 간혹 있는 것 같습니다. 그러나 다른 이유가 없다면 보통 저 지점, 다시 반복하자면 validation set loss가 떨어지다가 더이상 떨어지지 않고 상승하는 부분에서 멈추는 방식(early stopping)을 사용하는게 일반적 입니다.
(2) 훈련이 잘 안되는 경우
그리고 훈련이 잘 안되는 경우가 더 많을 것 입니다. 훈련이 잘 안되는 경우에 학습곡선을 보면, loss가 애초에 떨어지지를 않는다던가, loss가 떨어졌다가 올라갔다가 떨어졌다가 요동을 친다던가 하는 여러 문제가 있습니다. 심지어 train loss 보다 validation loss가 계속 더 낮은 상황도 나올 수 있죠. 가장 일반적인 상황 두가지를 예시로 들어보겠습니다.
1) Train set, validation set의 loss가 둘다 안떨어질때
모델이 일단 학습을 하나도 못하고 있는 상황인 것 입니다. 이럴때는 Loss 구현이 잘 못 되어 있나도 살펴보게 되고... 데이터가 너무 적은 건가? 싶기도 합니다만, 보통 모델의 복잡도를 더 크게 할 경우 해결이 될 것 입니다. 딥러닝의 경우 filter수를 늘린다던가, layer를 늘린다던가를 하는 것이죠.
2) Train set의 loss는 떨어지는데 validation set의 loss가 안 떨어질때
이럴 때는 validation set의 loss가 하나도 안떨어지는지, 불안정한지, 일정부분 이상 안떨어지는지를 봐야 합니다. 일반적으로는 train set으로 훈련한 모델이, 그 외의 샘플에 대해서는 작동을 하지 않는 상황인 겁니다. 데이터를 추가하는 방식이 가장 좋고, 그게 안된다면 모델의 일반화 성능을 좋게 해주는 방법을 찾아서 써야 합니다.
결국 모델의 복잡도는 적절해야 하고, 데이터는 보통 많으면 많을수록 좋고 합니다. 이 모든 방법을 한번에 사용하면 모델의 성능은 개선 될 것이나, 자원(시간, 하드웨어 등)은 한정적이기 때문에 가장 문제가 되는 부분을 해결해야 하는 것 입니다. 그 외에 Train set과 Validation set이 서로 동질성을 가지는지, 둘다 전체 데이터셋을 대표할만한 데이터인지도 보셔야 합니다.
그외에 정말 중요한 요소 중 하나는 'Learning rate(학습율)' 입니다. 학습율이 너무 낮거나 높으면 언더피팅, 오버피팅의 위험이 생깁니다. 보통 언더피팅이 되는 것 같다면 학습율을 더 작게 하고, 오버피팅이 된다 싶으면 학습율을 더 높이는 방식을 사용합니다.
* (21-06-24 수정 및 추가)
* 언더피팅 관련 내용을 설명할 때 자주 쓰이는 그림과 용어 입니다. 경사하강법(Gradient Descent)을 통한 학습을 진행할때 가장 일반적으로 마주치는 문제 중 하나는 위 그림에서 'local minimum' 이라는 부분에서 갇히게 되는 경우입니다. 단순히 '학습율'의 관점으로만 봤을때, 작은 학습율의 경우 local minimum 주위를 왔다갔다 하면서 벗어나지 못합니다. 이럴 경우 학습율을 크게 해주는 것만으로도 local minimum을 벗어나 다른 minimum 값을 찾아 학습을 진행할 수 있게 해줍니다.
* 위의 그림에 관한 추가 설명을 하자면, 단순히 학습율 말고도 momentum 등의 방식, API로 쉽게 사용할 수 있는 Adam 등의 Optimizer 등은 모두 위의 local minimum에 쉽게 갇히지 않도록 하는 방법을 사용합니다. (추후 기회가 되면 포스팅...)
그 외에 학습율을 시간에 따라서 줄이는 learning rate decay 방식 등 다양한 방법들도 존재합니다.
5. 학습 곡선을 그리는 방법
학습 곡선을 그리는 건 본인 취향에 따라 하시면 됩니다. Tensorboard를 이용하셔도 되고, 모델의 훈련 상황을 저장하는 방식을 이용해도 되고, 모델을 직접 구현해서 epoch 마다 loss와 metric을 계산하여도 됩니다. Transfer Learning code 중 학습곡선 관련 코드를 일부 이곳에다가 올려놓겠습니다. 이번 글에서 사용한 학습 곡선을 그리는데 사용한 코드 입니다.
Tensorflow 2.0에서 Keras api를 이용한 방식 입니다. 모델의 학습 내용을 저장해놓고, 그 내용을 토대로 plotting 한것 입니다.
...
#Tensorflow의 Keras api
history = model.fit(train_batches,
epochs=initial_epochs,
validation_data=validation_batches)
#Plotting
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()),1])
plt.title('Training and Validation Accuracy')
plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0,1.0])
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()
'딥러닝' 카테고리의 다른 글
14. AutoEncoder (0) | 2019.11.23 |
---|---|
13. RNN (순환 신경망) (0) | 2019.11.20 |
11. Activation Function (활성화 함수) (0) | 2019.11.18 |
10. Transfer Learning (0) | 2019.11.16 |
9. CNN - Transposed, Dilated, Causal (0) | 2019.11.14 |