I have always struggled with calculating gradients in backpropagation,
especially when there are matrices involved.
Here I will talk about how I solved the question below as an exercise.
It is question 2(c) in Assignment 1 of Stanford’s CS224n, Winter 2017.
I found it quite difficult, mentally, to do back propagation in terms of vectors,
so I calculate the partial derivatives w.r.t. an element of some vector,
and then vectorize the result, which means I would first calculate
∂xi∂J=scalar,
and then derive ∂x∂J=vector.
I’m not sure this is the right way to do it,
but I got the same results as the official solution. I hope it helps you!
Derive the gradients with respect to the inputs x to an one-hidden-layer neural network (that is, find ∂x∂J where J=CE(y,y^) is the cost function for the neural network). The neural network employs sigmoid activation function for the hidden layer, and softmax for the output layer. Assume the one-hot label vector is y, and cross entropy cost is used. (Feel free to use σ′(x) as the shorthand for sigmoid gradient, and feel free to define any variables whenever you see fit.)
Recall that the forward propagation is as follows
h=sigmoid(xW1+b1)
y^=softmax(hW2+b2)
Note that here we’re assuming that the input vector (thus the hidden variables and output probabilities) is a row vector to be consistent with the programming assignment. When we apply the sigmoid function to a vector, we are applying it to each of the elements of that vector. Wi and bi(i=1,2) are the weights and biases, respectively, of the two layers.
Let z2=hW2+b2, then J=CE(y,y^), and y^=softmax(z2).
We already know that ∂z2∂J=y^−y, which means ∂z2i∂J=y^i−yi,for i=1,...,I.
Now we go back.
∂hj∂z2i=W2ji
Let z1=xW1+b1,
∂xj∂z1i∂xk∂J∂x∂J=W1ji=i∑I∂z2i∂J∂xk∂z2i=i∑I(y^i−yi)(j∑J∂hj∂z2i⋅∂xk∂hj)=i∑I(y^i−yi)(j∑JW2ji⋅σ′(z1)jW1kj)=i∑Ij∑J(y^i−yi)W2jiσ′(z1)jW1kj=j∑Ji∑I(y^i−yi)W2jiσ′(z1)jW1kj=j∑J((y^−y)W2T)j⊙σ′(z1)jW1kj=(y^−y)W2T⊙σ′(z1)W1T
I then tried to do the calculation with matrices:
∂z2∂J∂h∂z2∂z1∂h=y^−y=W2T=σ′(z1)
However, I can’t multiply them together, because ∂z2∂J
is a 1×I vector, ∂h∂z2 is an I×J matrix,
while ∂z1∂h is a 1×J vector.
Now it would be tempting (and even correct) to multiply them element-wise,
but it does not make sense! Can someone please explain this to me?
Updated on Feb 23, 2018
Hats off to Rex Ying!
It is so nice of you to explain this to me!
It turns out that ∂z1∂h is a J×J matrix,
but it is diagonal. The elements on the diagonal are the same as those in σ′(z1).
(The function σ is an element-wise function,
which means every element in the output vector is determined solely by
the corresponding element in the input vector.)
Now element-wise multiplication makes sense because
it is the same as multiplying this diagonal matrix!
Now it is easy to see that:
∂z1∂J∂x∂z1∂x∂J=(y^−y)W2T⊙σ′(z1)=W1T=(y^−y)W2T⊙σ′(z1)W1T
Finally!