)
目录标题一、增加层数和增加一层的神经元区别二、梯度消失/爆炸三、参数优化SGD缺点Momentum(动量法)和学习衰减率1 SGD的缺点2 Momentum(动量法)第一步算出 \(v_3\)第二步把 \(v_2\) 展开第三步化简整理第四步参数更新 核心规律总结看透本质3 Momentum(动量法) 代码实现4 学习衰减率四、Momentum和学习衰减率1. 为什么 Momentum 容易“冲过头”2. 学习率衰减是如何“踩刹车”的3. 除了防止“冲过头”学习率衰减还有别的作用 总结一下一、增加层数和增加一层的神经元区别增加神经元是“变宽”增加层数是“变深”。增加一层的神经元让网络“变宽”作用和局限作用能提取更多种类的特征。如果16个神经元只能提取16种线条比如横、竖、斜那么100个神经元就能提取100种不同的局部纹理。它能让模型在同一个抽象层次上看得更细。局限致命弱点它无法学习组合特征。比如它能轻易识别出“一条横线”和“一个圆圈”但如果要识别“眼睛”其实是横线圆圈弧线组合单层宽网络就非常吃力。因为它只有一层无法把底层特征组合成高层特征。增加层数让网络“变深”作用和优势为什么现在流行深度学习特征组合核心优势深层网络可以实现层级特征提取。第1层识别边角、线条。第2层把线条组合成眼睛、鼻子。第3层把眼睛鼻子组合成人脸。非线性表达能力极强理论上只要有足够的层数即使每一层的神经元数量很少比如只有16个也能拟合极其复杂的函数。这就是所谓的“深度”的力量。假设我们要处理 784 个输入10 个输出。方案 A单层宽网络784 - 256 - 10参数量 784 ∗ 256 256 ∗ 10 203 , 264 784*256 256*10 203,264784∗256256∗10203,264方案 B多层深网络784 - 16 - 16 - 16 - 10参数量 784 ∗ 16 16 ∗ 16 16 ∗ 16 16 ∗ 10 12 , 544 256 256 160 13 , 216 784*16 16*16 16*16 16*10 12,544 256 256 160 13,216784∗1616∗1616∗1616∗1012,54425625616013,216看到了吗方案 B多层深网络的参数量只有方案 A 的十五分之一但它能学习到的复杂特征组合能力远超方案 A深度学习由此而来当神经网络的层数加深时往往可以有效地提高识别精度特别是对于大规模的复杂问题通常都需要用更多的层来分层次传递信息而且可以有效减少网络的参数数量从而使得学习更加高效。使用深度神经网络进行的学习就被称为 深度学习Deep Learning。ILSVRC 是近年来机器视觉领域最受追捧且最具权威的学术竞赛之一代表了图像领域的最高水平。它包含多个测试项目其中最有名的就是“类别分类”Classification该项目会进行 1000 个类别的分类比试识别精度。自从 2012 年以后的 ILSVRC 比赛优胜队伍采用的方法基本上都是以深度学习为基础的。可以说深度学习代表了目前人工智能领域的发展方向正以超乎想象的速度发展并改变我们的生活二、梯度消失/爆炸在某些神经网络中随着网络深度的增加梯度在隐藏层反向传播时倾向于变小。这就意味着前面隐藏层中的神经元要比后面的学习起来更慢。这种现象被称为“梯度消失”。与之对应如果我们进行一些特殊的调整比如初始权重很大可以让梯度反向传播时不会明显减小从而解决梯度消失的问题然而这样一来前面层的梯度又会变得非常大引起网络不稳定无法再从训练数据中学习。这种现象被称为“梯度爆炸”。基于梯度学习的深度神经网络中梯度本身是不稳定的前面层中的梯度可能“消失”也可能“爆炸”。对于梯度消失和梯度爆炸一个容易理解的解释是当反向传播进行很多层的时候每一层都对前一层梯度乘以了一个系数因此当这个系数比较小小于 1时越往前传递梯度就会越小、训练越慢导致梯度消失而如果这个系数比较大则越往前传递梯度就会越大导致梯度爆炸。所以深度神经网络的训练是比较复杂的会有一系列的问题。研究表明激活函数的选择、权重的初始化甚至学习算法的实现方式都是影响因素另外网络的架构和其它一些超参数也有重要影响。为了让深度神经网络的学习更加稳定、高效我们需要考虑进一步改进寻找最优参数的方法以及如何设置参数初始值、如何设定超参数此外还应该解决过拟合的问题。三、参数优化SGD缺点Momentum(动量法)和学习衰减率对于深度神经网络的学习之前更新参数的方法是随机梯度下降法SGD。这种方法比较简单也非常经典但在很多具体问题中并不是最高效的。1 SGD的缺点SGD的更新方式可以写为W ← W − η ∂ L ∂ W W \leftarrow W - \eta \frac{\partial L}{\partial W}W←W−η∂W∂L这里 W 是要更新的权重参数矩阵损失函数 L 关于 W 的梯度就是 (\frac{\partial L}{\partial W}) 而 (\eta) 表示 学习率。我们可以将 SGD 单独包装成一个类classSGD:def__init__(self,lr0.01):self.lrlr#参数更新传入参数字典和梯度字典defupdate(self,params,grads):#遍历传入所有参数按照公式更新forkeyinparams.keys():params[key]-self.lr*grads[key]SGD 有以下问题局部最优解陷入局部最优尤其在非凸函数中难以找到全局最优解。鞍点陷入鞍点梯度为 0导致训练停滞。收敛速度慢高维或非凸函数中收敛速度较慢。学习率选择学习率过大导致震荡或不收敛过小则收敛速度慢。2 Momentum(动量法)原始的梯度下降法直接使用当前梯度来更新参数W ← W − η ∇ W \leftarrow W - \eta \nablaW←W−η∇而 Momentum动量法会保存历史梯度并给予一定的权重使其也参与到参数更新中v ← α v − η ∇ v \leftarrow \alpha v - \eta \nablav←αv−η∇W ← W v W \leftarrow W vW←Wv(v)历史负梯度的加权和(\alpha)历史梯度的权重(\nabla)当前梯度即 (\frac{\partial L}{\partial W})(\eta)学习率公式拆解v ← α v − η ∇ v \leftarrow \alpha v - \eta \nablav←αv−η∇这个公式是 Momentum动量法的核心更新步骤之一意思是“计算当前的动量 (v)”( v (v(v)等号左边表示当前这一步计算出的动量也可以理解为带有惯性的更新方向。( α (\alpha(α)阿尔法读作 alpha是动量系数通常取 0.9 左右。它决定了“以前的动量”保留多少。( v (v(v)等号右边表示上一步的动量。( η (\eta(η)伊塔学习率。( ∇ (\nabla(∇)纳布拉当前计算出来的梯度。( ← (\leftarrow(←)赋值符号表示把等号右边的计算结果更新给左边的 (v)。这个公式的大白话意思是当前的动量 上一步的动量乘以一个衰减系数(\alpha) - 当前的学习率乘以当前的梯度。这就好比给小球下山加上了“惯性”。公式带入推导在推导这个公式第一行( v 1 − η ∇ 1 (v_1 -\eta \nabla_1(v1−η∇1) 这是第一步的动量只和当前梯度有关第二行( v 2 α v 1 − η ∇ 2 (v_2 \alpha v_1 - \eta \nabla_2(v2αv1−η∇2) 这是第二步的动量用到了上一步的动量 (v_1) 和当前的梯度 (\nabla_2)第三行 计算复杂点一步步来看第一步算出 (v_3)根据动量公式当前的 (v_3) 等于上一步的动量 (v_2) 乘以 (\alpha)再减去当前梯度带来的影响v 3 α v 2 − η ∇ 3 v_3 \alpha v_2 - \eta \nabla_3v3αv2−η∇3第二步把 (v_2) 展开我们把上一步推导出的( v 2 α ( − η ∇ 1 ) − η ∇ 2 (v_2 \alpha(-\eta \nabla_1) - \eta \nabla_2(v2α(−η∇1)−η∇2) 代入到上面的( v 3 (v_3(v3) 公式中v 3 α [ α ( − η ∇ 1 ) − η ∇ 2 ] − η ∇ 3 v_3 \alpha \Big[ \alpha(-\eta \nabla_1) - \eta \nabla_2 \Big] - \eta \nabla_3v3α[α(−η∇1)−η∇2]−η∇3第三步化简整理把外面的( α (\alpha(α) 乘进去就可以得到类似图片手写风格的最长展开式v 3 − α 2 η ∇ 1 − α η ∇ 2 − η ∇ 3 v_3 -\alpha^2 \eta \nabla_1 - \alpha \eta \nabla_2 - \eta \nabla_3v3−α2η∇1−αη∇2−η∇3第四步参数更新最后计算出( v 3 (v_3(v3) 之后用来更新权重( W (W(W)这是实际改变神经网络参数的步骤W ← W v 3 W \leftarrow W v_3W←Wv3或者写成更完整的形式W ← W − α 2 η ∇ 1 − α η ∇ 2 − η ∇ 3 W \leftarrow W - \alpha^2 \eta \nabla_1 - \alpha \eta \nabla_2 - \eta \nabla_3W←W−α2η∇1−αη∇2−η∇3 核心规律总结看透本质如果你观察上面化简后的式子会发现一个非常明显的规律( v 1 (v_1(v1) 包含了( ∇ 1 (\nabla_1(∇1)( v 2 (v_2(v2) 包含了( − α η ∇ 1 − η ∇ 2 (-\alpha \eta \nabla_1 - \eta \nabla_2(−αη∇1−η∇2)( v 3 (v_3(v3) 包含了( − α 2 η ∇ 1 − α η ∇ 2 − η ∇ 3 (-\alpha^2 \eta \nabla_1 - \alpha \eta \nabla_2 - \eta \nabla_3(−α2η∇1−αη∇2−η∇3)这就把“动量”的物理意义完全展现出来了越靠近当前的梯度比如( ∇ 3 (\nabla_3(∇3)权重最大系数是( − η (-\eta(−η)越久远的梯度比如( ∇ 1 (\nabla_1(∇1)由于每次都要乘以一个小于1的( α (\alpha(α)通常是0.9它的影响就会被不断衰减系数变成了( − α 2 η (-\alpha^2 \eta(−α2η)。就像滚雪球一样最近的方向影响最大老的方向虽然还在但影响力越来越小从而保证了优化的稳定性和速度。动量法有时能够减缓优化过程中的震荡加快优化的速度。因为其会累计历史梯度也可以有效避免鞍点问题。3 Momentum(动量法) 代码实现# 动量法classMomentum:# 初始化def__init__(self,lr0.01,momentum0.9):self.lrlr self.momentummomentum self.vNone# 历史负梯度的加权和# 更新方法defupdate(self,params,grads):# 对v进行初始化ifself.visNone:self.v{}forkey,valinparams.items():self.v[key]np.zeros_like(val)# 按照公式进行参数更新forkeyinparams.keys():self.v[key]self.momentum*self.v[key]-self.lr*grads[key]params[key]self.v[key]4 学习衰减率深度学习模型训练中调整最频繁的当属学习率好的学习率可以使模型逐渐收敛并获得更好的精度。较大的学习率可以加快收敛速度但可能在最优解附近震荡或不收敛较小的学习率可以提高收敛的精度但训练速度慢。学习率衰减是一种平衡策略初期使用较大学习率快速接近最优解后期逐渐减小学习率使参数更稳定地收敛到最优解。1等间隔衰减每隔固定的训练周期epoch学习率按一定的比例下降也称为“步长衰减”。例如使学习率每隔 20 epoch 衰减为之前的 0.72指定间隔衰减在指定的 epoch让学习率按照一定的系数衰减。例如使学习率在 epoch 达到 [10, 50, 200] 时衰减为之前的 0.73指数衰减学习率按照指数函数 (f(x) a^x, a 1) 进行衰减。例如使学习率以 0.99 为底数epoch 为指数衰减四、Momentum和学习衰减率1. 为什么 Momentum 容易“冲过头”Momentum动量法的核心思想是**“惯性”**就像滚雪球。在训练初期这种惯性非常好它能帮助模型加速冲出平坦区域逃离鞍点快速向最优解靠近。但是当模型快要接近最优解谷底时因为积攒了很大的“动量”速度很快它往往刹不住车会直接冲过谷底跑到对面坡上然后再冲回来。这就会导致在最优解附近剧烈震荡甚至永远停不下来。2. 学习率衰减是如何“踩刹车”的学习率(\eta)决定了每次参数更新的“步长”。学习率衰减的策略是一开始步子迈大点快到终点时步子迈小点。初期大学习率配合 Momentum 的惯性快速逼近最优解。后期小学习率当模型接近最优解时学习率已经衰减得很小了。此时虽然 Momentum 依然有惯性但由于基础步长学习率变得极小哪怕有惯性每次移动的距离也会变得非常短。这就相当于给狂奔的雪球换上了一个极小极小的轮子强迫它慢慢停下来从而稳定地收敛到最优解。3. 除了防止“冲过头”学习率衰减还有别的作用提高精度如果一直保持大学习率模型可能只能在最优解附近的一个“大圈”里打转无法真正进入最底部。衰减后的小学习率能让模型钻进更精细的“小坑”里获得更高的精度。逃离局部最优早期早期的大学习率加上 Momentum 的惯性能有效防止模型一开始就卡在某个局部最优的小坑里。 总结一下Momentum解决的是训练太慢、在平坦区域走不动、容易卡在鞍点的问题相当于踩油门。学习率衰减解决的是训练后期在最优解附近震荡、无法精确收敛的问题相当于踩刹车。它们经常一起使用。比如在深度学习框架中我们常常同时设置Momentum0.9和一个StepLR每隔多少轮学习率打个折这就是最经典的“油门配刹车”组合。