这部分主要讨论我们之前提到的几种激活函数的利弊:




首先我们看sigmoid函数,这种激活函数有着激活函数中常见的优点与缺点:




优点方面,它可以使数据分布在0-1之间,可以很好地表示神经元的饱和放电现象

缺点方面

我们考虑使用这个激活函数进行梯度的反向传播:




我们可以看到在x = 10或者x = -10时,传播的梯度都会接近于0,导致后面的所有梯度均变为0,这就会导致梯度消失,我们的神经网络无法学习

同时,sigmoid激活函数的输出并不是以0为中心:




我们知道w梯度的反向传播的值于x相关,所以当x一直为正时,w梯度将取决于w的正负,所以梯度很可能会在正负之间横跳,这样也不利于神经网络的学习,但是在小数据集上还是可以使用,并且小哥指出这一点其实不是特别关键

最后,就是exp()这种非线性操作从底层来说很花费时间(相对于线性操作来说)

之后我们再来看看其它激活函数:

tanh它的优缺点与sigmoid函数大致相同:




然后是最常用的relu激活函数:




relu函数有很多优异的性质,比如不会导致饱和杀死梯度,计算开销低速度快,神经网络收敛的也快

但是还有一个人们一直担心的问题就是:




小于0的数据永远不会被激活无法学习

因此人们又想出来了很多relu的变体:

leaky relu在小于0的区域加入一个线性函数,更进一步地,可以把小于0区域函数的系数作为一个可学习的参数加入神经网络,通过反向传播来更新优化




elu 相对于leaky relu添加了鲁棒性,但是计算开销增大




selu 对深度神经网络的效果很好 甚至可以不用batch normalization就可以训练深层神经网络 而其中的参数是固定的,是通过91页的数学推导得出的结果(震惊小哥一万年)




最后再放上不同激活函数数据的统计以及小哥的建议: