Doby's Lab

Tensorflow의 Callback(EarlyStopping, ReduceLROnPlateau) 본문

Code about AI/tensorflow

Tensorflow의 Callback(EarlyStopping, ReduceLROnPlateau)

도비(Doby) 2023. 1. 3. 23:54

Callback

keras는 Callback이라는 개념이 있습니다. 에포크를 진행하면서 특정한 값을 모니터링하면서 학습에 변동사항을 주는 기능입니다. Callback에는 여러 가지 종류가 많지만 자주 쓰이는 2가지만 알아봅시다.


EarlyStopping

EarlyStopping이란 조기 종료라는 뜻으로 에포크를 진행하면서 Overfitting으로 간주된다면 학습을 멈추는 Callback입니다.

조금 더 디테일하게 접근하기 위해 함수부터 알아봅시다.

early_stopping_cb = keras.callbacks.EarlyStopping(monitor='val_loss', mode='min',
                                                  min_delta=0,
                                                  patience=10, verbose=1,
                                                  restore_best_weights=True)

함수를 보면 많은 인자가 있습니다. 다 가져온 것은 아니지만 거의 많이 쓰이고, 대부분을 가져왔습니다.

 

  • monitor: 모니터링할 값을 고릅니다. (val_loss(default), val_accuracy 등)
  • mode: min(더 이상 감소하지 않으면 멈춘다), max(...), auto(default, loss면 min으로 accuracy면 max로 자동 설정)
  • min_delta: 최소 변동값을 정하여 min_delta보다 작은 값이 변동했다면 개선을 했다고 보지 않는다.
  • patience: 일시적으로 개선이 안 된 것일 수도 있으므로 몇 차례 Consecutive(연속적인) Epochs를 본다.
  • verbose: epoch에 EarlyStopping이 어디서 멈추게 했고, 몇 번째 Epoch에 멈췄는지 나오게 한다.
  • restore_best_weights: 마지막 에포크를 저장하는 게 아닌 monitor 하는 값이 최적의 상태일 때의 모델을 저장한다.

 

자세히 구현된 부분은 아래 Keras 구현 링크에 있습니다. Python의 Class를 알고 있다면 쉽게 이해할 수 있습니다.

https://github.com/keras-team/keras/blob/master/keras/callbacks.py#L2120

 

GitHub - keras-team/keras: Deep Learning for humans

Deep Learning for humans. Contribute to keras-team/keras development by creating an account on GitHub.

github.com


EarlyStopping Issue

조기 종료의 조건에 대해 잘못 알고 있었던 부분에 대해 짚고 넘어가려 합니다. 정확히는 patience입니다.

더보기

# 위 그래프 구현 코드

plt.xlim(0, 9)
plt.ylim(0, 2)
plt.title('Epochs & Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
x_epoch = np.arange(1, 9)
y_loss = np.array([1.8, 1.2, 0.5, 0.8, 1.2, 1.3, 1.0, 0.9])
plt.plot(x_epoch, y_loss)
plt.plot(x_epoch, y_loss, 'o')
plt.show()

EarlyStopping으로 Epoch가 멈추는 원리

위 그림에서 EarlyStopping을 걸고 patience가 4라 했을 때, 위 그래프는 7번째 에포크에서 멈춰야 합니다. 왜냐하면 3번째 에포크에서 0.5라는 최소 Loss값이 구해졌고, 이보다 더 작은 Loss가 4번의 consecutive epochs에서 나오지 않았기 때문입니다.

 

제가 오해했던 조기 종료의 조건은 'N번째 에포크가 N-1번째 에포크보다 높아지면 patience를 고려할 값에 +1을 한다.'는 것이었습니다. 즉, 변화가 없거나 Loss가 올라가는 게 최저점과 상관없이 patience만큼 consecutive 하게 일어났다면 멈추는 줄 알았습니다.

 

즉, 멈추는 원리는 최솟값이 나온 이후로 patience 동안 더 이상의 최솟값이 나오지 않으면 멈추는 원리입니다.

 

(DACON에 물어봤었는데 링크 남겨두겠습니다.)

https://dacon.io/forum/407555?page=1&dtype=recent&fType= 

 

Tensorflow의 Earlystopping에 대해 질문을 드립니다.

 

dacon.io


ReduceLROnPlateau

ReduceLROnPlateau는 모델의 개선의 여지가 없을 때, 학습률을 조정하여 weight의 변동량을 줄여보는 Callback입니다.

왜냐하면 parameter가 수렴하지 않고 진동하며 발산하는 경우를 생각했을 때 학습률을 줄여 변동량을 줄이면 진동하지 않고, 손실함수가 완만하게 내려갈 수 있기 때문입니다.

 

Local Minima에 빠지지 않게 인자들의 값 설정이 매우 중요합니다.

learning_rate_reduction_cb = keras.callbacks.ReduceLROnPlateau(
    monitor='val_accuracy', patience = 4, verbose=1, factor=0.5, min_lr=0.00001
)

EarlyStopping의 인자와 중복되는 인자들은 넘어가겠습니다.

단, ReduceLROnPlateau의 monitor 인자 default는 'val_accuracy'입니다.

  • factor: 학습률을 조정시킬 때 곱하는 값입니다. Learning rate = Learning rate * factor
  • cooldown: 학습률이 감소한 후, 지정된 에포크 동안은 cooldown이 적용되어 Callback이 일어나지 않습니다.
  • min_lr: 학습률의 최솟값입니다. factor를 통해 갱신되는 학습률이 min_lr보다 작아진다면 새로운 학습률은 min_lr이 됩니다.

Compile

이러한 Callback 함수를 만든 후에는 모델을 돌리기 전에 Compile 단계에서 Callback 함수를 넘겨주어야 합니다.

아래와 같이 리스트의 형태로 callbacks의 인자에 넘겨주면 됩니다.

history = model.fit(x_train, y_train, epochs=50, validation_data=(x_val, y_val),
               callbacks=[early_stopping_cb, learning_rate_reduction_cb], batch_size = 16)
728x90