Question

I ai un simple réseau de neurones à une couche cachée et softmax que la fonction d'activation de la couche de sortie. La couche cachée utilise diverses fonctions d'activation depuis que je suis essai et mettre en œuvre le plus grand nombre d'entre eux que je peux.

Pour la formation et de test pour le moment je suis en utilisant le jeu de données MNIST de chiffres écrits à la main afin que mes données d'entrée est une matrice qui dans chaque ligne a une image différente et dans chaque colonne un pixel de cette image qui a été remodelé comme vecteur .

Quand j'utilise un sigmoïde fonction d'activation pour les couches les gradients calculés et gradients analytiques semblent se mettre d'accord, mais quand j'essayer quelque chose d'autre comme tanh ou softplus pour la couche cachée et softmax pour la couche de sortie, il y a de grandes différences comme on le voit à partir des données ci-dessous (côtés gauche> numérique dégradé, le bouton droit> analyse Gradient)

(1) sigmoïde (2) softmax

  -9.4049e-04  -6.4143e-04
  -6.2623e-05  -2.5895e-05
   1.0676e-03   6.9474e-04
  -2.0473e-03  -1.3471e-03
   2.9846e-03   1.9716e-03
   4.0945e-05   2.7627e-05
  -2.5102e-05  -1.7017e-05
   8.8054e-06   6.0967e-06
   7.8509e-06   5.0682e-06
  -2.4561e-05  -1.6270e-05
   5.6108e-05   3.8449e-05
   2.0690e-05   1.2590e-05
  -9.7665e-05  -6.3771e-05
   1.7235e-04   1.1345e-04
  -2.4335e-04  -1.6071e-04

(1) tanh (2) softmax

  -3.9826e-03  -2.7402e-03
   4.6667e-05   1.1115e-04
   3.9368e-03   2.5504e-03
  -7.7824e-03  -5.1228e-03
   1.1451e-02   7.5781e-03
   1.5897e-04   1.0734e-04
  -9.6886e-05  -6.5701e-05
   3.3560e-05   2.3153e-05
   3.3344e-05   2.1786e-05
  -1.0282e-04  -6.8409e-05
   2.1185e-04   1.4774e-04
   9.0293e-05   5.3752e-05
  -4.0012e-04  -2.6047e-04
   6.9648e-04   4.5839e-04
  -9.7518e-04  -6.4468e-04

(1) sigmoïde (2) sigmoïde

-9.2783e-03  -9.2783e-03
   8.8991e-03   8.8991e-03
  -8.3601e-03  -8.3601e-03
   7.6281e-03   7.6281e-03
  -6.7480e-03  -6.7480e-03
  -3.0498e-06  -3.0498e-06
   1.4287e-05   1.4287e-05
  -2.5938e-05  -2.5938e-05
   3.6988e-05   3.6988e-05
  -4.6876e-05  -4.6876e-05
  -1.7506e-04  -1.7506e-04
   2.3315e-04   2.3315e-04
  -2.8747e-04  -2.8747e-04
   3.3532e-04   3.3532e-04
  -3.7622e-04  -3.7622e-04
  -9.6266e-05  -9.6266e-05

La façon dont je mets en œuvre rétropropagation est la suivante:

variables->

Theta1 , Theta2 . tables avec les différents coefficients de pondération pour la première et la seconde couche

m : taille de mon jeu de formation

y : un vecteur avec la bonne catégorie pour chaque échantillon d'entrée

Y : une matrice avec l'une de codage à chaud pour la catégorie pour chaque échantillon d'entrée

X : une matrice avec des données d'entrée, chaque ligne est un échantillon d'apprentissage différent

% Feedforward
a1 = [ones(m, 1) X];
z2 = a1*Theta1';
a2 = [ones(m, 1) activation(z2, activation_type)];
z3 = a2*Theta2';
a3 = activation(z3, 'softmax');
h = a3;

% Calculate J
J = sum(sum((-Y).*log(h) - (1-Y).*log(1-h), 2))/m + lambda*p/(2*m); # sigmoid
%J = -(sum(sum((Y).*log(h))) + lambda*p/(2*m)); # softmax

% Calculate sigmas
sigma3 = a3.-Y;
sigma2 = (sigma3*Theta2).*activationGradient([ones(m, 1) z2], 'sigmoid');
sigma2 = sigma2(:, 2:end);

% Accumulate gradients
delta_1 = (sigma2'*a1);
delta_2 = (sigma3'*a2);

Le premier calcul des coûts J a été calculé pour sigmoïde et celui ci-dessous pour softmax (voir les commentaires) donc je basculer entre les deux .

Ai-je raté quelque chose pendant rétropropagation, pourquoi est-il fonctionne pas comme prévu avec sigmoïdes mais pas comme prévu avec sofmax ?

Était-ce utile?

La solution

Je pense qu'il pourrait être un bug relativement trivial dans votre fonction de coût pour softmax:

J = -(sum(sum((Y).*log(h))) + lambda*p/(2*m)) 

doit être

J = -sum(sum((Y).*log(h)))/m + lambda*p/(2*m) 

i.e.. pour softmax seulement, vous avez effectivement soustrait le terme de régularisation de la fonction de coût au lieu de l'ajouter. En outre, vous avez oublié de diviser le terme d'erreur par le nombre d'exemples dans le lot (et que vous prenez cette moyenne lors du calcul des gradients)

Vos calculs de propagation arrière semblent corrects pour moi si vous corrigez cette erreur de calcul pour J.

Licencié sous: CC-BY-SA avec attribution
scroll top