Softmax cross entropy with logits can be defined as:
$a_i = \frac{e^{z_i}}{\sum_{\forall j} e^{z_j}}$
$l={\sum_{\forall i}}y_ilog(a_i)$
Where $l$ is the actual loss.
But when you look deep inside into C++ Tensorflow implementation of SoftmaxCrossEntropyWithLogits
operation, the exact formula which they use is descibed as:
$l={\sum_{\forall j}}y_j ((z_j-max(z))-log({\sum_{\forall i}}e^{z_i-max(z)}))$
The part: $z-max(z)$ - is perfectly understood - it is just normalization which helps to avoid under/overflow.
BUT:
Where is the actual
Softmax
in their implementation?Why from each $z_j$ they subtract $log({\sum_{\forall i}}e^{z_i-max(z)})$ before multiply it by $y_j$?
Note: One may argue that the code I provide is just Tensorflow's implementation of CrossEntropyWithLogits
operation, but the actual SoftmaxCrossEntropyWithLogits
operation - additionaly checks only dimentions and do not perform any more computation.