周末AI课堂 常见隐藏单元 机器学习你会遇到的“坑”

AI课堂开讲,就差你了!

很多人说,看了再多的文章,可是没有人手把手地教授,还是很难真正地入门AI。为了将AI知识体系以最简单的方式呈现给你,从这个星期开始,芯君邀请AI专业人士开设“周末学习课堂”——每周就AI学习中的一个重点问题进行深度分析,课程会分为理论篇和代码篇,理论与实操,一个都不能少!

来,退出让你废寝忘食的游戏页面,取消只有胡吃海塞的周末聚会吧。未来你与同龄人的差异,也许就从每周末的这堂AI课开启了!

全文共2779字,预计学习时长6分钟

在开始介绍各类隐藏单元的时候,我们有必要强调sigmoid隐藏单元更多意义在于其生物角度上,因为它将大范围的输入挤压到[0,1]区间,对应着生物学神经元抑制和激活两种状态,但却在神经网络的优化过程中非常容易出现迭代缓慢和梯度消失的问题。随着对现代神经网络的实践,激活函数最重要的作用并非为了与生物学上状态严格对应,而是通过层层相互作用近似出一个非线性函数。根据隐藏单元设计的几个原则,我们可以很快的排除两个简单的隐藏单元:

阶跃函数:

如图所示,阶跃函数在变量两端的导数均为零,在反向传播时

,梯度流将会恒为零,左导数和右导数均为无穷大,不可计算。

如图所示,阶跃函数在变量两端的导数均为零,在反向传播时

如图所示,线性函数在优化上没有什么困难,而且梯度流在逆向传播时会很稳定,但不符合万能近似定理,无法近似非线性函数。

对隐藏单元的理解有两条思路,其一,根据一些基本原则去自行设计,其二,基于阶跃函数和线性函数分别作出改进,我们根据第二条思路来逐渐介绍隐藏单元。

对阶跃函数的逐步改进

首先针对阶跃函数的缺点,选取喜闻乐见的sigmoid函数:

但是sigmoid非零中心化会带来更新缓慢,根据《隐藏单元的设计原则》中所介绍的,因为它的导数和函数值对于所有权重的更新永远沿着一个方向,一个自然的思路就是,将其中之一的输出区间扩展到以零为中心,基于这样的思路,我们可以选取tanh函数:

tanh函数是奇函数,而其导数均为正,使得连接到同一神经元的连接权重不再同时增大或者减小,而且在图中的[-2,2]区间,tanh函数的输出值与线性函数类似,满足近似线性化的原则。为了发挥线性的巨大优势,我们可以将中间区间的全部强制变成线性,这样就成为了hardtanh函数:

需要注意,这样的方法本质是将原来的平滑曲线,强行分段,也被叫做”硬饱和“,对噪声就比较敏感,因为我们假设对于输入加上一个极小的偏移,梯度仍然不变,但在训练过程中,我们希望在梯度流中,加了噪声和不加噪声具有不同的梯度。同时,tanh和hardtanh并没有缓解梯度消失问题,反而加剧了它,所以我们需要一个在输入值太小和太大的时候,梯度变化仍需要显著的函数,我们尝试使用反正切函数:

还可以使用softsign函数:

目前对于反正切函数和softsign函数都介绍很少,因为它们的梯度计算起来都是比较困难的。事实证明,在能够使用sigmoid函数作为激活函数的深层网络中,将其替换为tanh等类似零中心的激活函数可以改善学习效果。

对阶跃函数的函数改进中,一方面,仍然延续了"挤压"的基本性质,事实上,要达到非线性的目标,“挤压“并不是必要的,另一方面,在梯度计算简单、近似线性化和缓解梯度消失和爆炸,这三者中我们最多只能拥有其中的两个。所以,我们有必要思考另一条思路的改进。

对线性函数的逐步改进

对线性函数的改进首先要解决的问题是,如何将一个线性函数变为非线性的,同时又要继承近似线性化的优点。我们寻找近似线性的激活函数,比如Bent identity:

另一个简单的想法就是将其变为一个分段线性函数,比如ReLU(Rectified Linear Unit ):

为什么分段线性函数是非线性的呢?从数学上,我们可以说ReLU满足齐次性,但不满足可加性;直观来说,一个线性函数会将空间分割为平直的两部分,而非线性函数则不会,分段线性函数并不平滑,按照微积分的基本原理(黎曼可积),一个任意复杂的凸函数都可以通过线性函数的多次分段来逼近。

ReLU在很大的区间内近似线性,避免了梯度消失和梯度爆炸问题。所谓的“单侧抑制”还会带来一个巨大的好处,当神经元的输入小于零时,输出为零,神经元未被激活,只有当神经元被激活时才会有信息被传入下一级的神经元,当神经元关闭时,与之相连的权重边就不再重要,就减少了参数的数量,这种对网络的稀疏化减小了过拟合的可能,因为参数的数量与模型容量密切相关。

同时,也会带来风险,我们已经在上一节知道,反向传播更新参数时,可以看作梯度的流动。而ReLU输入小于零的时候,梯度也为零,当神经元一旦关闭,就很难再次激活,当我们神经元的参数初始化为零,或者更新幅度太大时就会发生某些关闭的神经元在整个训练中就不再激活,这就是所谓的神经元“死亡”。

为了解决风险,势必要破坏优势。我们可以尝试在输入小于零的时候,让其梯度不为零,比如Leaky ReLU:

其中,a是一个非常小的参数,就是希望能够避免神经元的死亡,又同时尽可能的保持原本ReLU的优点,当输入小于零时,神经元的激活也就很微弱,绝对值也不会特别大,这与我们的L2正则化有相似之处。同时我们可以注意到LeakyReLU仍然是硬饱和的。那么另一种ELU单元则改进了这一点:

注意到,我们使用ELU或者LeakyReLU时,引入了一个需要提前设定的参数,这个参数随着神经网络的结构和数据的不同,可能会存在差异,大多数情况下,我们会引入参数共享,即会对于所有的单元采取相同的,但将其确定好,仍然需要花费不少功夫。把如果这个参数可以内嵌到神经网络的学习过程中,使其变为一个可以被训练的参数,那么性能就会更加灵活,这就是所谓的PReLU(parametric ReLU),具体的形式与ELU和LeakyReLU相同,只是在训练过程中,我们需要多计算一个参数的梯度:

在PReLU中引入的可训练的参数是为了激活函数具备一定的灵活性,如果把激活函数本身当作学习的对象,那么灵活性一定更高,比如maxout单元。

maxout单元实际上很简单,原本的激活函数直接计算从上一级传入的值,比如考虑不加偏置的全连接网络,上一级有i个节点,那么这一层第j个ReLU接收的输入就是

,进入激活后,产生的输出就是

而maxout在上述步骤间加入了k个神经元,上一节的节点输出会先进入这些神经元,第k个神经元接受到输入

,然后将选取这k神经元中的最大值作为输出

如图,假设有两个输入,标准的ReLU神经元产生的是

,而添加3个神经元的maxout神经元产生的输出为

,注意到最后的三条边并非权重边,也就是说maxput若添加k个神经元,则参数的数量会变成原来的k倍。

可以直观地看出,ReLU只是maxout的特殊情况,事实上,maxout通过取最大值的方式可以逼近任意的凸函数,随着的增加,拟合能力就会越来越强,同时参数的增多使得它比起一般的激活函数具有更多过拟合风险,一般需要加上更为有力的正则化机制。

读芯君开扒

课堂TIPS

事实证明,ELU还有一个优点,它可以将激活函数的均值保持为零,而ReLU输出全为非负。降低均值偏移的程度等价于把激活输出的均值逼近0。同时,还有一种叫做SELU的激活函数,它可以自动使得神经元的输出值标准化。这与我们后面的将要介绍的batch normalization和自归一化神经网络相关,将会在后续课程中集中详细讲解。

不同的激活函数表达能力也会不同,有些激活函数的选择并非出于获得更好的优化,比如正弦函数和余弦函数可以被认为在周期性表达上有优势,双曲正弦函数则表示了矩形波的傅里叶变换。对激活函数的认识要放在一个庞大的神经网络中,所以如果只是对函数本身性质有所理解还远远不够。

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181104A0LKS100?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券