这篇文章介绍激活函数,之所以将激活函数单独拿出来进行介绍,因为多层感知机在刚开始发展的时候,梯度会消失,所以它梯度不会太深,训练不了太深的参数,其实最核心的问题就是激活函数,结合反向求导那篇文章求导的过程,我们提出两个问题,带着这两个问题往下看。
有的激活函数为什么导致那个参数无法收敛?
梯度为什么会消失?
激活函数特征
从激活函数特征我们可以知道,激活函数一定要是非线性的,如果是线性的,就相当于一层非常厚的线性模型,就是因为非线性,才能让神经网络得到更复杂的模型。如果激活函数不可微就没法求它的导数。单调的时候才能保证这个函数式凸函数,凸函数只有一个最优解。
前面是激活函数必须要有的特性,现在看看不同的激活函数都有什么特性呢?
如果输出结果是有限的,梯度优化更加稳定,不会出现极端的情况。当输出结果是无限的模型会更加高效,随之带来的结果是不稳定的,一般需要把学习速率设置更小一点。学习速率太大了容易激进,太小了得不到收敛。
01
Sigmoid 激活函数
下图蓝色曲线就是激活函数的曲线,黄色的是激活函数导数曲线,导数的值域在0-0.25之间,就验证之前说过的,输出是有限的收敛能稳定。所以要初始化要小心。不管输入范围多少,输出范围一直是0-1之间。
02
Sigmoid 激活函数
下图黄色是激活函数,蓝色是函数本身,都是受限制的,只不过范围不一样。
前面介绍的两个存在梯度消失,下面介绍的这个不会,但是神经元容易死掉。
03
Relu 激活函数
如果小于0,不被激活,大于0的话,激活结果是输入和输出是一样的。这个 正好类似f(x)约等于x,输出不受限制。
反向传播算法-核心思想
为什么激活函数决定了梯度会不会消失?决定了神经元会不会死掉?
请看下图中公式:前部分算的是误差值(这里由两部分组成,其中一个激活函数的导数),后部分算的是下层节点具体的值,前面的误差乘一个小于1的数,算出来的值只能越来越小,也就是从上层往下层传递的时候,乘了好几次小于1的值,误差会越来越小,只要层数越深,最后导致求下层边的权重的时候这个权重几乎等于0了,最后导数消失,就是梯度消失。
梯度消失导致的结果是什么?
看上图中更新参数,旧的参数是黄色的,减去导数值乘上学习速率,如果导数值小,相当于每次没有减,这就导致梯度消失导致权重无法更新问题,权重没有办法更新,这个模型就学不下去,所以说以前多层感知机三层就很多了,再多的话下面就学不好,学不好就导致整个模型非常差。
下面这个是sig()激活函数:
下面是Relu激活函数:
Relu激活函数导数等于1,hi也可以大于1,所以就解决了梯度消失问题,虽然解决了梯度消失问题,Relu激活函数不设上限,神经元容易死掉。
为什么神经元容易死掉?
hi这个值,假设前馈的时候hi非常大,通过激活函数之后也是很大,那导数也就非常大,如果用非常大的导数更新的时候,会导致 变成负数,那下次,新的参数值来了,负数给了这个激活函数,激活函数不会被激活,前馈计算的时候这个节点也是0,反向传播的时候没有被激活的节点的导数是0,也就是说这个节点死掉,以后也不会参与之后的过程。
小结
现在也有好多变种,既可以不让梯度消失,也不会把神经元变得脆弱。