本文的内容主要参考guoyuhaoaaa的博客,链接:https://blog.csdn.net/guoyuhaoaaa/article/details/53006516
对于训练神经网络来说,为了增强网络表征数据的能力,一般需要引入非线性激活函数,一般有sigmoid tanh relu,今天我们就来分布说明一些这些激活函数的特点。
总而言之层数越深relu的优势越明显。(故一般而言sigmoid和tanh多用在bp神经网络中,在深度学习的网络框架中多用relu激活函数)
那么为什么在深度学习框架中引入Relu激活函数呢?
当前,深度学习一个明确的目标是从数据变量中解离出关键因子。原始数据(以自然数据为主)中通常缠绕着高度密集的特征。原因是这些特征向量是相互关联的,一个小小的关键因子可能牵扰着一堆特征,有点像蝴蝶效应,牵一发而动全身。基于数学原理的传统机器学习手段在解离这些关联特征方面具有致命弱点。然而,如果能够解开特征间缠绕的复杂关系,转换为稀疏特征,那么特征就有了鲁棒性(去掉了无关的噪声)。
几十年的机器学习发展中,我们形成了这样一个概念:非线性激活函数要比线性激活函数更加先进。尤其是在布满Sigmoid函数的BP神经网络,布满径向基函数的SVM神经网络中,往往有这样的幻觉,非线性函数对非线性网络贡献巨大。该幻觉在SVM中更加严重。核函数的形式并非完全是SVM能够处理非线性数据的主力功臣(支持向量充当着隐层角色)。那么在深度网络中,对非线性的依赖程度就可以缩一缩。另外,在上一部分提到,稀疏特征并不需要网络具有很强的处理线性不可分机制。综合以上两点,在深度学习模型中,使用简单、速度快的线性激活函数可能更为合适。
更倾向于使用线性神经激活函数的另外一个原因是,减轻梯度法训练深度网络时的Vanishing Gradient Problem。看过BP推导的人都知道,误差从输出层反向传播算梯度时,在各层都要乘当前层的输入神经元值,激活函数的一阶导数。即Grad=Error⋅Sigmoid′(x)⋅xGrad=Error⋅Sigmoid′(x)⋅x。使用双端饱和(即值域被限制)Sigmoid系函数会有两个问题:
①Sigmoid’(x)∈(0,1) 导数缩放
②x∈(0,1)或x∈(-1,1) 饱和值缩放
这样,经过每一层时,Error都是成倍的衰减,一旦进行递推式的多层的反向传播,梯度就会不停的衰减,消失,使得网络学习变慢。而校正激活函数的梯度是1,且只有一端饱和,梯度很好的在反向传播中流动,训练速度得到了很大的提高。
然而我们不能过分强调稀疏性带来的优势,如果模型的稀疏性过高那么自然而然的模型的容量就会降低很多,如果降到了一定的程度将不能够进行有效的学习。
tanh和sigmoid函数对比
使用这两个函数的神经网络都会存在梯度消失的问题,因为在无穷大和无穷小的时候梯度几乎不变。
同时相对于tanh激活函数来讲sigmoid的输出都是正数,因为如果输入神经元的数据总是正数,梯度在反向传播的过程中,将会要么全部是正数,要么全部是负数,这样就会导致梯度更新的方向受到限制(拿到二维平面上来讲,只有第一和第三象限的方向,第二和第四象限的方向就受到限制了),不但会使梯度更新速度降低,同时很可能难以达到最优值(相对于tanh)。故tanh的性能要比sigmoid要好。