基本公式:
Si=∑j=0Cezjezi
其中,输入z为一个C维向量,输出S也是一个C维向量,这里的C通常就是分类里面的类别数量。公式的分母对于每个输出Si都是一样的,区别只在于分子ezi,从这个角度看softmax就有点类似于归一化操作,实际效果也是把任意范围的输入变成[-1,1]的输出(维度不变)。图像如下:

softmax交叉熵损失函数实际上就是通过softmax来计算各个类别的预测得分yj^,然后根据得分计算Loss:
Lce=−ylog(y^)=−log(y^)
其中上式中y为标签值,也就是1,y^是根据上面公式算出来的得分(分子为正确类别y对应的输入zy):
y^=∑j=0Cezjezy
两式合并:
Lce=−log(∑j=0Cezjezy)
参考从最优化的角度看待Softmax损失函数,这里对Softmax的更深层次的的含义进行一下探究。
在分类问题中,我们最朴素的目标就是输出一个C维向量,使目标类别(假设为第y类)zy最大,形式化为(这里下标y和j表示类别编号):
zy>zj(∀j=y)
在优化的过程中,最朴素的方式就是使zy变大,而其他的zj=y变小,于是目标函数:
L=j!=y∑C(zj−zy)
为了避免z无限制的下降,对其进行限制(类似于relu)
L=j!=y∑Cmax(zj−zy,0)
这个函数的优化结果将使L逐渐下降到0,此时分类边界zj=y=zy,但通常只有平时努力想考100分同学真正考试的时候才能拿到95分,目标是95分的同学只能考90分。于是我们人为的加入一个margin(这个margin得适中,太小了不起作用,太大了模型可能不收敛,一般类别数C较少时margin稍大,反之亦然),强迫不同的类别之间的分数拉大距离,使训练时候的难度更大,这样实际测试的时候泛化能力才更强,于是:
L=j!=y∑Cmax(zj−zy+m,0)
这个目标函数中,L是对所有的类别(j=0,1…C)都将会进行考虑,即计算梯度的时候会对所有的zj进行计算,更新权重的时候梯度也会向所有类别的路径进行传播。这在二分类问题中一般没什么问题(二分类中的CE函数L=−m1∑i=0m[yilogyi^+(1−yi)log(1−yi^)],既考虑目标类别,也考虑非目标类别),但在多分类中,特别是类别数特别多的情况下,如果所有类别都进行计算,将会有大量的非目标分数得到优化,这样每次优化时的梯度幅度不等且非常巨大,极易梯度爆炸。
所以多分类时一般只考虑目标类别,同时考虑“个别”非目标类别,达到平衡的目的,这个“个别”的非目标类别,我们应该怎么挑呢?
无疑,我们应该挑分数最大的那个(分数最大说明错的离谱,类似于hard example mining),于是我们的目标就是:
使目标分数比最大的非目标分数更大
形式化如下:
L=max(maxj=y(zj)−zy+m,0)
这里就没有了对所有类别的求和,而是改成了求所有类别里的最大分数值,这样目标类别和非目标类别都只求一个梯度,即优化参数时只有一个+1和一个-1梯度进入网络,达到平衡的目的。
为了均衡考虑各个非目标类别,可以对max函数做一个smooth:
maxj=y(zj)≈log(j=0,j=y∑Cezj)
上式把max smooth成LogSumExp,而其中LogSumExp的梯度刚好就是softmax:
∂zi∂log(∑j=0,j=yCezj)=∑j=0,j=yCezjezi
相当于通过softmx的分配方式,给其他非目标类别分一点梯度
于是目标函数变成:
L=max(log(j=0,j=y∑Cezj)−zy,0)
更进一步,还可以把max(x,0)smooth成softplus,即max(x,0)≈log(1+ex),于是:
L=log(1+elog(∑j=0,j=yCezj)−zy)=log(1+ezyelog(∑j=0,j=yCezj))=log(ezy∑j=0,j=yCezj+ezy)=log(ezy∑j=0Cezj)=−log(∑j=0Cezjezy)
这个就是softmax交叉熵损失函数了。
从上述分析过程我们可以看到,softmax虽然看起来简单,但实际上从朴素目标函数出发,包含了平滑过程(使优化过程更加通畅)、非目标类别选择(使正负梯度得以平衡)、梯度分配(梯度按softmax方式分配给各个非目标类别)等过程。