Skip to main content

HuggingFace에서의 조기 종료(early stopping) – 예시

조기 종료 정규화(regularization)를 통해 HuggingFace Transformer를 미세 조정합니다.
Created on March 3|Last edited on January 21
이는 여기에서 볼 수 있는 영어 기사를 번역한 것이다.

서론

이번 리포트에서는 조기 종료 정규화(early stopping regularization)을 사용해 HuggingFace Transformer를 미세 조정하는 예를 살펴보겠습니다. HuggingFace의 Trainer API와 함께 네이티브 PyTorch 및 TensorFlow 워크 플로를 통해 조기 종료 사용에 대해서 다루겠습니다.

early-stopping-en.png



네이티브 TensorFlow

Colab에서 TF를 사용하여 HuggingFace Transformer 미세 조정하기 →\rightarrow

TensorFlow(Keras)를 사용하여 HuggingFace Transformer를 미세 조정하는 경우, tf.keras.callbacks.EarlyStopping 콜백을 통해 조기 종료를 간단하게 추가할 수 있습니다. 여기에는 모니터링할 메트릭의 이름과 개선이 없는 경우 훈련을 중지할 epoch(에포크) 수가 필요합니다.

early_stopper = tf.keras.callbacks.EarlyStopping(monitor='val_loss', 
                                                 patience=5, 
                                                 restore_best_weights=True)

여기서 early_stoppermodel.fit과 함께 사용할 수 있는 콜백입니다.

model.fit(trainloader, 
          epochs=10, 
          validation_data=validloader,
          callbacks=[early_stopper])

관측

  • 모델은 검증 손실(validation loss)에서 분명히 알 수 있는 훈련 데이터세트에서 빠르게 오버핏(overfit) 되었습니다.

  • 조기 종료(early stopping)를 포함한 훈련 모델은 훈련 프로세스의 조기 종료(early termination)으로 이어집니다. 이를 통해 계산상 비용(computational cost)과 시간을 절약할 수 있습니다.

  • 모델의 최적 인스턴스(가장 낮은 검증 손실)는 EarlyStopping 콜백을 사용하여 저장되었으므로, 실험 정확도 결과는 보다 일반화된 모델을 나타냅니다.




Run set
4


네이티브 PyTorch

Colab에서 PyTorch를 사용하여 HuggingFace Transformer 미세 조정하기 →\rightarrow

네이티브 PyTorch는 기성의(off-the-shelf) 조기 종료(early stopping) 방법이 없습니다. 그러나 네이티브 PyTorch를 사용하여 HuggingFace Transformer를 미세 조정할 경우, 여기 조기 정지 후크(early stopping hook)를 제공하는 GitHub Gist가 있습니다.

class EarlyStopping(object):
    def __init__(self, mode='min', min_delta=0, patience=10, percentage=False):
        self.mode = mode
        self.min_delta = min_delta
        self.patience = patience
        self.best = None
        self.num_bad_epochs = 0
        self.is_better = None
        self._init_is_better(mode, min_delta, percentage)

        if patience == 0:
            self.is_better = lambda a, b: True
            self.step = lambda a: False

    def step(self, metrics):
        if self.best is None:
            self.best = metrics
            return False

        if np.isnan(metrics):
            return True

        if self.is_better(metrics, self.best):
            self.num_bad_epochs = 0
            self.best = metrics
        else:
            self.num_bad_epochs += 1

        if self.num_bad_epochs >= self.patience:
            print('terminating because of early stopping!')
            return True

        return False

    def _init_is_better(self, mode, min_delta, percentage):
        if mode not in {'min', 'max'}:
            raise ValueError('mode ' + mode + ' is unknown!')
        if not percentage:
            if mode == 'min':
                self.is_better = lambda a, best: a < best - min_delta
            if mode == 'max':
                self.is_better = lambda a, best: a > best + min_delta
        else:
            if mode == 'min':
                self.is_better = lambda a, best: a < best - (
                            best * min_delta / 100)
            if mode == 'max':
                self.is_better = lambda a, best: a > best + (
                            best * min_delta / 100)


훈련 루프(training loop)에서 조기 종료(early stopping)를 사용하시려면 위에 링크된 Colab notebook 을 확인하시기 바랍니다.

es = EarlyStopping(patience=5)

num_epochs = 100
for epoch in range(num_epochs):
      train_one_epoch(model, data_loader)  # train the model for one epoch.
      metric = eval(model, data_loader_dev)  # evalution on dev set.
      if es.step(metric):
          break  # early stop criterion is met, we can stop now

PyTorch Lightning을 사용하여 PyTorch 코드를 재구성하기를 적극적으로 추천합니다. 이는 조기 종료(early stopping) 및 그 외 많은 테크닉을 즉시 사용할 수 있습니다. PyTorch Lightning에 대해 잘 모르는 경우, 다음과 같은 리포트를 참조하여 시작할 수 있습니다:




Run set
2

Iterate on AI agents and models faster. Try Weights & Biases today.