相关申明及相关参考:
体系学习地址 主要学习笔记地址
激活函数,你真的懂了吗? - 知乎 (zhihu.com)
聊一聊深度学习的activation function - 知乎 (zhihu.com)
由于是文章阅读整合,依据个人情况标注排版,
不确定算不算转载,主要学习围绕AI浩的五万字总结,深度学习基础,不过其部分内容与百度等相同,不知如何判定,就此简单申明。
如有侵权,请联系删除。
目录
1 激活函数的概念
2 激活函数意义
3 激活函数是非线性函数原因
4 常见的激活函数及导数
A sigmoid 激活函数
B tanh激活函数——双曲正切函数
C Relu激活函数——优先选择
D Leaky Relu激活函数(PReLU)
E ELU激活函数
5 激活函数的性质
6 激活函数的选择
7 Softmax函数
A Softmax函数定义(以第 i 个节点输出为例)
B Softmax函数求导
8 交叉熵代价函数定义及其求导推导
激活函数(Activation functions)将非线性特性引入到网络中。如下图,在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数。引入激活函数是为了增加神经网络模型的非线性。
- 激活函数对模型学习、理解非常复杂和非线性的函数具有重要作用。
- 激活函数可以引入非线性因素。如果不使用激活函数,则输出信号仅是一个简单的线性函数。线性函数一个一级多项式,线性方程的复杂度有限,从数据中学习复杂函数映射的能力很小。没有激活函数,神经网络将无法学习和模拟其他复杂类型的数据,例如图像、视频、音频、语音等。
- 激活函数可以把当前特征空间通过一定的线性映射转换到另一个空间,让数据能够更好的被分类。
激活函数向神经网络中引入非线性因素的,通过激活函数,神经网络就可以拟合各种曲线。
举例:
典型二分类问题:将随意放置的圆形和三角形分开。
不管是单层感知机还是多层感知机,其实质都是一条直线,无法将两种图形分开。
事实证明无法用一条直线将两种图形完全分开,因为该问题是线性不可分的。
而利用激活函数:在每一层叠加完之后,为输入与输出之间加上一个激活函数(引入非线性因素),则函数表达就极为丰富了,可以表达任意曲线。
- 假若网络中全部是线性部件,那么线性的组合还是线性,与单独一个线性分类器无异。这样就做不到用非线性来逼近任意函数。
- 使用非线性激活函数 ,以便使网络更加强大,增加它的能力,使它可以学习复杂的事物,复杂的表单数据,以及表示输入输出之间非线性的复杂的任意函数映射。使用非线性激活函数,能够从输入输出之间生成非线性映射。
【特点】能够把输入的连续实值变换为0和1之间的输出,特别的:如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1。
【缺点】sigmoid极容易导致梯度消失问题||计算费时||函数不关于原点中心对称。
tanh读作Hyperbolic Tangent,它解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。
【优点】解决了Sigmoid的输出不关于零点对称的问题||具有Sigmoid的优点平滑,容易求导
【缺点】激活函数运算量大(幂运算问题)||Tanh的导数图像虽然最大值变大,使得梯度消失的问题得到一定的缓解,但是不能根本解决这个问题。
【Tanh收敛速度比Sigmoid快】
根据两个函数的求导,tanh(x)梯度消失问题比sigmoid轻,所以Tanh收敛速度比Sigmoid快。
讨论激活函数收敛速度或与梯度消失或者爆炸相关时,应同时考虑当前权重W数值的影响。
保留了 step 函数的生物学启发(只有输入超出阈值时神经元才激活)
当输入为正时,导数不为零,允许基于梯度的学习(尽管在 x=0 的时候,导数未定义)。
使用这个函数能使计算变得很快,因为无论是函数还是其导数都不包含复杂的数学运算。
当输入为负时,ReLU 的学习速度可能会变得很慢,甚至使神经元直接无效,因为此时输入小于零而梯度为零,从而其权重无法得到更新,在剩下的训练过程中会一直保持静默。
【理解Relu < 0 时 ,是非线性激活函数】
根据图像可看出具有如下特点:
- 单侧抑制:ReLU 函数从图像上看,是一个分段线性函数,把所有的负值都变为 0,而正值不变,这样就成为单侧抑制。
- 相对宽阔的兴奋边界。
- 稀疏激活性:因为单侧抑制,使得神经网络中的神经元具有稀疏激活性。
稀疏激活性:从信号方面来看,即神经元同时只对输入信号的少部分选择性响应,大量信号被刻意的屏蔽了,这样可以提高学习的精度,更好更快地提取稀疏特征。
当x < 0时,ReLU 硬饱和,而当x > 0 时,则不存在饱和问题。
ReLU 能够在x > 0时保持梯度不衰减,从而缓解梯度消失问题。
【优点】
- 相比起Sigmoid和tanh,ReLU在SGD中能够快速收敛,这是因为它线性(linear)、非饱和(non-saturating)的形式。
- Sigmoid和tanh涉及了很多很expensive的操作(比如指数),ReLU可以更简单的实现。
- 有效缓解了梯度消失的问题。
- 在没有无监督预训练的时候也能有较好的表现。
【优点扩展】
- 在区间变动很大的情况下,ReLu 激活函数的导数或者激活函数的斜率都会远大于 0,在程序实现就是一个 if-else 语句,而 sigmoid 函数需要进行浮点四则运算,在实践中,使用 ReLu 激活函数神经网络通常会比使用 sigmoid 或者 tanh 激活函数学习的更快。
- sigmoid 和 tanh 函数的导数在正负饱和区的梯度都会接近于 0,这会造成梯度弥散,而 Relu 和Leaky ReLu 函数大于 0 部分都为常数,不会产生梯度弥散现象。
- 需注意,Relu 进入负半区的时候,梯度为 0,神经元此时不会训练,产生所谓的稀疏性,而 Leaky ReLu 不会产生这个问题。
【缺点】
- ReLU的输出不是zero-centered。
- Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生:
- 非常不幸的参数初始化,这种情况比较少见
- learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。
【特点】与 ReLu 相比 ,leak 给所有负值赋予一个非零斜率, leak是一个很小的常数
,这样保留了一些负轴的值,使得负轴的信息不会全部丢失。
理论上来讲,Leaky ReLU有ReLU的所有优点,外加不会有Dead ReLU问题,但是在实际操作当中,并没有完全证明Leaky ReLU总是好于ReLU。
与Leaky ReLU相似的还有PReLU和RReLU
PReLU中的
是根据数据变化的;
Leaky ReLU中的
是固定的;
RReLU中的
是一个在给定的范围内随机抽取的值,这个值在测试环节就会固定下来。
【意义】ELU也是为解决ReLU存在的问题而提出,ELU有ReLU的基本所有优点,以及:
- 不会有Dead ReLU问题
- 输出的均值接近0,zero-centered
【问题】在于计算量稍大。类似于Leaky ReLU,理论上虽然好于ReLU,但在实际使用中目前并没有好的证据ELU总是优于ReLU。
【特点】
- 融合了sigmoid和ReLU,左侧具有软饱和性,右侧无饱和性。
- 右侧线性部分使得ELU能够缓解梯度消失,而左侧软饱能够让ELU对输入变化或噪声更鲁棒。
- ELU的输出均值接近于零,所以收敛速度更快。
- 在ImageNet上,不加 Batch Normalization 30 层以上的 ReLU 网络会无法收敛,PReLU网络在MSRA的Fan-in (caffe )初始化下会发散,而 ELU 网络在Fan-in/Fan-out下都能收敛。
除了以上介绍的几个激活函数外, 还有一些比较小众的激活函数 Mish激活函数、 Swish激活函数、SiLU激活函数。
- 非线性:当激活函数是非线性的,一个两层的神经网络就可以基本上逼近所有的函数。但如果激活函数是恒等激活函数的时候,即
,就不满足这个性质,而且如果 MLP 使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。
- 可微性: 当优化方法是基于梯度的时候,就体现了该性质;
- 单调性: 当激活函数是单调的时候,单层网络能够保证是凸函数;
: 当激活函数满足这个性质的时候,如果参数的初始化是随机的较小值,那神经网络的训练将会很高效;如果不满足这个性质,那么就需要详细地去设置初始值;
- 输出值的范围:当激活函数输出值是有限的时候,基于梯度的优化方法会更加稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出值是无限的时候,模型的训练会更加高效,不过在这种情况下,一般需要更小的 Learning Rate。
选择一个适合的激活函数并不容易,需要考虑很多因素,通常的做法是,如果不确定哪一个激活函数效果更好,可以把它们都试试,然后在验证集或者测试集上进行评价。然后看哪一种表现的更好,就去使用它。
1 常见的选择情况:
- 如果输出是 0、1 值(二分类问题),则输出层选择 sigmoid 函数,然后其它的所有单元都选择 Relu 函数。
- 如果在隐藏层上不确定使用哪个激活函数,那么通常会使用 Relu 激活函数。有时,也会使用 tanh 激活函数,但 Relu 的一个优点是:当是负值的时候,导数等于 0。
- sigmoid 激活函数:除了输出层是一个二分类问题基本不会用它。
- tanh 激活函数:tanh 是非常优秀的,几乎适合所有场合。
- ReLu 激活函数:最常用的默认函数,如果不确定用哪个激活函数,就使用 ReLu 或者 Leaky ReLu,再去尝试其他的激活函数。
- 如果遇到了一些死的神经元,可以使用 Leaky ReLU 函数。
2 线性激活函数的使用条件:
- 输出层,大多使用线性激活函数。
- 在隐含层可能会使用一些线性激活函数。
- 一般用到的线性激活函数很少。
Softmax从字面上来说,可以分成soft和max两个部分。max故名思议就是最大值的意思。Softmax的核心在于soft,而soft有软的含义,与之相对的是hard硬。很多场景中需要找出数组所有元素中值最大的元素,实质上都是求的hardmax。但hardmax最大的特点就是只选出其中一个最大的值,即非黑即白,但是往往在实际中这种方式是不合情理的。(比如对于文本分类来说,一篇文章或多或少包含着各种主题信息,更期望得到文章对于每个可能的文本类别的概率值(置信度),可以简单理解成属于对应类别的可信度)。所以,此时用到了soft的概念,Softmax的含义就在于不再唯一的确定某一个最大值,而是为每个输出分类的结果都赋予一个概率值,表示属于每个类别的可能性。
其中 为第i个节点的输出值,C为输出节点的个数,即分类的类别个数。通过Softmax函数就可以将多分类的输出值转换为范围在[0, 1]和为1的概率分布。
引入指数函数对于Softmax函数是把双刃剑,即得到了优点也暴露出了缺点:
【优点】
指数函数曲线呈现递增趋势,最重要的是斜率逐渐增大,也就是说在x轴上一个很小的变化,可以导致y轴上很大的变化。这种函数曲线能够将输出的数值拉开距离。
【缺点】
指数函数的曲线斜率逐渐增大虽然能够将输出值拉开距离,但是也带来了缺点,当
值非常大的话,计算得到的数值也会变的非常大,数值可能会溢出。
【注意】
当使用Softmax函数作为输出节点的激活函数的时候,一般使用交叉熵作为损失函数。由于Softmax函数的数值计算过程中,很容易因为输出节点的输出值比较大而发生数值溢出的现象,在计算交叉熵的时候也可能会出现数值溢出的问题。为了数值计算的稳定性,TensorFlow提供了一个统一的接口,将Softmax与交叉熵损失函数同时实现,同时也处理了数值不稳定的异常,使用TensorFlow深度学习框架的时候,一般推荐使用这个统一的接口,避免分开使用Softmax函数与交叉熵损失函数。
单个输出节点的二分类问题一般在输出节点上使用Sigmoid函数,拥有两个及其以上的输出节点的二分类或者多分类问题一般在输出节点上使用Softmax函数。其他层建议使用的激活函数参考。
现在可以构建比较复杂的神经网络模型,最重要的原因之一得益于反向传播算法。反向传播算法从输出端也就是损失函数开始向输入端基于链式法则计算梯度,然后通过计算得到的梯度,应用梯度下降算法迭代更新待优化参数。
由于反向传播计算梯度基于链式法则,因此下面为了更加清晰,首先推导一下Softmax函数的导数。作为最后一层的激活函数,求导本身并不复杂,但是需要注意需要分成两种情况来考虑。
【案例】
softmax 将原来输出是3 , 1 , − 3 ,通过 softmax 函数作用,就映射成为( 0 , 1 ) 的值,而这些值的累和为1(满足概率的性质),可以将它理解成概率,在最后选取输出结点的时候,选取概率最大(也就是值对应最大的)结点,作为我们的预测目标!
神经元的输出就是 a = σ(z),其中输⼊的带权和: 。
其中 n 是训练数据的总数,求和是在所有的训练输⼊ x 上进⾏的, y 是对应的⽬标输出。
表达式是否解决学习缓慢的问题并不明显。实际上,甚⾄将这个定义看做是代价函数也不是显⽽易⻅的!在解决学习缓慢前,先理解交叉熵为何能够解释成⼀个代价函数。
将交叉熵看做是代价函数有两点原因。
- 它是⾮负的, C > 0。可以看出:式子中的求和中的所有独⽴的项都是负数的,因为对数函数的定义域是 (0,1),并且求和前⾯有⼀个负号,所以结果是非负。
- 如果对于所有的训练输⼊ x,神经元实际的输出接近⽬标值,那么交叉熵将接近 0。
假设在这个例⼦中, y = 0 而 a ≈ 0 这是我们想到得到的结果。公式中第⼀个项就消去了,因为 y = 0,而第⼆项实际上就是 − ln(1 − a) ≈ 0。反之, y = 1 而 a ≈ 1。所以在实际输出和⽬标输出之间的差距越⼩,最终的交叉熵的值就越低了。(这里假设输出结果不是0,就是1,实际分类也是这样的)
综上所述,交叉熵是⾮负的,在神经元达到很好的正确率的时候会接近 0。这些其实就是想要的代价函数的特性。其实这些特性也是⼆次代价函数具备的。所以,交叉熵就是很好的选择了,但是交叉熵代价函数有⼀个比二次代价函数更好的特性就是它避免了学习速度下降的问题。为了弄清楚这个情况,计算交叉熵函数关于权重的偏导数。将 a = σ(z)代⼊到 公式中应⽤两次链式法则,得到:
这是⼀个优美的公式。它告诉我们权重学习的速度受到 σ(z)-y,也就是输出中的误差的控制。更⼤的误差,更快的学习速度,这是我们直觉上期待的结果。特别地,这个代价函数还避免了像在⼆次代价函数中类似⽅程中σ'(z)导致的学习缓慢。当使⽤交叉熵的时候, σ'(z)被约掉了,所以不再需要关心它是不是变得很小,这种约除就是交叉熵带来的特效。实际上,这也并不是⾮常奇迹的事情。我们在后⾯可以看到,交叉熵其实只是满⾜这种特性的⼀种选择罢了。
参考学习:交叉熵代价函数定义及其求导推导 - 简书 (jianshu.com)