Résumé des méthodes d'optimisation du modèle


Le choix de la méthode d'optimisation du modèle est directement lié à la performance du modèle final. Parfois, l'effet n'est pas bon, pas nécessairement un problème de fonctionnalités ou de conception de modèle, mais probablement un problème d'algorithme d'optimisation, et un bon algorithme d'optimisation peut également aider à accélérer la formation du modèle.

Le processus de développement du modèle de deep learning :
SGD -> SGDM -> NAG -> AdaGrad -> AdaDelta -> Adam -> Nadam

1. Cadre général
Définir d'abord :
les paramètres à optimiser www , fonction objectif :f ( w ) f(w)f ( w ) , le taux d'apprentissageα \alphaα
par itération :

Calculer le gradient de la fonction objectif par rapport aux paramètres : gt = ▽ f ( wt ) gt=▽f(wt)g t=f ( w t )
calcule la quantité de mouvement de premier et second ordre à partir des gradients historiques :
mt = ϕ ( g 1 , g 2 , . . . , gt ) , V t = ψ ( g 1 , g 2 , . . . , gt ) mt=ϕ(g1,g2,...,gt),Vt=ψ(g1,g2,...,gt)m t=ϕ ( g 1 ,g 2 ,. . . ,g t ) ,V t=ψ ( g 1 ,g 2 ,. . . ,g t )

Calculer la pente de descente à l'instant courant : η t = α ⋅ mt / V t ηt=α⋅m_t / \sqrt{V_t}η t=unmt/Vt

Les paramètres sont mis à jour en fonction du gradient de descente : wt + 1 = wt − η t wt+1=wt−ηtw t+1=w t η t

Les étapes 3 et 4 sont cohérentes pour chaque algorithme, et la principale différence se reflète dans 1 et 2.

1. Méthode de descente de gradient SGD

La méthode d'optimisation la plus basique, mettant à jour les paramètres dans le sens du gradient négatif, est mise en œuvre comme suit :

# 梯度下降法
w += - learning_rate * dw

Parmi eux, learning_rate est un hyperparamètre représentant le taux d'apprentissage, la variable mise à jour est w, et son gradient est dw, gradient->position, ce qui est facile à comprendre.

défaut:

  • Il est possible de tomber dans un minimum local, et il est facile d'être piégé dans un point de selle ;
  • Il est facile de générer des oscillations et de ne pas converger, et finalement il fluctuera toujours autour de la valeur minimale, et n'atteindra pas la valeur minimale et restera ici ;
  • La vitesse de déclin est lente et la valeur optimale globale ne peut pas être atteinte avant longtemps ;
  • Il est difficile de choisir le rythme d'apprentissage approprié ;
  • Gradients uniformément mis à l'échelle dans toutes les directions, ne conviennent pas aux données clairsemées

2. Momentum

La méthode de l'élan est une sorte de méthode d'optimisation inspirée de l'élan en physique. Elle peut être simplement comprise comme : lorsque nous faisons rouler une petite boule sur une montagne, s'il n'y a pas de résistance, son élan augmentera, mais si nous rencontrons une résistance, la vitesse va être réduit. La mise en œuvre est la suivante :

# 动量法
w += beta * w - learning_rate * (1-beta) * dw  # 梯度影响速度

La valeur initiale de la variable v est définie sur 0, et l'hyperparamètre mu est considéré comme l'élan dans le processus d'optimisation, et sa signification physique peut être considérée comme le coefficient de frottement.L'ajout de cet élément peut rendre la vitesse de la dimension inchangée dans la direction du gradient plus rapidement, des mises à jour plus lentes sont effectuées dans les dimensions où la direction du gradient a changé, ce qui se traduit par une convergence plus rapide et moins d'oscillation. La différence avec avant est que le gradient n'affecte pas directement la position, gradient->velocity->position.

Avantages :

  • stabilité accrue;
  • convergence plus rapide;
  • Il existe également une certaine capacité à sortir des optimums locaux.

3. RMSprop

RMSprop (Root Mean Square prop) est une méthode de taux d'apprentissage adaptatif qui met toujours à jour la position en fonction des gradients. Pour supprimer l'agitation dans la descente de gradient, une moyenne pondérée exponentiellement des gradients au carré est ajoutée. La moyenne pondérée exponentiellement avec un grand gradient est grande, et la moyenne pondérée exponentiellement avec un petit gradient est petite, garantissant que les gradients de chaque dimension sont dans une bonne opportunité, réduisant ainsi les oscillations.
Pour une compréhension populaire de la moyenne pondérée de manière exponentielle, veuillez vous référer à https://zhuanlan.zhihu.com/p/29895933

# RMSprop
cache = decay_rate * cache + (1 - decay_rate) * dw**2 # 梯度平方的指数加权平均
w += - learning_rate * dw / (np.sqrt(cache) + eps) # 基于梯度更新

Parmi eux, decay_rate et eps sont des hyperparamètres , et la valeur de la variable cache à chaque étape est différente, elle peut donc être considérée comme un ajustement adaptatif au taux d'apprentissage.
Il existe d'autres optimiseurs avec de meilleurs effets, ces prérequis étant suffisants pour comprendre Adam, je ne les présenterai pas trop ici.

Adam

Adam peut être vu comme une combinaison de la méthode momentum et de RMSprop

# Adam
m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
x += - learning_rate * m / (np.sqrt(v) + eps)

Pour le traitement de m et v, une moyenne pondérée exponentiellement est également utilisée. Par rapport à RMSprop, le gradient est remplacé par un m lisse et le traitement du cache est fondamentalement inchangé. Les valeurs initiales des hyperparamètres beta1 et beta2 sont proches de 1, donc le terme de biais calculé est proche de 0.

AdamW

AdamW est un algorithme amélioré basé sur la régularisation Adam+L2.
Utiliser Adam pour optimiser la perte avec la régularisation L2 n'est pas efficace. Si le terme régulier L2 est introduit, le résultat du gradient du terme régulier sera ajouté lors du calcul du gradient. Ensuite, si les gradients correspondant à certains des poids qui sont relativement grands seront également relativement grands, puisque les éléments soustraits dans l'étape de calcul d'Adam seront divisés par l'accumulation du carré du gradient, les éléments soustraits seront petits. Il est de bon sens que les poids plus grands devraient pénaliser les plus gros, mais ce n'est pas le cas dans Adam. La décroissance des poids utilise le même coefficient pour mettre à jour tous les poids, et plus le poids est élevé, plus la pénalité est importante. Seule la régularisation L2 est fournie dans les bibliothèques d'apprentissage en profondeur communes, et il n'y a pas d'implémentation de la décroissance du poids.

image
Adam+L2 contre AdamW

Le rouge sur l'image est la méthode de régularisation traditionnelle Adam + L2, et le vert est la méthode Adam + weightdecay. On peut voir que la différence entre les deux méthodes ne réside que dans la position du "coefficient multiplié par la valeur du paramètre de l'étape précédente". Jetons un coup d'œil à l'implémentation spécifique d'AdamW en combinaison avec le code.

Le code suivant provient de la fonction apply_gradients dans AdamWeightDecayOptimizer dans https://github.com/macanv/BERT-BiLSTM-CRF-NER/blob/master/bert_base/bert/optimization.py , l'optimiseur dans BERT utilise cette méthode . Quelques commentaires sont également faits dans le code pour correspondre à la version simplifiée de la formule d'Adam donnée précédemment, qui est facile à comprendre. On peut voir que la phrase update += self.weight_decay_rate * param n'est pas dans Adam, c'est-à-dire le code correspondant à la partie verte dans Adam. L'étape weightdecay se produit après le calcul de mise à jour du paramètre qui doit être mis à jour dans Adam, et dans Adam C'est exactement le même ordre que le pseudocode dans l'image avant de multiplier par learning_rate. En bref, si vous utilisez weightdecay, vous n'avez plus besoin d'utiliser la régularisation L2.

      # m = beta1*m + (1-beta1)*dx
      next_m = (tf.multiply(self.beta_1, m) + tf.multiply(1.0 - self.beta_1, grad))
      # v = beta2*v + (1-beta2)*(dx**2)
      next_v = (tf.multiply(self.beta_2, v) + tf.multiply(1.0 - self.beta_2, tf.square(grad)))
      # m / (np.sqrt(v) + eps)
      update = next_m / (tf.sqrt(next_v) + self.epsilon)
      # Just adding the square of the weights to the loss function is *not*
      # the correct way of using L2 regularization/weight decay with Adam,
      # since that will interact with the m and v parameters in strange ways.
      #
      # Instead we want ot decay the weights in a manner that doesn't interact
      # with the m/v parameters. This is equivalent to adding the square
      # of the weights to the loss with plain (non-momentum) SGD.
      if self._do_use_weight_decay(param_name):
        update += self.weight_decay_rate * param
      update_with_lr = self.learning_rate * update
      # x += - learning_rate * m / (np.sqrt(v) + eps)
      next_param = param - update_with_lr

Le commentaire original en anglais expliquait également la différence entre Adam et la régularisation traditionnelle Adam + L2. Eh bien, vous devriez pouvoir comprendre Adam ici, et vous pouvez également comprendre l'amélioration d'AdamW sur Adam.

Anticiper,Radam ?

Lookahead et RAdam sont des optimiseurs relativement nouveaux, et les principes spécifiques ne sont pas introduits ici. Mais j'ai des questions auxquelles Dieu doit répondre.
Il y a un tel commentaire dans le code source de l'optimiseur introduit dans BERT

  # It is recommended that you use this optimizer for fine tuning, since this
  # is how the model was trained (note that the Adam m/v variables are NOT
  # loaded from init_checkpoint.)

C'est-à-dire qu'il est fortement recommandé d'utiliser l'optimiseur AdamW lors du réglage fin du BERT. En utilisant le BERT à 6 couches sur mon propre jeu de données NER, AdamW peut obtenir environ 98 % de la valeur F1. J'ai essayé d'utiliser RAdam, Lookahead + RAdam, Lookahead + AdamW et Ranger, et les résultats étaient très médiocres. La valeur F1 de 0 , soit environ 30 %, semble n'avoir aucun effet du tout.

Code source de référence du projet : https://github.com/macanv/BERT-BiLSTM-CRF-NER
RAdam , Lookahead : https://github.com/lifeiteng/Optimizers
https://github.com/michaelrzhang/lookahead : https://github.com/jyhengcoder/Ranger_tensorflow

LazyAdam

Il s'agit d'une variante de l'optimiseur Adam qui gère plus efficacement les mises à jour rares.

L'algorithme original d'Adam maintient deux accumulateurs de moyenne mobile pour chaque variable tranable ; cet accumulateur est mis à jour à chaque étape. Cette classe fournit un mécanisme de gestion plus paresseux pour les mises à jour de gradient de variables éparses. Il ne met à jour l'accumulation de la moyenne mobile que pour les indices de variables éparses qui sont présents dans le lot actuel, et non pour tous les indices. Par rapport à l'optimiseur Adam d'origine, il peut fournir une grande amélioration du débit de formation du modèle pour certaines applications. Cependant, il a une sémantique différente de celle de l'algorithme original d'Adam, ce qui peut conduire à des résultats attendus différents.

Notez qu'amsgrad n'est actuellement pas pris en charge, ce paramètre ne peut être que False.

Références

https://www.zhihu.com/question/323747423/answer/790457991
https://www.cnblogs.com/guoyaohua/p/8542554.html
https://zhuanlan.zhihu.com/p/63982470
https:/ /zhuanlan.zhihu.com/p/38945390

https://www.jianshu.com/p/e17622b7ffee

https://blog.csdn.net/yinyu19950811/article/details/90476956

https://ruder.io/optimizing-gradient-descent/index.html

https://mooc.study.163.com/learn/2001281003?tid=2403023002& trace_c_p_k2 =a20d455215c44c419594a999c46400ee#/learn/content

Je suppose que tu aimes

Origine blog.csdn.net/weixin_41744192/article/details/119813725
conseillé
Classement