文章目录
- 类神经网络优化技巧
-
- [局部最小值local minima 与 鞍点saddle point](#局部最小值local minima 与 鞍点saddle point)
-
- [Saddle Point 的情况更常见](#Saddle Point 的情况更常见)
- [Tips for training:Batch and Momentum](#Tips for training:Batch and Momentum)
-
- [Small Batch vs Large Batch](#Small Batch vs Large Batch)
-
- [回顾:optimization优化 找到参数使L最小](#回顾:optimization优化 找到参数使L最小)
- 问题:为什么要用Batch,Batch对训练的帮助
-
- [考虑并行计算:不同batch size的消耗](#考虑并行计算:不同batch size的消耗)
- noisy的gradient可以帮助训练
- [Momentum(动量):对抗local minima](#Momentum(动量):对抗local minima)
-
- [求 σ \sigma σ的一种常见方法:Root Mean Square均方根](#求 σ \sigma σ的一种常见方法:Root Mean Square均方根)
- [另外一种方法:RMSProp 调整当前步梯度与历史梯度的重要性](#另外一种方法:RMSProp 调整当前步梯度与历史梯度的重要性)
- [Learning Rate Scheduling => 让 η \eta η与训练时间有关](#Learning Rate Scheduling => 让 η \eta η与训练时间有关)
-
- [最常见的策略:Learning Rate Decay](#最常见的策略:Learning Rate Decay)
- [策略2(黑科技):Warm Up](#策略2(黑科技):Warm Up)
- Optimization的总结
笔记内容对应视频章节
类神经网络优化技巧
本章介绍的优化思路是:当Error Surface
非常崎岖时,我们需要比较好的方法做optimization
=> 我们怎么走才能走得更好
下一次的优化思路是:将Error Surface
铲平 => 让路更好走,更好训练
局部最小值local minima 与 鞍点saddle point
主题:讨论在Optimization时怎么把gradient descent做得更好
问题: 为什么Optimization的时候会失败?
情况1: 发现deep network没有比linear model、比较shallow network做得更好,所以对loss不满意。
情况2: 模型训练不出来,不管怎么更新参数loss都不降低
猜想: 参数对loss的微分(gradient梯度)为0,Gradient descent
不会再更新参数了,训练停止,loss也不会再下降了。
=> 局部最小值local minima
和鞍点saddle point
统称为critical point
关键点,critical point
都可能导致gradient=0
如何确定是local minima还是saddle point导致梯度接近0
这里推荐B站的国防科技大学高数教程,这部分在多元函数的极值
问题 :假设因为critical point
导致gradient
接近0,如何确定时local minima
还是saddle point
- 如果卡在
local minima
,那么暂时没有路可以走了,因为四周都比该点的loss高 - 如果卡在
saddle point
,saddle point
周围存在比该点loss更低的点
假设给定参数 θ ′ \theta' θ′,在其附近的loss function可以表示为 L ( θ ) ≈ L ( θ ′ ) + ( θ − θ ′ ) T g + 1 2 ( θ − θ ′ ) T H ( θ − θ ′ ) L(\theta) \approx L(\theta') + (\theta-\theta')^Tg+\frac{1}{2}(\theta-\theta')^TH(\theta-\theta') L(θ)≈L(θ′)+(θ−θ′)Tg+21(θ−θ′)TH(θ−θ′)(tayler series approximation)
右边的式子是 θ ′ \theta' θ′某领域内 θ \theta θ的函数值 L ( θ ) L(\theta) L(θ)的近似计算公式,目的是用更高的精确度去逼近函数 L ( θ ) L(\theta) L(θ)
如果走到了critical point
(驻点或稳定点),梯度为0,右边第二项结果为0
=> L ( θ ) ≈ L ( θ ′ ) + 1 2 ( θ − θ ′ ) T H ( θ − θ ′ ) L(\theta) \approx L(\theta') +\frac{1}{2}(\theta-\theta')^TH(\theta-\theta') L(θ)≈L(θ′)+21(θ−θ′)TH(θ−θ′)
- 如果Hessian正定,则 θ ′ \theta' θ′为极小值点
- 如果Hessian负定,则 θ ′ \theta' θ′为极大值点
- 如果Hessian不定,则 θ ′ \theta' θ′为鞍点
如果发现卡住的地方 θ ′ \theta' θ′为鞍点,说明loss还可以下降 => 利用H的特征向量确定参数的更新方向
u ⃗ \vec{u} u 为H的特征向量, λ \lambda λ为 u ⃗ \vec{u} u 的特征值, 在 θ ′ \theta' θ′的位置加上 u ⃗ \vec{u} u ,沿著 u ⃗ \vec{u} u 的方向做update得到 θ \theta θ,新的 θ \theta θ可以0让loss变小。
但由于需要算H需要求特征值特征向量,实际上很少采用这种方法逃离Saddle point
Saddle Point 的情况更常见
直觉:在一维中是Local Minima的点,在二维上,该点会不会是鞍点?
经验:Loss在一个维度很高的空间中,往往只会遇到鞍点而几乎不会遇到局部极小值点
Tips for training:Batch and Momentum
Small Batch vs Large Batch
回顾:optimization优化 找到参数使L最小
第一讲中,我们在构建模型的第三步optimization优化,找到参数使L最小。
实际上, 不会一次性将全部数据用于训练一个L,而是将全部资料分成n个batch(这里的n也是一个超参数)去训练n个L。
shuffle:1个epoch之后,会重新再分一次Batch,所以每轮的Batch不是完全一样。
问题:为什么要用Batch,Batch对训练的帮助
假设有20笔资料
- 左边需要看完所有资料更新一次参数,每次更新参数需要花费时间长,但参数更新结果比较精确。
- 右边一个样本就更新一次参数,每次更新参数的时间短, 用一笔资料算出来的 Loss,显然是比较 Noisy 的,所以 Update 的方向是曲折的 。
直觉上我们认为大batch size更新一次参数的时间 > 小batch size更新一次参数的时间
考虑并行计算:不同batch size的消耗
batch size大的不一定比小的batch size花的时间长,由于可以并行运算,即使需要一次看20笔资料,也可以并形成20个1笔
现象:
- Batch Size 是从1到1000,所需要的时间几乎是一样的,
- 增加到 10000,乃至增加到60000的时候,一个 Batch所要耗费的时间,确实有随着 Batch Size 的增加而逐渐增长
原因:
- 有 GPU,可以做并行运算,所以1000笔资料所花的时间,并不是一笔资料的1000倍
- GPU 平行运算的能力还是有它的极限,当你的 Batch Size 真的非常非常巨大的时候,GPU 在跑完一个 Batch,计算出 Gradient 所花费的时间,还是会随著 Batch Size 的增加,而逐渐增长
总时间:
由于可以并行计算。
实际上,小 Batch Size 跑完一个 Epoch(更新20次参数)的时间 > 大 Batch Size 跑完一个epoch的时间。
noisy的gradient可以帮助训练
发现batch size 越大,验证的正确率越差 => Optimization优化的问题
结论1:为什么小batch size会在traning set上得到比较好的结果?为什么noisy的update、noisy的gradient会在训练时得到较好的结果。
解释:不同的Batch 求得的Loss略有差异,可以避免局部极小值"卡住"
结论2: 为什么小的batch size对testing有帮助?
解释:这个解释不一定权威?
假设在training loss上存在多个local minima,local minima也有好坏之分
- 坏的local minima在峡谷里(尖锐最小值)
- 好的local minima在平原上(平坦最小值)
假设training loss 和 testing loss存在mismatch(可能training跟testing的distribution不一样,也可能是其他原因)
- 对于平坦最小值来说,在training和testing上的结果不会相差太大
- 对于尖锐最小值来说,在training和testing上的结果相差太大
大的batch size倾向于走到峡谷里,小的batch size倾向于走到盆地里
总结:BatchSize是一个需要调整的参数,它会影响训练速度与优化效果。
Momentum(动量):对抗local minima
假设Error Surface
误差曲线(loss 曲线)是一个真正的斜坡,参数是一个球。将球从斜坡上滚下来。Gradient Descent
会在Local Minima
和Saddle Point
处停住。但在真实世界,由于惯性,球会一直滚。
问题 :是否可以将真实世界的概念融入到Gradient Descent
里?
复习:一般的Gradient Descent
参数移动方法说明:梯度的方向是函数值增加最快的方向,那么梯度的反方向是函数值减少最快的方向,所以我们要往反方向更新参数
Gradient Descent + Momentum
解读方向1:动量(新移动的方向) = 前一步Update
的方向 + 梯度的反方向
解读方向2:当前n的动量=之前算出来(n-1)个gradient的weighted sum
Adaptive Learning Rate 自动调整学习率技术
技术核心:给每一个参数不同的Learning Rate
问题引入
训练的时候很少卡在Critical point :Critical point
不是训练过程中最大的阻碍
现象1 :训练停滞(Loss不再下降)不一定是梯度很小导致的
现象2 : 如果参数使用固定的学习率,即使是在凸面体的优化,都会让优化的过程非常困难 ⇒ 不同的参数需要不同的学习率
客制化的Learning Rate
原则
- 某个方向gradient的值很小(平坦),learning rate调大一点,这样可以移动的远一点
- 某个方向gradient的值很大(陡峭),learning rate调小一点,这样可以移动的近一点
做法
案例只放某一个参数update的式子。
假设有一个参数 θ i \theta_i θi,i用来标识是哪一个参数,在第t次更新时值为 θ i t \theta_i^t θit。
求 σ \sigma σ的一种常见方法:Root Mean Square均方根
对本次的梯度及之前算出每一次更新的梯度求均方根
缺陷:同一个参数的learning rate需要随着时间而改变,该方法不能实时考虑梯度的变化情况
另外一种方法:RMSProp 调整当前步梯度与历史梯度的重要性
在RMS里面, σ \sigma σ的值取本次及历史梯度的均方值,说明每一个梯度同等重要。
在RMSProp添加参数 α \alpha α( α \alpha α是一个超参数,不随迭代变化),越大说明过去的梯度信息更重要
- α设很小趋近於0,就代表这一步算出的$ g_i $相较於之前所算出来的gradient而言比较重要
- α设很大趋近於1,就代表现在算出来的$ g_i $比较不重要,之前算出来的gradient比较重要
RMSProp方法比之前的RMS方法灵敏度更高,对梯度的变化敏感
最常见optimization的策略:Adam = RMSProp + Momentum
代码中直接引入Adam,使用Pytorch中预设的参数就能够得到比较好的结果。
Learning Rate Scheduling => 让 η \eta η与训练时间有关
加上Adaptive Learning Rate
之后上述案例的训练过程
最常见的策略:Learning Rate Decay
核心 :让 η \eta η和训练时间有关,而不是一个常量
思路 :随着时间进行,让 η \eta η越来越小, η t \eta^t ηt
开始训练的时候离终点很远,随着参数不断update
,距离终点越来越近,减小learning rate
,让参数的更新慢下来
策略2(黑科技):Warm Up
思路 : η \eta η先变大后变小
变到多大,变小的速率怎么样,这些都是超参数,需要手动调整
解释
σ \sigma σ指示某一个方向它到底有多陡/多平滑,这是一个统计的结果,要看得够多笔数据以后才精准,所以一开始我们的统计是不精准。
一开始learning rate比较小,是让它探索收集一些有关error surface的情报 ,在这一阶段使用较小的 η \eta η,限制参数不会走的离初始的地方太远
等到 σ \sigma σ统计得比较精准以后再让 η \eta η慢慢爬升。
Optimization的总结
原始梯度下降的方法 : θ i t + 1 \theta_i^{t+1} θit+1 <- θ i t − η g i t \theta_i^t - \eta g_i^t θit−ηgit
优化后的方法 : θ i t + 1 \theta_i^{t+1} θit+1 <- θ i t − η t σ i t m i t \theta_i^t - \frac{\eta^t}{\sigma_i^t} m_i^t θit−σitηtmit
优化 | 原来的做法 | 优化后的做法 | 公式 | 作用 |
---|---|---|---|---|
更新update的方向:Momentum |
沿着逆梯度的方法更新参数 | $ m_i^t = $ 前一步Update 的方向 + 梯度的反方向 |
m i t = λ m i t − 1 − η g t − 1 m_i^t=\lambda{m_i^{t-1}}-\eta{g^{t-1}} mit=λmit−1−ηgt−1 | 为了增加历史的惯性 |
update的步伐 | 学习效率 η \eta η | 不同的参数需要不同的学习效率 σ i t \sigma_i^t σit | RMS、RMSProp、不同的方法计算不一样 | 缓和步伐的大小,让步伐的变化效果受梯度的影响 |
Learning rate scheduling | 学习效率 η \eta η | 学习效率 η t \eta^t ηt | 本章介绍了:Warm Up 与Learning Rate Decay |
让 η \eta η和训练时间有关,而不是一个常量 |
说明
- Momentum是将梯度加起来,所以Momentum有考虑方向。
- σ \sigma σ计算时,由于梯度取了平方,所以只考虑梯度的大小并不考虑梯度的方向。
- λ \lambda λ是一个超参数。