I'm trying to understand how backpropagation works for a softmax/cross-entropy output layer.
The cross entropy error function is
$$E(t,o)=-\sum_j t_j \log o_j$$
with $t$ and $o$ as the target and output at neuron $j$, respectively. The sum is over each neuron in the output layer. $o_j$ itself is the result of the softmax function:
$$o_j=softmax(z_j)=\frac{e^{z_j}}{\sum_j e^{z_j}}$$
Again, the sum is over each neuron in the output layer and $z_j$ is the input to neuron $j$:
$$z_j=\sum_i w_{ij}o_i+b$$
That is the sum over all neurons in the previous layer with their corresponding output $o_i$ and weight $w_{ij}$ towards neuron $j$ plus a bias $b$.
Now, to update a weight $w_{ij}$ that connects a neuron $j$ in the output layer with a neuron $i$ in the previous layer, I need to calculate the partial derivative of the error function using the chain rule:
$$\frac{\partial E} {\partial w_{ij}}=\frac{\partial E} {\partial o_j} \frac{\partial o_j} {\partial z_{j}} \frac{\partial z_j} {\partial w_{ij}}$$
with $z_j$ as the input to neuron $j$.
The last term is quite simple. Since there's only one weight between $i$ and $j$, the derivative is:
$$\frac{\partial z_j} {\partial w_{ij}}=o_i$$
The first term is the derivation of the error function with respect to the output $o_j$:
$$\frac{\partial E} {\partial o_j} = \frac{-t_j}{o_j}$$
The middle term is the derivation of the softmax function with respect to its input $z_j$ is harder:
$$\frac{\partial o_j} {\partial z_{j}}=\frac{\partial} {\partial z_{j}} \frac{e^{z_j}}{\sum_j e^{z_j}}$$
Let's say we have three output neurons corresponding to the classes $a,b,c$ then $o_b = softmax(b)$ is:
$$o_b=\frac{e^{z_b}}{\sum e^{z}}=\frac{e^{z_b}}{e^{z_a}+e^{z_b}+e^{z_c}} $$
and its derivation using the quotient rule:
$$\frac{\partial o_b} {\partial z_{b}}=\frac{e^{z_b}*\sum e^z - (e^{z_b})^2}{(\sum_j e^{z})^2}=\frac{e^{z_b}}{\sum e^z}-\frac{(e^{z_b})^2}{(\sum e^z)^2}$$ $$=softmax(b)-softmax^2(b)=o_b-o_b^2=o_b(1-o_b)$$ Back to the middle term for backpropagation this means: $$\frac{\partial o_j} {\partial z_{j}}=o_j(1-o_j)$$
Putting it all together I get
$$\frac{\partial E} {\partial w_{ij}}= \frac{-t_j}{o_j}*o_j(1-o_j)*o_i=-t_j(1-o_j)*o_i$$
which means, if the target for this class is $t_j=0$, then I will not update the weights for this. That does not sound right.
Investigating on this I found people having two variants for the softmax derivation, one where $i=j$ and the other for $i\ne j$, like here or here.
But I can't make any sense out of this. Also I'm not even sure if this is the cause of my error, which is why I'm posting all of my calculations. I hope someone can clarify me where I am missing something or going wrong.