J'étudie TensorFlow et comment l'utiliser, même si je ne suis pas un expert des réseaux de neurones et de l'apprentissage en profondeur (juste les bases).
Après des tutoriels, je ne comprends pas les différences réelles et pratiques entre les trois optimiseurs pour la perte. Je regarde le API et je comprends les principes, mais mes questions sont les suivantes:
1. Quand est-il préférable d'utiliser l'un au lieu des autres?
2. Y a-t-il des différences importantes à connaître?
Voici une brève explication basée sur ma compréhension:
Adam ou dynamique adaptative est un algorithme similaire à AdaDelta. Mais en plus de stocker les vitesses d'apprentissage pour chacun des paramètres, il stocke également les changements d'élan pour chacun d'eux séparément.
Je dirais que SGD, Momentum et Nesterov sont inférieurs aux 3 derniers.
La réponse de Salvador Dali explique déjà les différences entre certaines méthodes populaires (par exemple, les optimiseurs), mais je voudrais essayer de les développer davantage.
(Notez que nos réponses ne concordent pas sur certains points, en particulier en ce qui concerne ADAGRAD.)
(Principalement basé sur la section 2 du document Sur l’importance de l’initialisation et de l’élan dans l’apprentissage en profondeur .)
Chaque étape de CM et de NAG est en réalité composée de deux sous-étapes:
[0.9,1)
) De la dernière étape.CM prend d'abord la sous-étape de gradient, tandis que NAG prend la sous-étape d'élan en premier.
Voici une démonstration de ne réponse sur l'intuition pour CM et NAG :
Donc, NAG semble être meilleur (au moins dans l'image), mais pourquoi?
La chose importante à noter est que peu importe la date de la sous-étape de la dynamique, ce serait la même chose dans les deux cas. Par conséquent, nous pourrions aussi bien nous comporter si la sous-étape d'élan a déjà été franchie.
La question est donc la suivante: en supposant que la sous-étape de gradient soit prise après la sous-étape d'élan, devrions-nous calculer la sous-étape de gradient comme si elle commençait à la position avant ou après la sous-étape d'élan?
"Après" semble être la bonne réponse car, généralement, le gradient à un certain point θ
Vous indique approximativement la direction allant de θ
À un minimum (avec la magnitude relativement correcte), tandis que le Un gradient à un autre point est moins susceptible de vous orienter dans la direction allant de θ
à un minimum (avec l'ampleur relativement correcte).
Voici une démonstration (du gif ci-dessous):
Notez que cet argument pour lequel NAG est meilleur est indépendant du fait que l'algorithme soit proche du minimum.
En général, NAG et CM ont souvent le problème d’accumuler plus d’élan que ce qui est bon pour eux. Ainsi, chaque fois qu’ils doivent changer de direction, ils ont un "temps de réponse" embarrassant. L'avantage de NAG sur CM que nous avons expliqué n'empêche pas le problème, mais rend seulement le "temps de réponse" de NAG moins gênant (mais gênant tout de même).
Ce problème de "temps de réponse" est magnifiquement démontré dans le gif par Alec Radford (apparu dans réponse de Salvador Dali ):
(Principalement basé sur la section 2.2.2 dans ADADELTA: une méthode du taux d'apprentissage adaptatif (le document ADADELTA original), car je le trouve beaucoup plus accessible que Méthodes adaptatives de substitution pour l'apprentissage en ligne et stochastique Optimisation (le document original ADAGRAD).)
Dans SGD , l'étape est donnée par - learning_rate * gradient
, Tandis que learning_rate
Est un hyperparamètre.
ADAGRAD possède également un hyperparamètre learning_rate
, Mais le taux d'apprentissage réel de chaque composant du dégradé est calculé individuellement.
La i
- ème composante de la t
- ème étape est donnée par:
learning_rate
- --------------------------------------- * gradient_i_t
norm((gradient_i_1, ..., gradient_i_t))
tandis que:
gradient_i_k
Est le i
- ème composant du dégradé de la k
- ème étape(gradient_i_1, ..., gradient_i_t)
Est un vecteur avec des composants t
. Ce n’est pas intuitif (du moins pour moi) que la construction d’un tel vecteur ait un sens, mais c’est ce que fait l’algorithme (conceptuellement).norm(vector)
est la norme norme euclidienne (alias l2
) de vector
, qui est notre notion intuitive de longueur de vector
.gradient_i_t
(Dans ce cas, learning_rate / norm(...)
) est souvent appelée "taux d’apprentissage" (en fait, Je l'ai appelé "le taux d'apprentissage réel" dans le paragraphe précédent). J'imagine que c'est parce que dans SGD l'hyperparamètre learning_rate
Et cette expression sont identiques.Par exemple. si:
i
- ème composant du dégradé de la première étape est 1.15
i
- ème composant du dégradé de la deuxième étape est 1.35
i
- ème composant du dégradé de la troisième étape est 0.9
Alors la norme de (1.15, 1.35, 0.9)
Est la longueur de la ligne jaune, qui est:sqrt(1.15^2 + 1.35^2 + 0.9^2) = 1.989
.
Et le composant i
de la troisième étape est: - learning_rate / 1.989 * 0.9
Notez deux choses à propos du i
- ème composant de l’étape:
learning_rate
.Cela signifie qu'ADAGRAD est sensible au choix de l'hyperparamètre learning_rate
.
En outre, il se peut qu'après un certain temps, les étapes deviennent si petites que l'ADAGRAD reste pratiquement bloqué.
Du papier ADADELTA :
L'idée présentée dans ce document a été dérivée d'ADAGRAD afin de remédier aux deux principaux inconvénients de la méthode: 1) la décroissance continue des taux d'apprentissage tout au long de la formation, et 2) la nécessité d'un taux d'apprentissage global sélectionné manuellement.
Le document explique ensuite une amélioration destinée à remédier au premier inconvénient:
Au lieu d’accumuler la somme des gradients carrés sur tous les temps, nous avons limité la fenêtre des gradients antérieurs accumulés à une taille fixe
w
[...]. Cela garantit que l'apprentissage continue de progresser même après de nombreuses itérations de mises à jour.
La mémorisation dew
des gradients carrés précédents étant inefficace, nos méthodes implémentent cette accumulation comme une moyenne en décroissance exponentielle des gradients carrés.
Par "moyenne décroissante exponentielle des gradients carrés", le papier signifie que pour chaque i
, nous calculons une moyenne pondérée de toutes les composantes i
carrées de tous les gradients calculés.
Le poids de chaque élément i
au carré est supérieur au poids du composant i
au carré de l'étape précédente.
Il s’agit d’une approximation d’une fenêtre de taille w
car les poids des étapes précédentes sont très faibles.
(Quand je pense à une moyenne en décroissance exponentielle, j'aime visualiser un sentier de la comète , qui devient de plus en plus sombre à mesure qu'il s'éloigne de la comète:
Si vous modifiez uniquement ADAGRAD, vous obtiendrez RMSProp, une méthode proposée par Geoff Hinton dans Lecture 6e de sa classe Coursera .
Ainsi, dans RMSProp, la i
- ème composante de la t
- ème étape est donnée par:
learning_rate
- ------------------------------------------------ * gradient_i_t
sqrt(exp_decay_avg_of_squared_grads_i + epsilon)
tandis que:
epsilon
est un hyperparamètre qui empêche une division par zéro.exp_decay_avg_of_squared_grads_i
Est une moyenne décroissante de façon exponentielle des composantes au carré i
de la totalité des gradients calculés (y compris gradient_i_t
).Mais comme mentionné ci-dessus, ADADELTA vise également à se débarrasser de l'hyperparamètre learning_rate
, Il doit donc y avoir plus de choses à l'intérieur.
Dans ADADELTA, le i
- ème composant de la t
- ème étape est donné par:
sqrt(exp_decay_avg_of_squared_steps_i + epsilon)
- ------------------------------------------------ * gradient_i_t
sqrt(exp_decay_avg_of_squared_grads_i + epsilon)
tandis que exp_decay_avg_of_squared_steps_i
est une moyenne en décroissance exponentielle des composantes au carré i
de la totalité des étapes calculées (jusqu’à la t-1
- ème étape).sqrt(exp_decay_avg_of_squared_steps_i + epsilon)
est un peu similaire à la quantité de mouvement et, selon le document , il "agit comme un terme d'accélération". (Le papier donne également une autre raison pour laquelle il a été ajouté, mais ma réponse est déjà trop longue, alors si vous êtes curieux, consultez la section 3.2.)
(Principalement basé sur Adam: une méthode d'optimisation stochastique , le document d'Adam original.)
Adam est l'abréviation de Adaptive Moment Estimation (voir cette réponse pour une explication sur le nom).
La i
- ème composante de la t
- ème étape est donnée par:
learning_rate
- ------------------------------------------------ * exp_decay_avg_of_grads_i
sqrt(exp_decay_avg_of_squared_grads_i) + epsilon
tandis que:
exp_decay_avg_of_grads_i
Est une moyenne en décroissance exponentielle des i
- ème éléments de tous les gradients calculés (y compris gradient_i_t
).exp_decay_avg_of_grads_i
Et exp_decay_avg_of_squared_grads_i
Sont également corrigés pour tenir compte d'un biais en faveur de 0
(Pour plus d'informations à ce sujet, voir la section 3 dans l'article , et aussi ne réponse dans stats.stackexchange ).Notez que Adam utilise une moyenne décroissante de façon exponentielle des i
- èmes composantes des gradients où la plupart des méthodes SGD utilisent la méthode i
-ème composant du dégradé actuel. Cela entraîne Adam à se comporter comme "une balle lourde avec friction", comme expliqué dans l'article Les GAN formés par une règle de mise à jour à deux échelles de temps convergent vers un équilibre de Nash local .
Voir cette réponse pour en savoir plus sur la façon dont le comportement semblable au momentum d'Adam est différent du comportement habituel semblable au momentum.
Résumons-nous à une question simple:
Quel optimiseur me donnerait le meilleur résultat/précision?
Il n'y a pas de solution miracle. Certains optimiseurs pour votre tâche fonctionneraient probablement mieux que les autres. Il n’ya aucun moyen de le savoir à l’avance, vous devez en essayer quelques-uns pour trouver le meilleur. La bonne nouvelle est que les résultats de différents optimiseurs seraient probablement proches les uns des autres. Vous devez cependant trouver les meilleurs hyperparamètres pour chaque optimiseur que vous choisissez.
Quel optimiseur dois-je utiliser maintenant?
Peut-être, prenez AdamOptimizer et exécutez-le pour learning_rate 0.001 et 0.0001. Si vous voulez de meilleurs résultats, essayez de courir pour d’autres vitesses d’apprentissage. Ou essayez d’autres optimiseurs et réglez leurs hyperparamètres.
Il y a quelques aspects à considérer lors du choix de votre optimiseur:
Plain SGD est le strict minimum possible: il multiplie simplement les gradients par le taux d'apprentissage et ajoute le résultat aux poids. SGD a un certain nombre de belles qualités: il n'a qu'un seul hyperparamètre; il n'a pas besoin de mémoire supplémentaire; cela a un effet minimal sur les autres parties de la formation. Il présente également deux inconvénients: il peut être trop sensible au choix du taux d’apprentissage et la formation peut prendre plus de temps que d’autres méthodes.
À partir de ces inconvénients simples de SGD, nous pouvons voir quelles sont les règles de mise à jour les plus compliquées (optimiseurs): nous sacrifions une partie de notre mémoire pour obtenir une formation plus rapide et, éventuellement, simplifier le choix des hyperparamètres.
surcharge de mémoire est généralement non significatif et peut être ignoré. Sauf si le modèle est extrêmement volumineux, si vous vous entraînez sur GTX760 ou si vous vous battez pour le leadership d'ImageNet. Des méthodes plus simples comme le momentum ou le gradient accéléré de Nesterov nécessitent 1,0 ou moins de la taille du modèle (taille des hyperparamètres du modèle). Les méthodes de second ordre (Adam, peut nécessiter deux fois plus de mémoire et de calcul.
Vitesse de convergence - sage presque tout est meilleur que SGD et tout le reste est difficile à comparer. AdamOptimizer peut très bien commencer l’entraînement presque immédiatement, sans échauffement.
Je considère que facile à utiliser est le plus important dans le choix d'un optimiseur. Différents optimiseurs ont un nombre différent d'hyperparamètres et ont une sensibilité différente. Je considère Adam comme le plus simple des plus facilement disponibles. Vous devez généralement vérifier 2-4 taux d’apprentissage entre 0.001
et 0.0001
pour savoir si le modèle converge bien. Pour comparer SGD (et élan), j’essaie généralement de [0.1, 0.01, ... 10e-5]
. Adam a 2 autres hyperparamètres qui doivent rarement être changés.
Relation entre l'optimiseur et d'autres parties de la formation. Le réglage hyperparamètre implique généralement la sélection de {learning_rate, weight_decay, batch_size, droupout_rate}
simultanément. Tous sont interdépendants et chacun peut être considéré comme une forme de régularisation du modèle. Par exemple, il faut faire très attention si weight_decay ou L2-norm est utilisé et éventuellement choisir AdamWOptimizer
au lieu de AdamOptimizer
.