神经网络与深度学习笔记——第3章 改进神经网络的学习方法

第3章 改进神经网络的学习方法

改进激活函数

我们的神经元是通过改变权重和偏置,并以一个代价函数的偏导数来决定的学习速度。如果学习缓慢,实际上就是说这些偏导数很小。
当神经元的输出接近1的时候,S型曲线变得相当平,所以偏导数就会很小。
常用的激活函数包括:

  1. S型函数sigmoid
  2. 双曲正切函数tanh
  3. 修正线性神经元(rectified linear neuron,或者rectified linear unit,简称ReLU)

S型神经元的所有激活值都是正数,反向传播告诉我们相关的梯度是 alkδl+1j ,因为所有的激活值 alk 都是正数,所以梯度的符号就和 δl+1j 一致。这意味着如果 δl+1j 为正,那么所有的权重 wl+1jk 都会在梯度下降时减少;如果 δl+1j 为负,那么所有的权重 wl+1jk 都会在梯度下降时增加。换句话说,针对同一神经元的所有权重都会或者一起增加,或者一起减少。这就有问题了,因为某些权重可能需要有相反的变化。这样的话,只能是某些输入激活值有相反的符号才可能出现。所以tanh就能够达到这个目的。隐藏层的激活值能够在正负之间保持平衡。
需要注意的是,tanh并不一定就超过sigma函数。
sigmoid神经元在输出接近0或者1的时候会趋于饱和,即sigmoid的导数趋向于0,减缓了学习。tanh神经元也有这个问题,ReLU就不会有这个问题。

改进代价函数

引入交叉熵代价函数

二次代价函数:

C=12(ya)2

二次代价函数计算偏导数:
Cw=(ay)σ(z)x

Cb=(ay)σ(z)

交叉熵函数:
C=1nx[ylna+(1y)ln(1a)]

交叉熵函数计算偏导数:
Cwj=1nxxj(σ(z)y)

Cb=1nx(σ(z)y)

可以通过 使用交叉熵代价函数来替换二次代价函数
为什么交叉熵可以看做代价函数,因为:
1.交叉熵函数值是非负的;
2.如果神经元输出接近目标值,则交叉熵接近0;
3.交叉熵函数避免了学习速度下降缓慢的问题。

根据交叉熵偏导数的公式可知,权重学习的速度收到 σ(z)y ,也就是输出中的误差的控制。更大的误差,更快的学习速度。同时避免了二次代价函数中 σ(z) 导致的学习缓慢。

什么时候使用交叉熵来替换二次代价函数?
如果输出神经元是S型神经元时,交叉熵一般都是更好的选择。
而如果输出的神经元是线性的,那么二次代价函数不再会导致学习速度下降的问题。这种情况下,二次代价函数就是一种合适的选择。

二次代价对于相同的学习速率,以平均慢6倍的速度进行学习。所以我们可以把二次代价的学习速率除以6。当然,这个理由不严谨,不应该被认真对待。不过,有时候是个有用的起点。

交叉熵是“不确定性”的一种度量。
交叉熵衡量我们学习到 y 的正确值的平均起来的不确定性。如果输出我们期望的结果,不确定性就会小一点;反之,不确定性就大一些。

柔性最大值(softmax)

柔性最大值层的输出是一些相加为 1 正数的集合。换言之,柔性最大值层的输出可以被看做是一个概率分布。
softmax是怎样解决学习缓慢问题的?
定义一个对数似然代价函数:

C=lnaLy

如果一个对应的概率跟1非常接近,那么代价函数就会很小。反之,那么代价函数就会很大。所以对数似然代价函数也是满足我们期待的代价函数条件的。
对数似然代价函数的偏导数:
CbLj=aLjyj

CwLjk=aL1k(aLjyj)

这些表达式和交叉熵类似,确保我们不会遇到学习缓慢的问题。

应该使用一个具有交叉熵代价的 S 型输出层,还是一个具有对数似然代价的柔性最大值输出层呢?
实际上,在很多应用场景中,这两种方式的效果都不错。甚至可以使用这两种方式的组合。组合更加适用于那些需要将输出激活值解释为概率的场景。在诸如 MNIST 这种有着不重叠的分类问题上确实很有用。

改进权重的初始化

通过使用交叉熵函数代替二次代价函数可以解决输出神经元的饱和,但对隐藏层的饱和却一点儿作用都没有。
如果使用均值为0标准差为1的独立高斯随机变量初始化权重和偏置,假设输入有1000个神经元,输入神经元的值一半为0一半为1,那么隐藏层神经元输入的带权和为 z=jwjxj+b ,其中500个项消去了,因为对应的输入为0,所以z是遍历总共501个归一化的高斯随机变量的和,包括500个权重和1个偏置。所以z是一个均值为0标准差为 501=22.4 的高斯分布。z非常宽,就是指大多数的z大于1或者z小于-1,那么隐藏层神经元的输出就会接近1或者0,意味着隐藏层的神经元会饱和。
所以我们使用均值为0标准差为 1nin 的高斯随机分布初始化这些权重,使用均值为0标准差为1的高斯分布来对偏置进行初始化。这样的化,带权和 z=jwjxj+b 仍然是一个均值为0,不过有尖锐峰值的高斯分布,这样的一个神经元隐藏层更不可能会饱和,所以也不大可能会遇到学习速率下降的问题。
1nin 权重初始化会带来训练速度的加快,有时候在最终的性能上也有很大的提升(也有时候不会改变网络的最终性能)。

偏置的初始化使用均值为0标准差为1的高斯分布是可行的,因为这样并不会让我们的神经网络更容易饱和。对于饱和问题,如何初始化偏置影响不大。甚至有些人将所有的偏置初始化为0,依赖梯度下降来学习合适的偏置。

正则(规范化)

这里的正则包括L1正则,L2正则,dropout(弃权)
正则不包括偏置。

直觉地看,规范化的效果是让网络倾向于学习小一点的权重,其他的东西都一样的。大的权重只有能够给出代价函数第一项足够的提升时才被允许。换言之,规范化可以当做一种寻找小的权重和最小化原始的代价函数之间的折中。这两部分之前相对的重要性就由 λ 的值来控制了:λ 越小,就偏向于最小化原始代价函数,反之,倾向于小的权重。

多次随机初始化进行网络训练的时候,没有正则的网络会被限制住,困在了代价函数的局部最优值处。结果就是不同的运行会给出相差很大的结果。相反,正则化的网络能够提供得到更好的结果。

L1正则:

C=C0+λnw|w|

L1网络进行更新的规则是:
ww=wηλnsgn(w)ηC0w

其中, sgn(w) 是指 w 为正数时为1,w为负数时为-1。
L1网络进行更新的规则是:
ww=w(1ηλn)ηC0w

两种规范化都惩罚大的权重,但权重缩小的方式不同。
L1规范化中,权重通过一个常量向0缩小。
L2规范化中,权重通过一个和 w 成比例的量进行缩小。
所以,权重的绝对值|w|很大时,L2权重缩小的多;
权重的绝对值 |w| 很小时,L1权重缩小的多。
最终的结果就是,L1规范化倾向于聚集网络的权重在相对少量的高重要度连接上,其他权重向0接近。
w=0的时候导数不存在,可以定义sgn(0)=0。

弃权(dropout)是一种相当激进的技术。
弃权的过程就如同大量不同网络的效果的平均那样。不同的网络以不同的方式过度拟合了,所以弃权过的网络效果会减轻过度拟合。
因为神经元不能依赖其他神经元特定的存在,这个技术其实是减少了复杂的互适应的神经元。所以,强制要学习那些在神经元的不同随机子集中更加健壮的特征。
弃权可以看做是一种确保模型对于一部分证据丢失健壮的方式。
弃权技术在训练大规模深度网络时尤其有用,这样的网络中过度拟合问题经常特别突出。

人为扩展训练数据

获取更多的训练样本其实是很好的想法,但是这种方式代价很大,实践中难以达到。不过还有一种方法能够获得类似的效果,那就是人为扩展训练数据。例如,MNIST训练样本进行旋转,转换或者扭曲等方法进行扩展;语音识别中加入背景噪音进行扩展数据。
注意的是,人为扩展训练数据也不一定是有用的。例如语音识别中增加背景噪音的数据可能不如通过去除噪音的方式进行数据清洗更有效。
更多的训练数据可以补偿不同的机器学习算法的差距。

随机梯度下降的变化形式

包括Hessian技术,基于momentum的梯度下降以及其他优化代价函数的方法。

Hessian技术
代价函数关于权重w的表达式 C=C(w) ,借助于泰勒展开式,代价函数在点w处被近似为:

C(w+Δw)=C(w)+jCWjΔwj+12jkΔwj2CwjwkΔwk+...

可以将其压缩为
C(w+Δw)C(w)+CΔw+12ΔwTHΔwk

使用微积分,可证明右式表达式可以进行最小化:
Δw=H1C

所以,我们把点 w 移动到w+Δw=wηH1C就可以显著地降低代价函数的值,其中 η 是学习速率。
在理论上和实践中的结果都表明 Hessian 方法比标准的梯度下降方法收敛速度更快。特别地,通过引入代价函数的二阶变化信息,可以让 Hessian 方法避免在梯度下降中常碰到的多路径(pathologies)问题。而且,反向传播算法的有些版本也可以用于计算 Hessian。
不幸的是,尽管 Hessian 优化有很多可取的特性,它其实还有一个不好的地方:在实践中很难应用。这个问题的部分原因在于Hessian 矩阵的太大了。假设你有一个 107 个权重和偏置的网络。那么对应的 Hessian 矩阵会有 107107=1014 个元素。这真的是太大了!所以在实践中,计算 H1C 就极其困难。
基于momentum的梯度下降
直觉上看,Hessian 优化的优点是它不仅仅考虑了梯度,而且还包含梯度如何变化的信息。基于 momentum 的梯度下降就基于这个直觉,但是避免了二阶导数的矩阵的出现。
该方法引入了速度 v 的概念,并且引入了摩擦力u的项,用来逐步地减少速度。
将梯度下降更新规则 ww=wηC 改成
vv=uvηC

ww=w+v

u 是用来控制摩擦力的参数,当u=1的时候,没有任何摩擦力。此时, C 改变了速度 v ,然后再控制w的变化率。而当 u=0 的时候,存在很大的摩擦力,速度无法叠加,就变成了普通的梯度下降。所以,在实践中,使用0和1之间的 u 值可以给我们避免过量而又能够叠加速度的好处。
我们使用验证集来选择合适的u值。
关于 momentum 技术的一个很好的特点是它基本上不需要改变太多梯度下降的代码就可以实现。
其他优化代价函数的方法
例如共轭梯度下降,BFGS方法,L-BFGS方法,Nesterov加速梯度技术(对momentum进行了改进)。
对于很多问题,标准的随机梯度下降算法,特别当momentum用起来以后就可以工作的很好了。

其他

关于过拟合

防止过拟合的方法有:
1.使用验证集来调整超参数,防止过拟合。
2.一般来说,最好的降低过度拟合的方式之一就是增加训练样本的量。有了足够的训练数据,就算是一个规模非常大的网络也不大容易过度拟合。不幸的是,训练数据其实是很难或者很昂贵的资源,所以这不是一种太切实际的选择。
3.正则化。包括L1正则,L2正则。
4.dropout(弃权)
5.人为增加训练样本

为什么正则可以防止过拟合?
在规范化的网络中,更小的权重意味着网络的行为不会因为我们随便改变了一个输入而改变太大。这会让规范化网络学习局部噪声的影响更加困难。将它看做是一种让单个的证据不会影响网络输出太多的方式。相对的,规范化网络学习去对整个训练集中经常出现的证据进行反应。对比看,大权重的网络可能会因为输入的微小改变而产生比较大的行为改变。所以一个无规范化的网络可以使用大的权重来学习包含训练数据中的噪声的大量信息的复杂模型。简言之,规范化网络受限于根据训练数据中常⻅的模式来构造相对简单的模型,而能够抵抗训练数据中的噪声的特性影响。我们的想法就是这可以让我们的网络对看到的现象进行真实的学习,并能够根据已经学到的知识更好地进行泛化。

第一,确定两种解释中哪个“更加简单”其实是一件相当微妙的工作。
第二,即使我们可以做出这样一个判断,简单性也是一个使用时需要相当小心的指导!
第三,对模型真正的测试不是简单性,而是它在新场景中对新的活动中的预测能力。

拥有 100 个隐藏元的网络会有接近80,000 个参数。我们的训练集仅仅有 50,000 幅图像。这好像是用一个 80,000 阶的多项式来拟合50,000 个数据点。我们的网络肯定会过度拟合得很严重。但是,这样的网络实际上却泛化得很好。为什么?这一点并没有很好地理解。这里有个猜想:梯度下降学习的动态有一种自规范化的效应。

规范化没有限制偏置?
实践看来,做出这样的调整并不会对结果改变太多,所以,在某种程度上,对不对偏置进行规范化其实就是一种习惯了。然而,需要注意的是,有一个大的偏置并不会像大的权重那样会让神经元对输入太过敏感。所以我们不需要对大的偏置所带来的学习训练数据的噪声太过担心。同时,允许大的偏置能够让网络更加灵活 —— 因为,大的偏置让神经元更加容易饱和,这有时候是我们所要达到的效果。所以,我们通常不会对偏置进行规范化。

关于代价函数

代价函数在我们的网络中扮演了两种不同的⻆色。
明显的⻆色就是代价是输出激活值 a 和目标输出 y 差距优劣的度量。
另一个角色就是,不同的代价函数,输出误差的形式就不同。例如交叉熵函数的输出误差为δL=aLy

关于调节神经网络的超参数

在使用神经网络解决问题时,寻找好的超参数(如学习率,规范化参数)其实是很困难的一件事。
因为如果网络较大,或者训练数据较多,那么一次训练可能要几个小时甚至几天几周,最终什么都没有获得。
宽泛策略:也就是说达到比随机的情况要好的结果。
例如MNIST分类问题,开始可以丢弃除了0和1以外的那些图像,这样实验起来更快;还可以通过简化网络来加速实验,如选择【784,10】网络,而不是【784,30,10】;还可以通过提高监控的频率获得加速(监控运行过程中,而不是只监控每次迭代的结果),这样可以加快实验其他超参数。
10个隐藏层调整学习率和规则化参数后,然后实验20个隐藏层的情况。每一步使用验证集评价性能来找到越来越好的超参数。
所以在前期,应该从试验中尽可能早的获得快速反馈。
学习率
好的策略就是开始时使用稍微大点儿的学习率,然后随着训练的进行,再减小学习率的大小。
首先,我们选择在训练数据上的代价立即开始下降而非震荡或者增加时作为 η 的阈值的估计。比如从 η=0.01 开始,代价在训练的前面若干回合已经开始下降了,那么接着尝试 η=0.1,1.0,10,... ,直到找到一个合适的值使得在开始若干回合代价就开始震荡或者增加。相反,如果代价在 η=0.01 时就开始震荡或者增加,那就尝试 η=0.001,0.0001,... 直到你找到代价在开始回合就下降的设定。按照这种方法,可以掌握学习速率阈值量级的估计。
实际上, η 实际值不应该比阈值大。如果 η 的值重复使用很多回合的话,应该使用稍微小一点的值,例如阈值的一半。这样能够训练更多回合,不会减慢学习速度。
为什么使用代价函数选择学习率?不是应该通过验证集来确定超参数吗?
实际上,应该用验证集选择规范化超参数,小批量数据大小,神经网络层数和隐藏层个数这些超参数。但是学习速率只是偶然影响最终分类准确率。学习速率目的是控制梯度下降的步长,而监控代价是最好的检测步长过大的方法。而且在学习前期,如果验证准确率提升了,那么训练代价通常都在下降。
dropout确定迭代期数量
每个回合的最后,我们都要计算验证集的分类准确率。当准确率不再提升,就终止。但如果准确率刚开始下降就终止就会错过更好的选择。应该等准确率一段时间或者几个回合不提升了再终止。可以在初始阶段使用10个回合,然后逐步选择更久的回合。
学习速率的调整
采用可变的学习速率更加有效。
最好是使用一个较大的学习速率让权重变化得更快。越往后,我们可以降低学习速率。
保持学习速率为一个常量直到验证准确率开始变差,然后按照某个量下降学习速率,重复若干次,直到学习速率是初始值的1/1024(或者1/1000)。那时就终止。
规范化参数
开始时不包含规范化参数(即 λ=0 ),确定 η 的值,使用确定的 η 的值,我们再使用验证集选择更好的 λ
尝试从 λ=1.0 开始,根据验证集性能按照10增加或减少,一旦我们找到一个好的量级,你就可以改进 λ 的值。然后再重新优化 η
小批量数据大小
更大的小批量数据还是能够显著地加速训练。
数据太小,不会用上很好的矩阵库进行快速计算;
数据太大,不能够足够频繁地更新权重。
所以要选择一个折衷的值,才可以最大化学习速度。
小批量数据大小的选择其实是相对独立的一个超参数,不需要优化那些参数来寻找好的小批量数据大小。
所以其他参数选择可以接受的值(不需要最优),然后进行不同小批量数据大小的尝试,通过验证集的准确率随时间的变化图,选择那个得到最快性能提升的小批量数据的大小。得到了小批量数据大小,也就可以对其他的超参数进行优化了。
自动技术
网格搜索(grid search),可以系统化地对超参数的参数空间的网格进行搜索。

调参总结
实践中,超参数之间存在着很多关系。你可能使用 η 进行试验,发现效果不错,然后去优化 λ,发现这里又对 η 混在一起了。在实践中,一般是来回往复进行的,最终逐步地选择到好的值。
超参数优化就不是一个已经被完全解决的问题。总有一些技巧能够尝试着来提升性能。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值