L’extraction d’informations à partir de documents
Introduction
Dans ce rapport, nous verrons des exemples d’utilisation de régularisation par arrêt prématuré pour affiner votre modèle Transformer HuggingFace. Nous aborderons l’usage de l’arrêt prématuré avec le flux de travail natif de PyTorch et TensorFlow, avec l’API Trainer de HuggingFace.
Tensorflow natif
Affiner Transformer HuggingFace en utilisant TF dans le Colab →\rightarrow
Si vous utilisez TensorFlow (Keras) pour affiner un Transformer HuggingFace, l’ajout d’un arrêt prématuré est très simple avec la fonction de rappel tf.keras.callbacks.EarlyStopping
. Il assimile le nom du métrique que vous voulez surveiller et le nombre d’epochs après lequel l’entraînement devra être arrêté s’il n’y a pas d’améliorations.
early_stopper = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
patience=5,
restore_best_weights=True)
Ici, early_stopper
est la fonction de rappel qui peut être utilisée avec model.fit
.
model.fit(trainloader,
epochs=10,
validation_data=validloader,
callbacks=[early_stopper])
Observations
-
Le modèle fait rapidement du surapprentissage (overfitting) sur le jeu de données d’entraînement, ce qui est évident par rapport à la perte de validation.
-
Entraîner le modèle avec l’arrêt prématuré induit l’arrêt prématuré du processus d’entraînement. Cette manœuvre permet d’alléger les contraintes de puissance informatique et le temps d’exécution.
-
Puisque la meilleure instance du modèle (la perte de validation la plus faible) a été sauvegardée via la fonction de rappel
EarlyStopping
, la précision de test obtenue indique un modèle plus généralisé.
PyTorch Natif
Affiner Transformer HuggingFace en utilisant PyTorch dans Colab →\rightarrow
Le modèle natif PyTorch n’inclut pas de méthode d’arrêt prématuré prêt à l’emploi. Mais si vous affinez votre Tranformer HuggingFace en utilisant PyTorch natif, voici un GitHub Gist qui fournit un hook d’early stopping fonctionnel.
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)
Pour utiliser l’early stopping dans votre boucle d’entraînement, consultez le Colab notebook dont le lien est cité un peu plus haut.
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
Je vous recommande vivement de réorganiser votre code PyTorch en utilisant le PyTorch Lightning. Il fournit des techniques d’arrêt prématuré et d’autres techniques prêtes à l’emploi. Si vous êtes novice en PyTorch Lightning, voici quelques rapports qui vous aideront à démarrer :