HuggingFace中的Early Stopping ——示例
使用Early Stoping正则化功能微调您的HuggingFace Transformer。
Created on February 25|Last edited on July 12
Comment
导言
在此报告中,我们将看到一些示例,这些示例使用early stopping正则化来微调您的HuggingFace Transformer。 我们将使用原生PyTorch和TensorFlow工作流程以及HuggingFace的Trainer API来讲解early stopping的使用。
原生TensorFlow
在Colab中使用TF微调HuggingFace Transformer →\rightarrow
如果您使用TensorFlow(Keras)来微调HuggingFace Transformer,则使用tf.keras.callbacks.EarlyStopping
回调来添加early stopping非常简单。 它采用您将监视的指标的名称,以及在没有改善的情况下停止训练的epoch数。
early_stopper = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
patience=5,
restore_best_weights=True)
这里early_stopper
是可以与model.fit
一起使用的回调。
model.fit(trainloader,
epochs=10,
validation_data=validloader,
callbacks=[early_stopper])
观察结果
-
该模型很快在训练数据集上过度拟合,这从验证损失中可以明显看出。
-
early stopping训练模式会导致训练过程提前终止。反过来,这节省了计算成本和时间。
-
由于使用
EarlyStopping
回调保存了模型的最佳实例(最低的验证损失),测试准确性表明模型更为通用。
Run set
4
原生PyTorch
在Colab中使用PyTorch微调HuggingFace Transformer →\rightarrow
原生PyTorch没有现成的early stopping方法。但是,如果您使用原生PyTorch对HuggingFace Transformer进行微调,则可以使用GitHub Gist ,它提供了一个有效的early stopping hook。
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)
要在训练循环中使用early stopping,请查看上面链接的Colab笔记本。
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
Add a comment
Iterate on AI agents and models faster. Try Weights & Biases today.