回忆一下(一)里的通用近似定理,非线性激活函数可以使神经网络逼近任意的函数。激活函数的作用就是决定对于一个输入,该给出怎样对应的输出,相当于在神经元里接收到了多大的刺激才会使神经元传递信息。
1.Sigmoid
从生物学模型上来看, sigmoid很符合神经元的功能,但又是可以微分的。sigmoid的输入可以是任意的实数,输出在0到1之间。
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(X):
return 1/(1+np.exp(-X))
x = np.linspace(-6, 6)
plt.plot(x,sigmoid(x))
plt.xlabel('x')
plt.ylabel('y')
plt.title('Sigmoid')
plt.grid()
plt.show()

可以看到在sigmoid的两边,当x趋于无限大或者无限小时, y是趋于1或者0的,也就是说当x特别大或者特别小时,x的变换不会在y上显示出来,这就可能导致梯度消失的问题。而且sigmoid的输出总是大于零的,不是以0为中心的(zero-centered),假设输入是一个均值为0的分布,在训练过程中sigmoid会使得数据整体的均值大于0,在层层传递之后,原来的分布可能都要飘到天上去了。
2. Tanh
def tahn(X):
return np.tanh(X)

从图上就能看出了, tanh解决了sigmoid没有以0为中心的问题,输出的分布在-1到1之间。但是tanh可以看作是sigmoid的变形版,所以tahn的两端依旧存在饱和的问题,以及会导致梯度消失的问题。
(梯度消失:在x上的巨大变化在y上只有很小的变化,y的梯度“消失”了。)
3. ReLU
ReLU(Rectified Linear Units)是一个分成两段的函数,x大于0时为线性,小于0时就是0.
def relu(X):
return np.maximum(0,X)

ReLU的优点有加快学习速度,避免了梯度消失的问题。但是同样的也不是以零为中心的分布。
当x为负的时候,输出y和f'(x)都成了0,梯度不会再更新,这是ReLU就相当于死了(dying ReLU)。这种情况通常于过大的学习率有关。
为了解决这个问题,一个ReLU的改进版是Leaky ReLU/Parametric ReLU。
当 = 0.01,叫Leaky ReLU, 其他的
值叫Parametric ReLU。
def lrelu(X, alpha = 0.01):
return np.where(X < 0, alpha*X, X)
def erelu(X, alpha = 0.01):
return np.where(X < 0, alpha*(np.exp(X)-1), X)

4. 总结
一个好的激活函数需要有:
- 几乎是线性的部分,用来防止梯度消失的问题
- 饱和的区域,提供非线性,保证多层网络不会退化成单层线性网络
- 单调性,近似定理的条件
这里可以参考:https://blog.csdn.net/zhanghao3389/article/details/85267461
网友评论