Question

Je tente de mettre en place le réseau de neurones à partir de zéro pour comprendre les mathématiques derrière elle. Mon problème est complètement lié à rétropropagation lorsque nous prenons dérivée par rapport au biais) et je dérive toutes les équations utilisées dans rétropropagation. Maintenant, chaque équation correspondant à ce code de réseau de neurones à l'exception de ce que la dérivée par rapport au biais.

z1=x.dot(theta1)+b1

h1=1/(1+np.exp(-z1))
z2=h1.dot(theta2)+b2
h2=1/(1+np.exp(-z2))

dh2=h2-y
#back prop

dz2=dh2*(1-dh2)
H1=np.transpose(h1)
dw2=np.dot(H1,dz2)
db2=np.sum(dz2,axis=0,keepdims=True)

J'ai regardé en ligne pour le code, et je veux savoir pourquoi nous ajoutons la matrice et le db2=np.sum(dz2,axis=0,keepdims=True) scalaire est soustrait du biais original, pourquoi ne pas la matrice dans son ensemble est soustrait. aider quelqu'un peut me donner quelques intuion derrière. Si je prends dérivée partielle de la perte par rapport à polariser me donner un gradient supérieur que ce qui est DZ2 parce z2=h1.dot(theta2)+b2 h1 et thêta sera de 0 et b2 sera 1. Ainsi sera laissé le terme supérieur.

b2+=-alpha*db2
Était-ce utile?

La solution

Le terme de polarisation est très simple, ce qui est la raison pour laquelle vous ne voyez souvent pas calculé. En fait

db2 = dz2

Ainsi, vos règles de mise à jour pour le biais sur une seul élément sont:

b2 += -alpha * dz2

et

b1 += -alpha * dz1

En ce qui concerne les mathématiques, si votre perte est de $ J $, et vous savez $ \ frac {\ J partielle} {\ Z_I partielle} $ pour un donné neurone i $ $ qui a terme de biais $ b_i $. . .

$$ \ frac {\ J partielle} {\ b_i partielle} = \ frac {\ J partielle} {\ Z_I partielle} \ frac {\ Z_I partielle} {\ b_i partielle} $$

et

$$ \ frac {\ Z_I partielle} {\ b_i partielle} = 1 $$

parce que $ Z_I = (\ texte {} quelque chose non affecté par b_i) + b_i $


Il semble que le code copié utilise la forme

db2=np.sum(dz2,axis=0,keepdims=True)

parce que le réseau est conçu pour des exemples de processus par lots (mini), et vous avez donc gradients calculés pour plus d'un exemple à la fois. La somme est Squashing les résultats vers le bas à une mise à jour unique. Ce serait plus facile de confirmer si vous avez aussi montré un code de mise à jour pour les poids.

Autres conseils

Je voudrais expliquer le sens de db2=np.sum(dz2,axis=0,keepdims=True) comme il m'a aussi confus une fois et il n'a pas obtenir une réponse.

Le dérivé de L (perte) w.r.t. b est la dérivée en amont multipliée par la dérivée locale : $$ \ Frac {\ L partielle} {\ partial \ mathbf {b}} = \ frac {\ L partielle} {\ Z partielle} \ frac {\ Z partielle} {\ partial \ mathbf {b}} $$

Si nous avons plusieurs échantillons Z et L sont les deux matrices. b est encore un vecteur.

Le dérivé local est simplement un vecteur de ceux : $$ \ Frac {\ Z partielle} {\ partial \ mathbf {b}} = \ frac {\ partial} {\ partial \ mathbf {b}} W \ times X + \ mathbf {b} = \ mathbf {1} $$

Cela signifie que notre dérivé complet est une multiplication de matrice, qui se présente comme suit (2 échantillons avec par exemple 3 sorties.): $$ \ Frac {\ L partielle} {\ Z partielle} \ times \ mathbf {1} = \ Begin {} bmatrix . &. &. \\ . &. &. \ End {} bmatrix \ Begin {} bmatrix 1\\ 1\\ \ End {} bmatrix $$

Notez que ceci est la somme des lignes .

Et là db2=np.sum(dz2,axis=0,keepdims=True) vient. Il est tout simplement une abréviation pour la multiplication matricielle des dérivés local et les amont.

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