关于为什么引入非线性activation function?
- 如果不用激励函数,在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是Perceptron了,浪费了资源,且没有达到预期的效果。正因为这个原因,我们决定引入非线性函数作为activation function,这样深层神经网络就有意义了,输出不再是输入的线性组合,最早的选择是sigmoid函数(输出区间[0,1])或者Tanh函数(输出区间[-1,1])。
为什么引入ReLU?
使用sigmoid和Tanh作为activation function时,在计算上计算量比较大,而ReLU计算量能得到一定程度的降低。
Sigmoid和Tanh函数在接近饱和区时,变换太缓慢,gradient趋近于0,进而发生了vanishing gradient的情况,减缓收敛速度,在网络层数较多的时候比较明显,是加深网络结构的主要障碍之一。ReLU的gradient大多数情况下是常数,有助于解决深层网络的收敛问题。Relu的另一个优势是在生物上的合理性,它是单边的,相比Sigmoid和Tanh,更符合生物神经元的特征。我们可以用python的pyplot把这两个函数画出来。
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-6,6,5120,endpoint=True)
y=np.tanh(x)
y1=1/(1+np.exp(-x))
p1=plt.plot(x,y,label='Tanh',color='green')
p2=plt.plot(x,y1,label='Sogmoid',color='orange')
plt.legend(loc=3)
z1=np.zeros(shape=100)
z2=np.linspace(0,6,512,endpoint=True)
s1=np.linspace(-6,0,100)
s2=z2
z=np.concatenate((z1,z2))
s=np.concatenate((s1,s2))
p3=plt.plot(s,z,label='ReLU')
plt.legend(loc=3)
3. Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
4. leaky ReLU函数
- 有人说经过测试leaky ReLU的效果更好,但是当小于0部分的gradient接近于0时,和ReLU的效果相差无几。再此不多说明了。
二次修改:
1. 关于为什么要引入非线性函数:(用visio做了一张图)
- 从图中我们可以很清楚的看到,这个两层的神经网络共计有两个输入
X1,X2,经过一系列的矩阵变化,最终得到了输出Y(暂且认为X都是矩阵,1x1),其实不难看出,其实两次的矩阵变化(矩阵乘法)可以合并成一次的变化,所以线性变化便成了神经网络加深的一大重要阻碍。