Supposons que nous utilisons une taille de lot de 100 échantillons pour l'apprentissage.
Donc, dans chaque lot, le poids de chaque neurone (et biais, etc.) est mis à jour en ajoutant le moins du taux d'apprentissage * la valeur d'erreur moyenne que nous avons trouvée en utilisant les 100 échantillons * la dérivée de la fonction d'erreur par rapport à le poids actuel des neurones mis à jour.
Maintenant, lorsque nous utilisons une couche Max Pool, comment pouvons-nous calculer la dérivée sur cette couche? Dans chaque échantillon que nous alimentons en avant, un pixel différent (disons) est choisi comme maximum, donc quand nous rétropropagons plus de 100 échantillons dans lesquels chaque fois qu'un chemin différent a été choisi, comment pouvons-nous le faire? Une solution que j'ai à l'esprit est de se souvenir de chaque pixel qui a été choisi comme maximum, puis de diviser la dérivée sur tous les pixels max. C'est ce qui se fait?
Réponses:
Lorsqu'un réseau neuronal traite un lot, toutes les valeurs d'activation pour chaque couche sont calculées pour chaque exemple (peut-être en parallèle par exemple si la bibliothèque et le matériel le prennent en charge). Ces valeurs sont stockées pour une utilisation ultérieure possible - c'est-à-dire une valeur par activation par exemple dans le lot, elles ne sont en aucun cas agrégées
Pendant la rétropropagation, ces valeurs d'activation sont utilisées comme l'une des sources numériques pour calculer les gradients, ainsi que les gradients calculés jusqu'à présent en arrière et les poids de connexion. Comme la propagation avant, la propagation arrière est appliquée par exemple, elle ne fonctionne pas avec des valeurs moyennes ou sommées. Ce n'est que lorsque tous les exemples ont été traités que vous travaillez avec les dégradés sommés ou moyennés pour le lot.
Cela s'applique également aux couches de pool max. Non seulement vous savez quelle était la sortie de la couche de regroupement pour chaque exemple du lot, mais vous pouvez également regarder la couche précédente et déterminer quelle entrée dans le pool était maximale.
Mathématiquement, et en évitant de définir des indices pour les couches NN et les neurones, la règle peut être exprimée comme ceci
La fonction avant estm = m a x ( a , b )
Nous savons∂J∂m pour une fonction cible J (dans le réseau neuronal qui sera la fonction de perte que nous voulons minimiser, et nous supposons que nous avons déjà rétropropagé à ce point)
Nous voulons savoir∂J∂une et ∂J∂b
Sia > b
Localement , * . Doncm = a ∂J∂une=∂J∂m
Localement , * ne dépend pas de . Doncm b ∂J∂b=0
Par conséquent si , sinon∂J∂a=∂J∂m a>b ∂J∂a=0
et si , sinon∂J∂b=∂J∂m b>a ∂J∂b=0
Lorsque la propagation arrière traverse une couche de regroupement maximale, le gradient est traité par exemple et affecté uniquement à l'entrée de la couche précédente qui était maximale. Les autres entrées ont un gradient nul. Lorsque cela est groupé, ce n'est pas différent, il est simplement traité par exemple, peut-être en parallèle. Sur un lot entier, cela peut signifier que plus d'une, peut-être la totalité, des activations d'entrée dans le pool max obtiennent une part du gradient - chacune provenant d'un sous-ensemble différent d'exemples du lot.
* Localement -> lorsque vous effectuez uniquement des modifications infinitésimales sur .m
** Techniquement, si exactement nous avons une discontinuité, mais dans la pratique , nous pouvons ignorer que , sans problèmes lors de la formation d' un réseau de neurones.a=b
la source
J'ai la même question, mais je la comprends probablement en examinant le code source de Caffe.
Veuillez consulter le code source de Caffe:
lignes 620 et 631 de ce code.
Il calcule la dérivée de chaque paramètre en ajoutant la dérivée (de ce paramètre) de chaque entrée, puis la divise par la taille du lot.
Voir également la ligne 137 de ce code, il redimensionne simplement le dérivé à 1 / iter_size, exactement comme la moyenne.
Nous pouvons voir qu'il n'y a AUCUN traitement spécial pour la couche Max Pooling lorsque BP.
Quant au dérivé de Max Pooling, voyons à nouveau le code source de Caffe:
ligne 272 de ce code. De toute évidence, seule la dérivée du plus grand élément est
1*top_diff
, la dérivée des autres l'est0*top_diff
.la source