本文的内容主要转载自微信公众号“深度学习大讲堂”中的《深度学习中的激活函数导引》一文,可在公众号中阅读全文。
激活函数的定义与作用
在人工神经网络中,神经元节点的激活函数定义了对神经元输出的映射,简单来说,神经元的输出(例如,全连接网络中就是输入向量与权重向量的内积再加上偏置项)经过激活函数处理后再作为输出。激活函数可以定义为一种映射 $h:R\to R$,且几乎处处可导。
神经网络中激活函数的主要作用是提供网络的非线性建模能力,如不特别说明,激活函数一般而言是非线性函数。假设一个示例神经网络中仅包含线性卷积和全连接运算,那么该网络仅能够表达线性映射,即便增加网络的深度也依旧还是线性映射,难以有效建模实际环境中非线性分布的数据。加入(非线性)激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。因此,激活函数是深度神经网络中不可或缺的部分。
几种常用的激活函数
以下摘抄一些常用的激活函数。
Sigmoid是使用范围最广的一类激活函数,具有指数函数形状。Sigmoid函数具有软饱和性,使得深度神经网络在二三十年里一直难以有效的训练,是阻碍神经网络发展的重要原因。具体来说,由于在后向传递过程中,sigmoid向下传导的梯度包含了一个$f’(x)$因子(sigmoid关于输入的导数),因此一旦输入落入饱和区,$f’(x)$就会趋近于0,导致向底层传递的梯度也变得非常小。此时,网络参数很难得到有效训练。这种现象被称为梯度消失。一般来说,使用sigmoid作为激活函数的网络在5层之内就会产生梯度消失现象。梯度消失问题至今仍然存在,但被新的优化方法有效缓解了,例如DBN中的分层预训练,Batch Normalization的逐层归一化等。
Sigmoid的饱和性虽然会导致梯度消失,但也有其有利的一面。例如它在物理意义上最为接近生物神经元;$(0, 1)$的输出还可以被理解为概率,或用于输入的归一化,例如Sigmoid交叉熵损失函数。
tanh也具有软饱和性。但是使用tanh作为激活函数的网络收敛速度要比sigmoid快。因为tanh的输出均值比sigmoid更接近0,SGD会更接近 natural gradient,从而降低所需的迭代次数。
ReLU与传统的sigmoid激活函数相比,ReLU能够有效缓解梯度消失问题,从而直接以监督的方式训练深度神经网络,无需依赖无监督的逐层预训练,这也是2012年深度卷积神经网络在ILSVRC竞赛中取得里程碑式突破的重要原因之一。
ReLU在x<0时硬饱和。由于x>0时导数为1,所以,ReLU能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。但随着训练的推进,部分输入会落入硬饱和区,导致对应权重无法更新。这种现象被称为“神经元死亡”。ReLU还经常被“诟病”的一个问题是输出具有偏移现象,即输出均值恒大于零。偏移现象和神经元死亡会共同影响网络的收敛性。
PReLU是ReLU的改进版本,具有非饱和性。与LReLU相比,PReLU中的负半轴斜率a可学习而非固定。虽然PReLU引入了额外的参数,但基本不需要担心过拟合。与ReLU相比,PReLU收敛速度更快。因为PReLU的输出更接近0均值,使得SGD更接近natural gradient。
原文中有一个论述很有意思。ResNet采用ReLU而非PReLU的原因可能在于:首先,对PReLU采用正则将激活值推向0也能够带来性能提升。这或许表明,小尺度或稀疏激活值对深度网络的影响更大;其次,ResNet中包含单位变换和残差两个分支。残差分支用于学习对单位变换的扰动。如果单位变换是最优解,那么残差分支的扰动应该越小越好。这种假设下,小尺度或稀疏激活值对深度网络的影响更大。此时,ReLU或许是比PReLU更好的选择。
其他激活函数还包括RReLU、Maxout、ELU、Noisy Activation Functions、CReLU、MPELU等,但个人感觉并没有以上几种常用,而且相对来说ReLU和PReLU的应用更广泛。