1. softmax
softmax函数比较简单,可以用如下公式表示
其中CC表示共有个类,即有CC个输出。并且一般将softmax的输出当做概率置信度结果,即
2. cross entropy
交叉熵的公式也很简单,对于两个向量y,xy,x(其中yy表示真实的概率分布),他们的交叉熵可表示如下:
其中p(xi)p(xi)表示softmax的输出,认为是预测的概率分布。
3. softmax loss和数值稳定问题
在深度学习中,这二者常被联合使用,softmax常被用来将输出映射到0~1的概率值,而cross entropy则常被用来作为分类模型的损失函数,构成常见的softmax loss。
在softmax loss中需要注意的是数值稳定的问题。softmax loss存在数值下溢和上溢的问题,如果∀j,xj=c∀j,xj=c,那么softmax的输出都一样∀j,softmax(xj)=1/n∀j,softmax(xj)=1/n。但如果c很小,比如c=- 999999999999, 那么就可能因为计算机的舍入误差导致ec=0ec=0,那么softmax函数的分母就等于0,就产生溢出,输出为nan,这就是下溢。同样,如果c特别大,比如c=999999999999999c=999999999999999,那么ecec就有可能等于无穷大,输出还是nan,那么就会上溢。不管是上溢还是下溢,都会出现Nan的情况,导致无法计算。那么怎么解决这个问题呢?
令r=maxixi,zj=xj−rr=maxixi,zj=xj−r,那么zj≤0zj≤0,而且有softmax(xj)=softmax(zj)softmax(xj)=softmax(zj)。因为ezj≤e0≤1ezj≤e0≤1,故不会出现上溢。而在分母中,至少包含一项ezj=e0=1ezj=e0=1,故分母不会等于0,因此也就不会产生下溢。
那么就可以通过softmax的结果,计算cross entropy。但计算交叉熵的时候,会涉及到log算子,那么又有可能出现溢出的问题。如果softmax的输出结果=0=0,那么就会导致需要计算log(0)log(0),其等于负无穷,导致溢出。对于该溢出风险,只需在计算log时做一个等式变化,不要先计算出softmax,再计算log,而是将公式融在一起,并做相关变化,如下:
可以发现,做上述等式变换后,没有了除法,故前面谈到的softmax的分母下溢问题没有了,指数运算最大值为1,不存在上溢风险,log算子中的求和式子最小值为1,也不会出现溢出。
在tensorflow和caffe中,针对softmax的数值不稳定,也有相应的处理机制。单独的softmax层是数值不稳定的,会发生溢出,而在tensorflow中,tf.nn.softmax_cross_entropy_with_logits是数值稳定的,caffe中softmaxwithloss是数值稳定的。
另外一个需要提醒的问题是,在用softmax loss做分类时,真实的概率分布一般都是one-hot的编码,即只有一个值等于1,而其他值全都等于0,比如[0,0,0,0,1,0,0][0,0,0,0,1,0,0],那么cross entropy的多个求和项,只有一项是非0的,即one hot编码中非0项对应的输出概率。