在深度学习中,我们常常选用sigmoid函数作为激活函数。sigmoid函数的具体形式如下:
f(x)=11+e−x
曲线表示为:
再画大一点,取x区间更大一些,则为:
显然从图像上看,sigmoid函数是数值稳定的,即对于更大范围的x,y的取值是连续的,有效的。
从理论上看,
limx→+∞f(x)=1;limx→−∞f(x)=0
且中间数值可以从数学上证明是稳定的。
但我们考虑1-f(x)呢?
1−f(x)=e−x1+e−x
我们用matlab绘制其曲线:
我们发现这时,当x趋向负无穷,甚至仅仅x趋向-800,此时1-f(x)就不再稳定了,在matlab的值变成了NAN了。
其实我们发现,对于 1- f(x),显然当x趋向正无穷时,还是稳定的,此时:
分子:e−x→0,而分母:1+e−x→1,
显然01,结果趋向0.
但是当x趋向负无穷时,此时,
分子: e−x→+∞,而分母:1+e−x→+∞,
此时:
e−x1+e−x就会变得不稳定,尽管理论上趋向1。
因此就出现了以上的图像。
那么如何解决这种不稳定问题的解呢?
其实有两种办法:
(一)先计算稳定的f(x),结果赋予y,再计算1-y .
乍看从数学上,好像完全一致,但是在数值解上不等价。 y=f(x)是稳定的,因此对于1-f(x)=1-y也变成了稳定的解。
我们从图像上证明:
此时就正确了,与理论解完全一致。
(二)直接从1-f(x)着手
这里我们从caffe的sigmoid_cross_entropy_loss_layer.cpp得到启发。
主要办法就是对于
1−f(x)=e−x1+e−x
分别考虑正负x.
当x≥0时,维持上式不变;
当x<0时,分子分母同时乘以ex,则有:
e−x1+e−x=⎧⎩⎨⎪⎪⎪⎪e−x1+e−x11+exx≥0x<0
此时绘制曲线为:
因此在实际coding中,我们需要考虑计算的稳定性。