从感知机到神经网络
一、感知机
1.概念
感知机(perceptron)是二类分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别。
听起来复杂,但其实很简单,我们先来看一个感知机的例子:
本例中的感知机有三个输入信号:(当然,它可以有更多或者更少的输入),他们分别有一个权重: , 图中的⚪被称为神经元或节点,输入信号被送往神经元时会被分别乘以固定的权重。神经元的输出是0还是1,由加权和 是否小于或者大于某一个阈值(threshold)决定的,这也被称为“神经元被激活”。
用数学方法表示就是:
感知机的各个信号都有其固有的权重,这些权重来表示各个输入对于输出的重要程度,权重越大,对应权重信号的重要性就越高。
利用单个感知机,我们可以轻松的模拟,与 和 或 两种运算,但对于异或运算,我们似乎束手无策。
2.单层感知机的局限性
异或运算:
思考一下,有没有办法使用单个感知机进行异或运算呢?
好像真的不行....
但这是为什么呢,我们先来看看或运算的数学图像:
这是这个或门数学公式的图像化表示,阴影区域代表输出0,非阴影区域代表输出1,三角和圆圈分别代表和。
但我们要是用数学图像表示异或运算呢?
通过异或门的图像化表示,我们发现,这些结果并不按套路出牌,它们的位置无法用一条直线分割成两类。
也可以说:异或运算是非线性的(线性与非线性在机器学习领域很常见)。
通过观察感知机的数学公式,我们知道上面的感知机只能被画成直线;但要想正确把异或门的结果分开,必须使用曲线。
上过计组的大家一定都知道,其实仅使用与门和或门是可以实现所有电路的,所以:
没错,这就是异或门,不信咱们用真值表验证一下:
所以,异或对应的多层感知机已经呼之欲出:
图中的感知机总共由3层构成,但是因为拥有权重的层实际上只有2层(第0层和第1层之间,第1层和第2层之间)所以被称为“2层感知机”,不过也有人称其为“3层感知机”。
通过这样的双层结构,感知机得以实现异或门,这可以解释为“单层感知机无法解决的问题, 可以通过增加一层感知机来解决”。也就是说,通过叠加层(加深层),感知机能进行更加灵活的表示。
3.多层感知机
多层感知机可以实现比之前见到的电路更复杂的电路,比如进行加法运算的加法器也可以使用感知机实现(如计组实现过的那样),编码器等也可以通过感知机实现,其实,用感知机甚至可以表现计算机。
综上,多层感知机可以进行复杂的表示,甚至可以构建计算机。理论上,可以说2层感知机就能构建计算机。这是因为,亦有研究证明,2层感知机(严格地说是激活函数使用了非线性的sigmoid函数的感知机,会在后面提到)可以表示任意函数。但是,使用2层感知机的构造,通过设定合适的权重来制造计算机还是非常复杂,但只要记住,感知机通过叠加层能够进行非线性的表示,理论上还可以表示计算机进行的处理即可。
4.小结
可以说,感知机是神经网络的基础,所以,对于感知机的理解十分重要。
二、神经网络
1.基础
通过对感知机的学习,我们知道,即便对于复杂的函数,感知机也隐含着能够表示他的可能性,但是,设定权重的工作,即确定合适的、能符合预期的输入与输出的权重,还是由人工进行的。
神经网络和感知机有很多的共同点,我们先以他们的差异为中心,来介绍神经网络的结构:
图中就是一个简单的神经网络,其中的“中间层”有时也被称为“隐藏层”。我们也可以用第0层代表输入层,第1层代表中间层(隐藏层),第2层代表输出层。
再进一步深入以前,我们先再简单回顾一下感知机:
对于一个简单的双输入感知机,存在公式
b就是阈值,也可以称为偏置的参数,用于控制神经元被激活的容易程度;是表示各个信号重要程度的参数,用于控制各个信号的重要性。
在之前的感知机图像中,我们并没有将b明确的画出来,如果想要表示它,我们可以这样做:
对于之前的公式,我们可引入新函数,将其改写为:
2.激活函数
刚刚出现的函数会将输入信号的加权综合转换为输出信号,这种函数一般被称为激活函数,激活函数的作用在于决定如何来激活输入信号的总和。
在之前已经认识了激活函数家族的第一个成员:像实现与门或门的函数这样的,以阈值为界,一旦输入超过阈值,就切换输出的函数被称为“阶跃函数”。
因此,可以说感知机中使用了阶跃函数作为激活函数,那么,如果感知机使用其他函数作为激活函数的话会怎么样呢?实际上,如果将激活函数从阶跃函数换成其他函数,就可以进入神经网络的世界了。
就像下面这样:
如图2-3所示,表示神经元的⚪中明确显示了激活函数的计算过程,即信号的加权总和为节点a,然后节点a被激活函数 转换成节点y,这里,我们称a和y为“节点”,其实它和之前所说的“神经元”含义相同。
2.1 sigmoid函数
神经网络中经常使用的一个激活函数就是sigmoid函数 。
(e是自然常数2.7182...)
神经网络中用sigmoid函数作为激活函数,进行信号的转换,转换后的信号被传送给下一个神经元。感知机和接下来要介绍的神经网络的主要区别就在于这个激活函数。其他方面,比如神经元的多层连接的构造、信号的传递方法等,基本上和感知机是一样的。
我们先看看阶跃函数的图像:
如图所示,阶跃函数以0为界,输出从0切换为1(或者从1切换为0)。 它的值呈阶梯式变化,所以称为阶跃函数。
2.2 sigmoid函数和阶跃函数的比较
现在我们来比较一下sigmoid 函数和阶跃函数,把他们重合在一起:
可以明显观察到,他们的平滑性不同,sigmoid函数是一条平滑的曲线,输出随着输入发生连续性的变化。而阶跃函数以0为界,输出发生急剧性的变化,sigmoid函数的平滑性对神经网络的学习具有重要意义。
另一个不同点是,相对于阶跃函数只能返回0或1,而sigmoid函数可以返回0到1之间的任意实数,也就是说,感 知机中神经元之间流动的是0或1的二元信号,而神经网络中流动的是连续 的实数值信号。
而他们的共同性质是:如果从宏观视角看图2-5,可以发现它们 具有相似的形状。实际上,两者的结构均是“输入小时,输出接近0(为 0); 随着输入增大,输出向1靠近(变成1)”。也就是说,当输入信号为重要信息时, 阶跃函数和sigmoid函数都会输出较大的值;当输入信号为不重要的信息时, 两者都输出较小的值。还有一个共同点是,不管输入信号有多小,或者有多大,输出信号的值都在0到1之间。
还有一点就是:两者均为非线性函数。 sigmoid函数是一条曲线,阶跃函数是一条像阶梯一样的折线,两者都属于非线性的函数。
2.3 非线性函数
神经网络的激活函数必须使用非线性函数,如果使用线性函数的话,加深神 经网络的层数就没有意义了。
这是为什么呢?
线性函数的问题在于,不管如何加深层数,总是存在与之等效的“无隐藏层的神经网络”。
为了具体地理解这一点,我们来思考下面这个简单的例子。
假如把线性函数 作为激活函数,把 的运算对应3层神经网络A。这个运算会进行 的乘法运算,但是同样的处理可以由 这一次乘法运算(即没有隐藏层的神经网络)来表示。
如本例所示, 使用线性函数时,无法发挥多层网络带来的优势,是一种“浪费”。因此,为了发挥叠加层所带来的优势,激活函数必须使用非线性函数。
2.4 ReLu函数
可以说,到目前为止,sigmoid函数和ReLu函数是最常用的两种激活函数。
ReLU函数在输入大于0时,直接输出该值;在输入小于等于0时,输出0:
3.多维数组的运算
这里一些十分基础的矩阵运算就不再提及了, 毕竟大家都已经学过线性代数了。
所以我们来直接看一看他在神经网络中是如何进行的:
信号在各层之间的传递:
图2-8中增加了表示偏置的神经元“1”。请注意,偏置的右下角的索引号只有一个。这是因为前一层的偏置神经元(神经元“1”)只有一个。
为了确认前面的内容,现在用数学式表示,通过加权信号和偏置的和按如下方式进行计算:
如果使用矩阵的乘法运算,则可以将第1层的加权和表示成下面的式子:
在我们加入激活函数后向后传递:
当神经网络进行到最后一层(输出层)时,为了和之前的流程保持一致,我们对输出层也增加一个激活函数,即恒等函数。恒等函数会将输入按原样输出,输出层的激活函数用σ()表示,不同于隐 藏层的激活函数h()。
Tip :输出层所用的激活函数,要根据求解问题的性质决定。一般地,回 归问题可以使用恒等函数,二元分类问题可以使用sigmoid函数, 多元分类问题可以使用softmax函数(会在后面介绍)。
4.恒等函数和softmax函数
恒等函数会将输入按原样输出,对于输入的信息,不加以任何改动地直接输出。
而在分类问题中使用的softmax函数可以如下表示:
如图所示, softmax函数的输出通过箭头与所有的输入信号相连,输出层的各个神经元都受到所有输入信号的影响。
4.1 softmax函数的特征
softmax函数的输出是0.0到1.0之间的实数。并且,softmax 函数的输出值的总和是1。输出总和为1是softmax函数的一个重要性质。正因为有了这个性质,我们才可以把softmax函数的输出解释为“概率”。
假设上图的结果, 是0.245(24.5 %), 是0.737(73.7%)。从概率的结果来看,我们可以说“因为第2个元素的概率最高,所以答案是第2个类别”,通过使用softmax函数,我们可以用概率的(统 计的)方法处理问题。
显然,各输出之间的大小关系也不会发生改变,一般而言,神经网络只把输出值最大的神经元所对应的类别作为识别结果。
4.2 输出层神经元的数量
输出层的神经元数量需要根据待解决的问题来决定。对于分类问题,输出层的神经元数量一般设定为类别的数量。
求解机器学习问题的步骤可以分为“学习” 和“推理”两个阶段。首先,在学习阶段进行模型的学习B,然后,在推理阶段,用学到的 模型对未知的数据进行推理(分类)。如前所述,推理阶段一般会省 略输出层的softmax函数。在输出层使用softmax函数是因为它和神经网络的学习有关(后面会提到)。
4.3 批处理
批处理对计算机的运算大有利处,可以大幅缩短每张图像的处理时间。这是因为大多数处理 数值计算的库都进行了能够高效处理大型数组运算的最优化。
并且,在神经网络的运算中,当数据传送成为瓶颈时,批处理可以减轻数 据总线的负荷(严格地讲,相对于数据读入,可以将更多的时间用在计算上)。也就是说,批处理一次性计算大型数组要比分开逐步计算各个小型数组速度更快。
一般通过设置batch_size来设置批数量。
三、神经网络的学习
神经网络的特征就是可以从数据中学习。所谓“从数据中学习”,是指 可以由数据自动决定权重参数的值。
在感知机的例子中,我们对照着真值表,人工设定了参数的值,但是那时的参数只有3个。 而在实际的神经网络中,参数的数量成千上万,在层数更深的深度学习中, 参数的数量甚至可以上亿,想要人工决定这些参数的值是不可能的
机器学习的方法中,由机器从收集到的数据中找出规律性。与从零开始 想出算法相比,这种方法可以更高效地解决问题,也能减轻人的负担。但是 需要注意的是,将图像转换为向量时使用的特征量仍是由人设计的。对于不同的问题,必须使用合适的特征量(必须设计专门的特征量),才能得到好的结果。
比如,识别动物和识别数字,显然需要使用不同的特征量。
到这里,我们介绍了两种针对机器学习任务的方法。将这两种方法用图来表示,。图中还展示了神经网络(深度学习)的方法,可以看出该方法不存在人为介入,神经网络直接学习图像本身。而在第2个方法,即利用特征量和机器学习的方法中,特征量仍是由人工设计的,但在神经网络中,连图像中包含的重要特征量也都是由机器来学习的。
神经网络的优点是对所有的问题都可以用同样的流程来解决。比如,不管要求解的问题是识别数字,还是识别动物或是识别人脸,神经网络都是通过不断地学习所提供的数据,尝试发现待求解的问题的模式。也就是说,与待处理的问题无关,神经网络可以将数据直接作为原始数据,进行“端对端”的学习,这也正是神经网络强大的地方。
1.基础
机器学习中,一般将数据分为训练数据和测试数据两部分来进行学习和 实验等。首先,使用训练数据进行学习,寻找最优的参数;然后,使用测试 数据评价训练得到的模型的实际能力。
为什么需要将数据分为训练数据和测试数据呢?因为我们追求的是模型的泛化能力。为了正确评价模型的泛化能力,就必须划分训练数据和测试数据。另外,训练数据也可以称为监督数据。
泛化能力是指处理未被观察过的数据(不包含在训练数据中的数据)的 能力。获得泛化能力是机器学习的最终目标,如果系统 只能正确识别已有的训练数据,那有可能是只学习到了训练数据中的个人的习惯写法。
因此,仅仅用一个数据集去学习和评价参数,是无法进行正确评价的。 这样会导致可以顺利地处理某个数据集,但无法处理其他数据集的情况。只对某个数据集过度拟合的状态称为过拟合避免过拟合也是机器学习的一个重要课题。
2.损失函数
损失函数是表示神经网络性能的“恶劣程度”的指标,即当前的神经网络对监督数据在多大程度上不拟合,在多大程度上不一致。
2.1 均方误差
可以用作损失函数的函数有很多,其中最有名的是均方误差(mean squared error)。均方误差如下式所示:
这里,是表示神经网络的输出,表示监督数据,k表示数据的维数。
2.2 交叉熵误差
除了均方误差之外,交叉熵误差(cross entropy error)也经常被用作损 失函数。交叉熵误差如下式所示:
实际上只计算对应正确解标签的输出的自然对数。比如,假设正确解标签的索引是“2”,与之对应的神经网络的输出是0.6,则交叉熵误差是−log 0.6 = 0.51;若“ 2”对应的输出是0.1,则交叉熵误差为−log0.1 = 2.30。 也就是说,交叉熵误差的值是由正确解标签所对应的输出结果决定的。
2.3 mini-batch学习
机器学习使用训练数据进行学习。使用训练数据进行学习,严格来说, 就是针对训练数据计算损失函数的值,找出使该值尽可能小的参数。因此,计算损失函数时必须将所有的训练数据作为对象。也就是说,如果训练数据有100个的话,我们就要把这100个损失函数的总和作为学习的指标,以交叉熵误差为例,可以写成下面的式子:
这里,假设数据有N个,表示第n个数据的第k个元素的值。
如果遇到大数据, 数据量会有几百万、几千万之多,这种情况下以全部数据为对象计算损失函 数是不现实的。因此,我们从全部数据中选出一部分,作为全部数据的“近 似”。神经网络的学习也是从训练数据中选出一批数据(称为mini-batch,小 批量),然后对每个mini-batch进行学习。比如,从60000个训练数据中随机 选择100笔,再用这100笔数据进行学习。这种学习方式称为mini-batch学习。
3.数值微分
3.1 导数
这个大家显然都学过,物理意义和数学意义就不在这里多讲了
3.2 数值微分的实现
利用微小的差分求导数的过程称为数值微分(numerical differentiation)。而基于数学式的推导求导数的过程,则用“解析性”(analytic)一词,称为“解析性求解”或者“解析性求导”。比如, y = x2的导数,可以通过解析性地求解出来。因此,当x = 2时, y的导数为4。解析性求导得到的导数是不含误差的“真的导数”。
3.3 偏导数
偏导数和单变量的导数一样,都是求某个地方的斜率。不过, 偏导数需要将多个变量中的某一个变量定为目标变量,并将其他变量固定为某个值。在上例的代码中,为了将目标变量以外的变量固定到某些特定的值 上,我们定义了新函数。然后,对新定义的函数应用了之前的求数值微分的 函数,得到偏导数。
4.梯度
在刚才的例子中,我们按变量分别计算了和的偏导数。现在,我们希望一起计算和的偏导数。比如,我们来考虑求 = 3, = 4时(x0,x 1) 的偏导数 ,由全部变量的偏导数汇总而成的向量称为梯度(gradient)。
如图所示的梯度呈现为有向向量(箭头),我们发现梯度指向函数的“最低处”(最小值),就像指南针 一样,所有的箭头都指向同一点。其次,我们发现离“最低处”越远,箭头越大。
虽然图4-9中的梯度指向了最低处,但并非任何时候都这样。实际上, 梯度会指向各点处的函数值降低的方向。更严格地讲,梯度指示的方向 是各点处的函数值减小最多的方向。
4.1 梯度法
机器学习的主要任务是在学习时寻找最优参数。同样地,神经网络也必须在学习时找到最优参数(权重和偏置)。这里所说的最优参数是指损失函数取最小值时的参数。但是,一般而言,损失函数很复杂,参数空间庞大,我们不知道它在何处能取得最小值。而通过巧妙地使用梯度来寻找函数最小值 (或者尽可能小的值)的方法就是梯度法。
梯度表示的是各点处的函数值减小最多的方向。因此,无法保证梯度所指的方向就是函数的最小值或者真正应该前进的方向。实际上,在复杂的函数中,梯度指示的方向基本上都不是函数值最小处。
函数的极小值、最小值以及被称为鞍点的地方, 梯度为0。极小值是局部最小值,也就是限定在某个范围内的最 小值。鞍点是从某个方向上看是极大值,从另一个方向上看则是极小值的点。
虽然梯度法是要寻找梯度为0的地方,但是那个地方不一定就是最小值(也有可能是极小值或者鞍点)。此外,当函数很复杂且呈扁平状时,学习可能会进入一个(几乎)平坦的地区, 陷入被称为“学习高原”的无法前进的停滞期。
虽然梯度的方向并不一定指向最小值,但沿着它的方向能够最大限度地 减小函数的值,在梯度法中,函数的取值从当前位置沿着梯 度方向前进一定距离,然后在新的地方重新求梯度,再沿着新梯度方向前进, 如此反复,不断地沿梯度方向前进。
严格地讲, 寻找最小值的梯度法称为梯度下降法 , 寻找最大值的梯度法称为梯度上升法,但是通过反转损失函数的符号,求最小值的问题和求最大值的问题会变成相同的问题。
η表示更新量,在神经网络的学习中,称为学习率。学习率决定在一次学习中,应该学习多少,以及在多大程度上更新参数。这个步骤会反复执行,也就是说,每 一步都按式(4.7)更新变量的值,通过反复执行此步骤,逐渐减小函数值。
学习率需要事先确定为某个值,比如0.01或0.001。一般而言,这个值过大或过小,都无法抵达一个“好的位置”。在神经网络的学习中,一般会 一边改变学习率的值,一边确认学习是否正确进行了。
4.2 神经网络的梯度
神经网络的学习也要求梯度,这里所说的梯度是指损失函数关于权重参数的梯度。比如,有一个只有一个形状为2×3的权重W的神经网络,损失函数用L表示。此时,梯度可以用表示。
然后我们用学习率乘以在相应位置上的梯度,更新权重。
相比数值微分法求梯度, 使用误差反向传播法精度更高,和解析法是一致的。误差反向传播法是通过计算图实现的,假如有时间可以另行介绍。
5.深度学习算法的实现
关于神经网络学习的基础知识,到这里就全部介绍完了。“损失函数”,“ mini-batch”,“梯度”,“梯度下降法”等关键词已经悉数登场,接下来我们来确认一下神经网络的学习步骤:
前提 神经网络存在合适的权重和偏置,调整权重和偏置以便拟合训练数据的 过程称为“学习”。神经网络的学习分成下面4个步骤。
步骤1 (mini-batch) 从训练数据中随机选出一部分数据,这部分数据称为mini-batch。我们 的目标是减小mini-batch的损失函数的值。
步骤2 (计算梯度) 为了减小mini-batch的损失函数的值,需要求出各个权重参数的梯度。 梯度表示损失函数的值减小最多的方向。
步骤3 (更新参数) 将权重参数沿梯度方向进行微小更新。
步骤4 (重复) 重复步骤1、步骤2、步骤3。
神经网络的学习按照上面4个步骤进行。这个方法通过梯度下降法更新参数,不过因为这里使用的数据是随机选择的mini batch数据,所以又称为随机梯度下降法(SGD)。“随机”指的是“随机选择的” 的意思,因此,随机梯度下降法是“对随机选择的数据进行的梯度下降法”。 深度学习的很多框架中,随机梯度下降法一般由一个名为SGD的函数来实现。 SGD来源于随机梯度下降法的英文名称的首字母。
三、学习的技巧
将会介绍神经网络的学习中的一些重要观点,主题涉及寻找最优权重参数的最优化方法、权重参数的初始值、超参数的设定方法等。此外,为了应对过拟合,还将介绍权值衰减、Dropout等正则化方法, 最后将对近年来众多研究中使用的Batch Normalization方法进行简单的介绍。
1.参数的更新
神经网络的学习的目的是找到使损失函数的值尽可能小的参数。这是寻 找最优参数的问题,解决这个问题的过程称为最优化(optimization)。
在之前,为了找到最优参数,我们将参数的梯度(导数)作为了线索。 使用参数的梯度,沿梯度方向更新参数,并重复这个步骤多次,从而逐渐靠 近最优参数,这个过程称为随机梯度下降法(SGD)。SGD是一个简单的方法,不过比起胡乱地搜索参数空间,也算是“聪 明”的方法。但是,根据不同的问题,也存在比SGD更加聪明的方法。
1.1 SGD
这里把需要更新的权重参数记为W,把损失函数关于W的梯度记为 。 η表示学习率,实际上会取0.01或0.001这些事先决定好的值。
虽然SGD简单,并且容易实现,但是在解决某些问题时可能没有效率。 这里,在指出SGD的缺点之际,我们来思考一下求下面这个函数的最小值的问题:
现在看一下这个函数的梯度。如果用图表示梯度的话,则如图所示,这个梯度的特征是,y轴方向上大,x轴方向上小。换句话说, 就是y轴方向的坡度大,而x轴方向的坡度小。这里需要注意的是,虽然式 (6.2)的最小值在(x,y) = (0, 0)处,但是图中的梯度在很多地方并没有指 向(0, 0)。
如果我们对这种形状的函数应用SGD,明显会呈现“之”字形移动这种非常低效的路径,所以,SGD的缺点是,如果函数的形状非均向(anisotropic),比如呈延伸状,搜索 的路径就会非常低效。
所以接下来我们介绍几种优化后的方法,很多原理都比较复杂,大家可以自行查阅论文,这里主要是介绍。
1.2 Momentum
Momentum是“动量”的意思,和物理有关。用数学式表示Momentum方 法,如下所示:
和前面的SGD一样,W表示要更新的权重参数, 表示损失函数关 于W的梯度,η表示学习率。这里新出现了一个变量v,对应物理上的速度。这个公式表示了物体在梯度方向上的受力,在这个力的作用下,物体的速度增加这一物理法则。其中中有 αv这一项。在物体不受任何力时,该项承担使物体逐渐减速的任务(α设定为0.9之类的值),对应物理上的地面摩擦或空气阻力。
可以看到,当我们使用momentum优化时,更新路径就像小球在碗中滚动一样。和SGD相比,我们发现 “之”字形的“程度”减轻了。这是因为虽然x轴方向上受到的力非常小,但是因为一直在同一方向上受力,所以朝同一个方向会有一定的加速。反过来,虽然y轴方向上受到的力很大,但是因为交互地受到正方向和反方向的力,它们会互相抵消,所以y轴方向上的速度不稳定。
1.3 AdaGrad
在神经网络的学习中,学习率(数学式中记为η)的值很重要。学习率过小, 会导致学习花费过多时间;反过来,学习率过大,则会导致学习发散而不能 正确进行。
在关于学习率的有效技巧中,有一种被称为学习率衰减(learning rate decay)的方法,即随着学习的进行,使学习率逐渐减小。实际上,一开始“多” 学,然后逐渐“少”学的方法,在神经网络的学习中经常被使用。 逐渐减小学习率的想法,相当于将“全体”参数的学习率值一起降低。
而AdaGrad 进一步发展了这个想法,针对“一个一个”的参数,赋予其“定制”的值。 AdaGrad会为参数的每个元素适当地调整学习率,与此同时进行学习 。下面,让我们用数学式表示AdaGrad的更新方法。
和前面的SGD一样,W表示要更新的权重参数, 表示损失函数关 于W的梯度,η表示学习率。这里新出现了变量h,它保存了以前的所有梯度值的平方和, 表示对应矩阵元素的乘法。 然后,在更新参数时,通过乘以 ,就可以调整学习的尺度。这意味着, 参数的元素中变动较大(被大幅更新)的元素的学习率将变小。也就是说, 可以按参数的元素进行学习率衰减,使变动大的参数的学习率逐渐减小。
AdaGrad会记录过去所有梯度的平方和。因此,学习越深入,更新的幅度就越小。实际上,如果无止境地学习,更新量就会变为0, 完全不再更新。为了改善这个问题,可以使用RMSProp方法。 RMSProp方法并不是将过去所有的梯度一视同仁地相加,而是逐渐 地遗忘过去的梯度,在做加法运算时将新梯度的信息更多地反映出来。 这种操作从专业上讲,称为“指数移动平均”,呈指数函数式地减小 过去的梯度的尺度。
函数的取值高效地向着最小值移动。由于y轴方向上的梯度较大,因此刚开始变动较大,但是后面会根据这个较大的变动按 比例进行调整,减小更新的步伐。因此,y轴方向上的更新程度被减弱,“之” 字形的变动程度明显减弱。
1.4 Adam
Momentum参照小球在碗中滚动的物理规则进行移动,AdaGrad为参 数的每个元素适当地调整更新步伐。如果将这两个方法融合在一起会怎么样呢?这就是Adam的基本思路。
Adam是2015年提出的新方法。它的理论有些复杂,简单地讲,就是融 合了Momentum和AdaGrad的方法。通过组合前面两个方法的优点,有望实现参数空间的高效搜索。此外,进行超参数(后面会提到)的“偏置校正”也是Adam的特征。 这里不再进行过多的说明,详细内容请参考原作者的论文。
Adam会设置3个超参数。一个是学习率(论文中以α出现),另外两 个是一次momentum系数β1和二次momentum系数β2。根据论文, 标准的设定值是β1为0.9,β2 为0.999。设置了这些值后,大多数情 况下都能顺利运行。
基于Adam的更新过程就像小球在碗中滚动一样。虽然 Momentun也有类似的移动,但是相比之下,Adam的小球左右摇晃的程度 有所减轻。这得益于学习的更新程度被适当地调整了。
上面我们介绍了SGD、Momentum、AdaGrad、Adam这4种方法,那么用哪种方法好呢?
非常遗憾,目前并不存在能在所有问题中都表现良好 的方法。这4种方法各有各的特点,都有各自擅长解决的问题和不擅长解决的问题。 很多研究中至今仍在使用SGD。Momentum和AdaGrad也是值得一试的方法,最近也很多研究人员和技术人员都喜欢用Adam。
2. 权重的初始值
在神经网络的学习中,权重的初始值特别重要。实际上,设定什么样的 权重初始值,经常关系到神经网络的学习能否成功。
后面我们会介绍抑制过拟合、提高泛化能力的技巧——权值衰减(weight decay)。简单地说,权值衰减就是一种以减小权重参数的值为目的进行学习的方法。通过减小权重参数的值来抑制过拟合的发生。
如果想减小权重的值,一开始就将初始值设为较小的值才是正途。实际上, 在这之前的权重初始值都是像0.01 * np.random.randn(10, 100)这样,使用由高斯分布生成的值乘以0.01后得到的值(标准差为0.01的高斯分布)。
如果我们把权重初始值全部设为0以减小权重的值,会怎么样呢?从结论来说,将权重初始值设为0不是一个好主意。事实上,将权重初始值设为0的话,将无法正确进行学习。
这是因为在误差反向传播法中,所有的权重值都会进行相同的更新。比如,在2层神经网络中,假设第1层和第2层的权重为0。这样一来,正向传播时,因为输入层的权重为0,所以第2层的神经元全部会被传递相同的值。第2层的神经元中全部输入相同的值,这意味着反向传播时第2层的权重全部都会进行相同的更新。因此,权重被更新为相同的值,并拥有了重复的值。 这使得神经网络拥有许多不同的权重的意义丧失了。为了防止“权重均一化” ,必须随机生成初始值。
接下来我们来看看权重的初值是如何影响隐藏层的激活值的分布的:
当我们使用标准差为1的高斯分布作为权重初始值时各层的激活值偏向0和1分布,假如使用sigmoid函数,随着输出不断靠近0或1,他的导数值不断接近于0。因此,偏向0和1的数据分布会造成反向传播中梯度的值不断变小,最后消失。这个问题称为梯度消失。层次加深的深度学习中,梯度消失的问题可能会更加严重。
而使用标准差为0.01的高斯分布时,如图所示:
这次呈集中在0.5附近的分布,因为不像刚才的例子那样偏向0和1,所以不会发生梯度消失的问题。但是,激活值的分布有所偏向,说明在表现力 上会有很大问题。为什么这么说呢?
因为如果有多个神经元都输出几乎相同 的值,那它们就没有存在的意义了。比如,如果100个神经元都输出几乎相同的值,那么也可以由1个神经元来表达基本相同的事情。因此,激活值在 分布上有所偏向会出现“表现力受限”的问题。
2.1 Xavier初始值
Xavier的论文中,为了使各层的激活值呈现出具有相同广度的分布,推导了合适的权重尺度。推导出的结论是,如果前一层的节点数为n,则初始 值使用标准差为的分布。使用Xavier初始值后,前一层的节点数越多,要设定为目标节点的初始值的权重尺度就越小。
使用Xavier初始值后的结果如图6-13所示。从这个结果可知,越是后面的层,图像变得越歪斜,但是呈现了比之前更有广度的分布。因为各层间传递的数据有适当的广度,所以sigmoid函数的表现力不受限制,有望进行高效的学习。
想了解Xavier初始值是如何推导的,可以看我在网上看到的这篇文章:深度学习中Xavier初始化
2.2 ReLu初始值
Xavier初始值是以激活函数是线性函数为前提而推导出来的。因为 sigmoid函数和tanh函数左右对称,且中央附近可以视作斜率为1的线性函数,所以适用于Xavier函数。
但当激活函数使用ReLu时,一般推荐使用“He初始值”,即当前一层的节点数为n时,He初始值使用标准差为的高斯分布。当 Xavier初始值是 时,(直观上)可以解释为,因为ReLU的负值区域的值 为0,为了使它更有广度,所以需要2倍的系数。
接下来我们看看三种情况下的实验结果:
观察实验结果可知,当“std = 0.01”时,各层的激活值非常小。神经网络上传递的是非常小的值,说明逆向传播时权重的梯度也同样很小,学习基本没有进展。
接下来是初始值为Xavier初始值时的结果。在这种情况下,随着层的加深, 偏向一点点变大。实际上,层加深后,随着激活值的偏向变大,学习时会出现梯度消失的问题。
而当初始值为He初始值时,各层中分布的广度相同。由于即便层加深,数据的广度也能保持不变,因此逆向传播时,也会传递合适的值。
3. Batch Normalization 批量标准化
Batch Normalization(下文简称Batch Norm)是 2015年提出的方法。 Batch Norm虽然是一个问世不久的新方法,但已经被很多研究人员和技术 人员广泛使用。
Batch Norm有以下优点:
• 可以使学习快速进行(可以增大学习率)。
• 不那么依赖初始值(对于初始值不用那么纠结)。
• 抑制过拟合(降低Dropout(一种避免过拟合的方法,后面会提到)等的必要性)。
Batch Norm的思路是调整各层的激活值分布使其拥有适当 的广度。为此,要向神经网络中插入对数据分布进行正规化的层,即Batch Normalization层。
Batch Norm,顾名思义,以进行学习时的mini-batch为单位,按mini-batch进行正规化。具体而言,就是进行使数据分布的均值为0、方差为1的正规化。用数学式表示的话,如下所示:
这里对mini-batch的m个输入数据的集合B ={x1,x2,...,xm}求均值 和方差 。然后,对输入数据进行均值为0、方差为1(合适的分布)的正规化。式子中的是一个微小值(比如,10e-7等),它是为了防止出现除以0的情况。
接着,Batch Norm层会对正规化后的数据进行缩放和平移的变换,用数学式可以如下表示:
这里,和是参数。一开始 = 1, = 0,然后再通过学习调整到合适的值。
几乎所有的情况下都是使用Batch Norm时学习进行得更快。 同时也可以发现,在不使用Batch Norm的情况下,如果不赋予一个尺度好的初始值,学习将完全无法进行。通过使用Batch Norm,可以推动学习的进行;并且,神经网络对权重初始值变得健壮。
4.正则化
机器学习的问题中,过拟合是一个很常见的问题。过拟合指的是只能拟合训练数据,但不能很好地拟合不包含在训练数据中的其他数据的状态。所以,抑制过拟合的技巧很重要。
发生过拟合的原因,主要有以下两个:
• 模型拥有大量参数、表现力强。
• 训练数据少。
4.1 权值衰减
权值衰减是一直以来经常被使用的一种抑制过拟合的方法。该方法通过在学习的过程中对大的权重进行惩罚,来抑制过拟合。很多过拟合原本就是因为权重参数取值过大才发生的。
神经网络的学习目的是减小损失函数的值。这时,例如为损失函数加上权重的平方范数(L2范数)。这样一来,就可以抑制权重变大。 用符号表示的话,如果将权重记为,L2范数的权值衰减就是 ,然 后将这个加到损失函数上。这里,λ是控制正则化强度的超参数。λ 设置得越大,对大的权重施加的惩罚就越重。此外,开头的是用于将的求导结果变成的调整用常量。 对于所有权重,权值衰减方法都会为损失函数加上 。因此,在求权 重梯度的计算中,要为之前的误差反向传播法的结果加上正则化项的导数。
L2范数相当于各个元素的平方和。用数学式表示的话,假设有权重 ,则L2范数可用计算出来。
4.2 Dropout
作为抑制过拟合的方法,前面我们介绍了为损失函数加上权重的L2范数的权值衰减方法。该方法可以简单地实现,在某种程度上能够抑制过拟合。但是,如果网络的模型变得很复杂,只用权值衰减就难以应对了。
在这种情 况下,我们经常会使用Dropout方法。 Dropout是一种在学习的过程中随机删除神经元的方法。训练时,随机选出隐藏层的神经元,然使其暂时失效。被删除的神经元不再进行信号的传递。训练时,每传递一次数据,就会随机选择要失效的神经元。
通过使用Dropout,训练数据和测试数据的识别精度的差距 变小了。并且,训练数据也没有到达100%的识别精度。像这样,通过使用 Dropout,即便是表现力强的网络,也可以抑制过拟合。
机器学习中经常使用集成学习。所谓集成学习,就是让多个模型单 独进行学习,推理时再取多个模型的输出的平均值。实验告诉我们,通过进行集成学习,神经网络的识别精度可以提高好几个百分点。这个集成学习与Dropout有密切的关系。
这是因为可以将Dropout 理解为,通过在学习过程中随机删除神经元,从而每一次都让不同的模型进行学习。并且,推理时,通过对神经元的输出乘以删除比例(比如,0.5等),可以取得模型的平均值。也就是说,可以理解成, Dropout将集成学习的效果通过一个网络实现了。
4.3 超参数验证
神经网络中,除了权重和偏置等参数,超参数(hyper-parameter)也经常出现。这里所说的超参数是指,比如各层的神经元数量、batch大小、参数更新时的学习率或权值衰减等。如果这些超参数没有设置合适的值,模型的性能就会很差。
之前我们使用的数据集分成了训练数据和测试数据,训练数据用于学习, 测试数据用于评估泛化能力。调整超参数时,必须使用超参数专用的确认数据。用于调整超参数的数据,一般称为验证数据(validation data)。我们使用这个验证数据来 评估超参数的好坏。
进行超参数的最优化时,逐渐缩小超参数的“好值”的存在范围非常重要。 所谓逐渐缩小范围,是指一开始先大致设定一个范围,从这个范围中随机选 出一个超参数(采样),用这个采样到的值进行识别精度的评估;然后,多次重复该操作,观察识别精度的结果,根据这个结果缩小超参数的“好值”的范围。 通过重复这一操作,就可以逐渐确定超参数的合适范围。
超参数的范围只要“大致地指定”就可以了,也就是像0.001()到 1000()这样,以“ 10的阶乘”的尺度指定范围。
在超参数的最优化中,要注意的是深度学习需要很长时间(比如,几天或几周)。因此,在超参数的搜索中,需要尽早放弃那些不符合逻辑的超参数。 在最优化中,减少学习的epoch,缩短一次评估所需的时间 是一个不错的办法。 简单归纳一下,如下所示:
步骤0 设定超参数的范围。
步骤1 从设定的超参数范围中随机采样。
步骤2 使用步骤1中采样到的超参数的值进行学习,通过验证数据评估识别精度(但是要将epoch设置得很小)。
步骤3 重复步骤1和步骤2(100次等),根据它们的识别精度的结果,缩小超参数的范围。
反复进行上述操作,不断缩小超参数的范围,在缩小到一定程度时,从该范围中选出一个超参数的值。这就是进行超参数的最优化的一种方法。