在深度学习中,我们常常选用sigmoid函数作为激活函数。sigmoid函数的具体形式如下:
曲线表示为:
再画大一点,取x区间更大一些,则为:
显然从图像上看,sigmoid函数是数值稳定的,即对于更大范围的x,y的取值是连续的,有效的。
从理论上看,
且中间数值可以从数学上证明是稳定的。
但我们考虑1-f(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得到启发。
主要办法就是对于
分别考虑正负x.
当
x≥0
时,维持上式不变;
当
x<0
时,分子分母同时乘以
ex
,则有:
此时绘制曲线为:
因此在实际coding中,我们需要考虑计算的稳定性。