激活函数(activation functions)的目标是,将神经网络非线性化。激活函数是连续的(continuous),且可导的(differential)。
- 连续的:当输入值发生较小的改变时,输出值也发生较小的改变;
- 可导的:在定义域中,每一处都是存在导数;
常见的激活函数:sigmoid,tanh,relu。
sigmoid
sigmoid是平滑(smoothened)的阶梯函数(step function),可导(differentiable)。sigmoid可以将任何值转换为0~1概率,用于二分类。细节可以参考。
公式:
导数:
导数2:
图(红色原函数,蓝色导函数):
sigmoid当使用sigmoid作为激活函数时,随着神经网络隐含层(hidden layer)层数的增加,训练误差反而加大。表现为:
- 靠近输出层的隐含层梯度较大,参数更新速度快,很快就会收敛;
- 靠近输入层的隐含层梯度较小,参数更新速度慢,几乎和初始状态一样,随机分布;
- 在含有四个隐藏层的网络结构中,第一层比第四层慢了接近100倍!
这种现象就是梯度弥散(vanishing gradient)。而另一种情况,梯度爆炸(exploding gradient),则是前面层的梯度,通过训练变大,导致后面层的梯度,以指数级增大。
sigmoid的更新速率由于sigmoid的导数值小于1/4,x变化的速率要快于y变化的速率,随着层数的增加,连续不断执行sigmoid函数,就会导致,前面更新较大的幅度,后面更新较小的幅度,因此,网络在学习过程中,更倾向于,更新后面(靠近输出层)的参数,而不是前面的参数(靠近输入层)。
sigmoid的导函数sigmoid缺点:
- 激活函数的计算量较大,在反向传播中,当求误差梯度时,求导涉及除法;
- 在反向传播中,容易就会出现梯度消失,无法完成深层网络的训练;
- 函数的敏感区间较短,(-1,1)之间较为敏感,超过区间,则处于饱和状态,
tanh
tanh,即双曲正切(hyperbolic tangent),类似于幅度增大sigmoid,将输入值转换为-1至1之间。tanh的导数取值范围在0至1之间,优于sigmoid的0至1/4,在一定程度上,减轻了梯度消失的问题。tanh的输出和输入能够保持非线性单调上升和下降关系,符合BP(back propagation)网络的梯度求解,容错性好,有界。
公式:
导数:
图(红色原函数,蓝色导函数):
tanhsigmoid和tanh:
- sigmoid在输入处于[-1,1]之间时,函数值变化敏感,一旦接近或者超出区间就失去敏感性,处于饱和状态,影响神经网络预测的精度值;
- tanh的变化敏感区间较宽,导数值渐进于0、1,符合人脑神经饱和的规律,比sigmoid函数延迟了饱和期;
- tanh在原点附近与y=x函数形式相近,当激活值较低时,可以直接进行矩阵运算,训练相对容易;
- tanh和sigmoid都是全部激活(fire),使得神经网络较重(heavy)。
relu
relu,即Rectified Linear Unit,整流线性单元,激活部分神经元,增加稀疏性,当x小于0时,输出值为0,当x大于0时,输出值为x.
公式:
图:
relu导数:
图:
ReLU的导函数relu对比于sigmoid:
- sigmoid的导数,只有在0附近,具有较好的激活性,而在正负饱和区的梯度都接近于0,会造成梯度弥散;而relu的导数,在大于0时,梯度为常数,不会导致梯度弥散。
- relu函数在负半区的导数为0 ,当神经元激活值进入负半区,梯度就会为0,也就是说,这个神经元不会被训练,即稀疏性;
- relu函数的导数计算更快,程序实现就是一个if-else语句;而sigmoid函数要进行浮点四则运算,涉及到除法;
relu的缺点:
在训练的时候,ReLU单元比较脆弱并且可能“死掉”。举例来说,当一个很大的梯度,流过ReLU的神经元的时候,可能会导致梯度更新到一种特别的状态,在这种状态下神经元将无法被其他任何数据点再次激活。如果这种情况发生,那么从此所以流过这个神经元的梯度将都变成0。也就是说,这个ReLU单元在训练中将不可逆转的死亡,因为这导致了数据多样化的丢失。
如果学习率设置得太高,可能会发现网络中40%的神经元都会死掉(在整个训练集中这些神经元都不会被激活)。通过合理设置学习率,这种情况的发生概率会降低。
在神经网络中,隐含层的激活函数,最好选择ReLU。
关于RNN中为什么选择tanh,而不是relu,参考。
网友评论