神经网络的激活函数及梯度消失

神经科学 2018-02-05

ICML 2016 的文章[Noisy Activation Functions]中给出了激活函数的定义:激活函数是映射 h:R→R,且几乎处处可导。

神经网络中激活函数的主要作用是提供网络的非线性建模能力,如不特别说明,激活函数一般而言是非线性函数。假设一个示例神经网络中仅包含线性卷积和全连接运算,那么该网络仅能够表达线性映射,即便增加网络的深度也依旧还是线性映射,难以有效建模实际环境中非线性分布的数据。加入(非线性)激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。

1、Sigmoid函数

Sigmoid 是使用范围最广的一类激活函数,具有指数函数形状 。正式定义为:

神经网络的激活函数及梯度消失
x=-10:0.001:10; 
%sigmoid和它的导数
sigmoid=1./(1+exp(-x));
sigmoidDer=exp(-x)./((1+exp(-x)).^2);
figure;
plot(x,sigmoid,‘r‘,x,sigmoidDer,‘b--‘);
axis([-10 10 -1 1]);
grid on;
title(‘Sigmoid函数(实线)及其导数(虚线)‘);
legend(‘Sigmoid原函数‘,‘Sigmid导数‘);
set(gcf,‘NumberTitle‘,‘off‘);
set(gcf,‘Name‘,‘Sigmoid函数(实线)及其导数(虚线)‘);

输出:

可见,sigmoid 在定义域内处处可导,且两侧导数逐渐趋近于0,即:

Bengio 教授等将具有这类性质的激活函数定义为软饱和激活函数。与极限的定义类似,饱和也分为左侧软饱和与右侧软饱和:

左侧软饱和:

右侧软饱和:

神经网络的激活函数及梯度消失

与软饱和相对的是硬饱和激活函数,即:f‘(x)=0,当 |x| > c,其中 c 为常数。

同理,硬饱和也分为左侧硬饱和和右侧硬饱和。常见的ReLU 就是一类左侧硬饱和激活函数。

Sigmoid 的软饱和性,使得深度神经网络在二三十年里一直难以有效的训练,是阻碍神经网络发展的重要原因。具体来说,由于在后向传递过程中,sigmoid向下传导的梯度包含了一个f‘(x) 因子(sigmoid关于输入的导数),因此一旦输入落入饱和区,f‘(x) 就会变得接近于0,导致了向底层传递的梯度也变得非常小。此时,网络参数很难得到有效训练。这种现象被称为梯度消失。一般来说, sigmoid 网络在 5 层之内就会产生梯度消失现象[Understanding the difficulty of training deep feedforward neural networks]。梯度消失问题至今仍然存在,但被新的优化方法有效缓解了,例如DBN中的分层预训练,Batch Normalization的逐层归一化,Xavier和MSRA权重初始化等代表性技术。

Sigmoid 的饱和性虽然会导致梯度消失,但也有其有利的一面。例如它在物理意义上最为接近生物神经元。(0, 1) 的输出还可以被表示作概率,或用于输入的归一化,代表性的如Sigmoid交叉熵损失函数

2、tanh函数

x=-10:0.001:10;
tanh=(exp(x)-exp(-x))./(exp(x)+exp(-x));
tanhDer=1-tanh.^2;
figure;
plot(x,tanh,‘r‘,x,tanhDer,‘b--‘);
grid on;
title(‘tanh函数(实线)及其导数(虚线)‘);
legend(‘tanh原函数‘,‘tanh导数‘);
set(gcf,‘NumberTitle‘,‘off‘);
set(gcf,‘Name‘,‘tanh函数(实线)及其导数(虚线)‘);

输出:

神经网络的激活函数及梯度消失

tanh也具有软饱和性。[Backpropagation applied to handwritten zip code recognition]中提到tanh网络的收敛速度要比sigmoid快。因为tanh的输出均值比sigmoid更接近0,SGD会更接近 natural gradient[Natural gradient works efficiently in learning](一种二次优化技术),从而降低所需的迭代次数。

3、Softsign函数

x=-10:0.001:10;
softsign=x./(1+abs(x));
%分段函数的表示方法如下
%y=sqrt(x).*(x>=0&x<4)+2*(x>=4&x<6)+(5-x/2).*(x>=6&x<8)+1*(x>=8);
softsignDer=(1./(1+x).^2).*(x>=0)+(1./(1-x).^2).*(x<0);
plot(x,softsign,‘r‘,x,softsignDer,‘b--‘);
axis([-10 10 -1 1]);%加在第一个plot后面
grid on;
title(‘softsign函数 x/(1+|x|)(实线)及其导数(虚线)‘);
legend(‘softsign原函数‘,‘softsign导数‘);
set(gcf,‘NumberTitle‘,‘off‘);
set(gcf,‘Name‘,‘softsign函数 x/(1+|x|)(实线)及其导数(虚线)‘);

输出:

神经网络的激活函数及梯度消失

4、RELU

定义为:

神经网络的激活函数及梯度消失
x=-10:0.001:10;
relu=max(0,x);
%分段函数的表示方法如下
%y=sqrt(x).*(x>=0&x<4)+2*(x>=4&x<6)+(5-x/2).*(x>=6&x<8)+1*(x>=8);
reluDer=0.*(x<0)+1.*(x>=0);
figure;
plot(x,relu,‘r‘,x,reluDer,‘b--‘);
title(‘Relu函数max(0,x)(实线)及其导数0,1(虚线)‘);
legend(‘Relu原函数‘,‘Relu导数‘);
set(gcf,‘NumberTitle‘,‘off‘);
set(gcf,‘Name‘,‘Relu函数(实线)及其导数(虚线)‘);

输出:

神经网络的激活函数及梯度消失

可见,ReLU 在x<0 时硬饱和。由于 x>0时导数为 1,所以,ReLU 能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。但随着训练的推进,部分输入会落入硬饱和区,导致对应权重无法更新。这种现象被称为“神经元死亡”。

ReLU还经常被“诟病”的一个问题是输出具有偏移现象[7],即输出均值恒大于零。偏移现象和 神经元死亡会共同影响网络的收敛性。

还有其他一些激活函数,如下表:

神经网络的激活函数及梯度消失

http://blog.csdn.net/cyh_24/article/details/50593400

http://blog.51cto.com/qing0991/1833398

相关推荐