1. RMSprop 算法
在上一部分中,我们通过 Momentum 解决了“方向震荡”的问题:
它利用 EMA 平滑梯度的方向,让模型在主方向上走得更快,在乱方向上走得更稳。
但这时,其实还有一个问题没解决:
不同参数的梯度幅度差异巨大,导致统一学习率无法同时适应所有参数。
这句话是什么意思?我们开始展开阐述:
1.1 参数间的梯度差异现象
在训练神经网络时,我们希望通过梯度下降不断更新参数:
但实际运行中会存在一种很难发现的问题,因为它并不明显,而是隐藏在传播内部:
不同参数的梯度幅度差异巨大,导致统一学习率无法同时适应所有参数。
造成这种现象的原因大致有以下几类:
不同输入特征的“数值范围”不同。
接近输入层的梯度更容易变小。
偏置与权重的梯度规模天然不同。
我们用几个实例来理解一下这种现象:
(1)输入特征的数值范围差异造成梯度差异
我们来看一组线性组合:
现在假设:
的范围是 1~10
的范围只有 0.0001~0.001
我们知道:
权重的梯度和输入成正相关
也就是说,量级较小的输入一定会得到量级较小的梯度。
因此就可能得到以下梯度:
可以发现:两者差了上万倍。
这时,对二者应用统一学习率就会出现:
梯度大的参数更新飞快,容易发散
梯度小的参数几乎不动
在这种情况下,如果
反而是核心特征,那这个参数的梯度消失是不是就严重阻碍了拟合?
虽然但是,实际上,我们之前就已经介绍了这种问题的解决方法,那就是归一化。
我们之前就介绍过,归一化在保持特征信息的同时消除上面提到的量纲差距。
我们用之前学到标准化再次处理这个例子看看:
假设我们对输入做了标准化,将两项输入都转化为均值 0、方差 1 的数据:
标准化后的
分布在
附近
标准化后的
也分布在
附近
此时,两者的尺度不再相差上万倍,重新计算梯度:
这两个梯度的量级已经处于同一数量级,这样一来:
用统一学习率更新时不再一快一慢
所有参数都能被“公平地”学习
梯度不再因为输入值差异而畸形缩小或放大
可以看到,归一化确实解决了“输入尺度不同 → 梯度差异巨大”的问题。
那RMSprop是不是还没出现就没用了?不至于不至于。
因为,归一化只能解决输入特征量级差别导致的梯度差异,而梯度差异不只来自输入数据的尺度,还来自网络结构与梯度自身的性质。
我们继续看下面几个例子:
(2)网络中层级间的梯度差异
我们用最简单的举例,假如现在有这样一个逻辑回归网络:
而我们知道,在多层网络结构中,梯度的计算是通过链式法则来传递的,而经过从后向前的层层相乘,网络中靠前层的参数梯度和靠后层的参数梯度就会出现较大差异。
在这种情况下,我们假定这样一个可能的梯度情况:
(靠近输入层,梯度很小)
(靠近输出层,梯度较大)
差距可能超过几千倍。
这时,对二者应用统一学习率就会出现:
梯度大的层更新快,甚至梯度爆炸
梯度小的层更新慢,可能几乎不动,梯度消失。
模型整体收敛受阻,尤其前层学习慢会影响特征提取
那这时候就需要 RMSProp 登场了?还得等等。
回想一下,针对这种层层传播导致的梯度差异,我们是不是还介绍了一种技术,叫权重初始化?
权重初始化即通过控制权重的方差,让信号方差保持恒定,这样既避免了梯度爆炸,又避免了梯度消失。
可是,权重初始化可以像归一化解决输入数据差异一样完全解决层间传播差异吗?
很可惜答案是不能,我们再展开一下:
权重初始化(如 Xavier/He 等)的主要目的是:控制信号方差在前向传播时不爆炸或消失这样可以保证前向传播的输出方差大致和输入方差相当,避免信号在网络中逐层放大或缩小。
而我们刚刚又提过,反向传播的梯度是链式相乘的,如果每一层权重方差合适,梯度也能大致保持稳定,所以权重初始化可以降低深层网络训练早期出现梯度爆炸或消失的概率。
这是权重初始化能起到的正面效果,现在我们来看看它的不足之处,即为什么权重初始化不能完全保证训练中梯度恒定?
梯度依赖于训练中的权重:初始化只是训练的起点,随着迭代,权重会不断更新,可能偏离初始分布,如果权重变得过大或过小,梯度仍可能出现爆炸或消失。
非线性激活函数的影响:ReLU、sigmoid、tanh 等激活函数会改变信号方差,例如 sigmoid 的输出在饱和区,梯度几乎为零。因此,即便初始化合适,深层网络仍可能出现梯度消失。
梯度放大或缩小的累积效应始终存在:链式法则让每层梯度相乘,当网络很深时,即便每层梯度稍微偏大或偏小,累积起来也会导致前层梯度消失或爆炸。
因此,针对层间的梯度差异现象,我们仍需要解决方法。
(3)权重梯度和偏置梯度的天然规模差异
在我们现在所学的内容里,我们知道:
也就是说,权重梯度取决于输入
,偏置梯度只与误差相关。
因此,就可能出现这种情况:
偏置更新会慢很多,因此,同一个学习率也不适合它们俩。
而这种梯度性质本身导致的差异,我们目前还不知道怎么处理。
1.2 RMSprop 算法
经过上面一大段的铺垫,我们已经知道了“不同参数的梯度幅度差异巨大,导致统一学习率无法同时适应所有参数” 这句话的含义。
千呼万唤始出来,我们来看看RMSprop 算法是如何解决这个问题的。
RMSProp(Root Mean Square Propagation)提出了按参数自适应调整梯度的思路,它的核心目标是:对梯度小的参数放大步长,让它们加快学习;对梯度大的参数缩小步长,避免爆炸。
现在来详细展开一下:
(1)梯度平方的指数加权平均
RMSProp 为每个参数维护一个梯度平方的EMA变量:
:
:当前梯度
:衰减因子或平滑系数,通常取 0.9
:记录梯度历史大小的“记忆”,刻画了参数梯度的量级
这一步的作用是:用历史梯度平方的平均来衡量该参数“走得快不快”。
(2)按参数自适应缩放学习率
现在的参数更新公式为:
:基础学习率
分母
:将梯度幅度大的参数步长缩小,梯度幅度小的参数步长放大
:防止除零,通常取
其核心思想是:动态缩放每个参数的步长,使得梯度大小差异不会导致更新过快或过慢。
只摆公式还是不太清晰,我们举一个实例来看看效果。
(3)RMSProp 的应用实例
我们还是用最开始的例子,来看看使用RMSProp的过程:
参数 当前梯度
历史均方
RMSProp 步长
更新量
1.2 1.44 0.01 0.012
0.00003 0.0000001 100 0.003
0.03 0.0009 1.05 0.0315
可以发现:
梯度大的
被自动“抑制”,避免发散
梯度小的
被放大,避免前层学习过慢
偏置
的更新量也被合理调节,收敛速度更统一
现在就可以看到,RMSProp 有效解决了我们之前讨论的三类梯度差异问题:
输入尺度差异(归一化+RMSProp)
层间梯度差异(权重初始化+RMSProp)
权重与偏置梯度差异(RMSProp 自适应缩放)
厉不厉害你RMSProp?
好了,最后再看看RMSProp和上一篇中Momentum的对比。
(4)RMSProp 与 Momentum 的对比
特性 Momentum RMSProp
解决问题 梯度方向震荡 参数间梯度幅度差异,步长自适应
核心机制 指数加权平均梯度方向 指数加权平均梯度平方,按参数缩放步长
适用场景 梯度方向不稳定的深层网络 梯度量级差异大或深层网络训练
学习率 全局统一 每个参数自适应
有没有发现,这两个优化算法好像并不冲突?
那我可不可以把Momentum 和 RMSProp 结合使用?
Momentum 负责加速收敛主方向
RMSProp 负责动态调节步长
那么你就得到了目前可以说是最常用的优化器:Adam 优化算法,我们下一篇就会展开介绍它。
2."人话版总结"
概念 原理 比喻
梯度差异问题 不同参数的梯度大小差别太大,同一个学习率对每个参数都不合适:有人走太快差点摔下山,有人走太慢一直原地踏步。 一群人下山,有人腿长一步五米,有人腿短一步十厘米;统一步长根本不公平。
RMSProp 的核心思想 给每个参数量身定制学习率:梯度大的 → 走慢点不摔;梯度小的 → 放大步子走快点。 给腿太长的人绑沙袋,让他慢点;给腿短的人装弹簧,让他快点。
梯度平方的 EMA 记录参数过去的“梯度大小平均值”,用来判断它平常走得快还是慢。 给每个人戴个运动手环,看他过去走路多快。
按参数缩放学习率 步长公式变成:大梯度 → 被除以大数 → 变小;小梯度 → 被除以小数 → 变大。 走太快的人车速被限速,老慢的人给他开绿色通道。
解决输入尺度差异 特征太大导致梯度大、特征太小导致梯度小 → RMSProp 自动调节。 富二代每次花钱花太快 → 限额;穷小孩花太慢 → 提额。
解决层间梯度衰减 前层梯度本来就小,RMSProp 会自动给它“放大步长”。 队伍最后的人落后太多 → RMSProp 给他上电动车。
解决权重 vs 偏置差异 偏置的梯度常常比较小 → 自动放大;权重有时很大 → 自动缩小。 偏置像个小孩 → 给他增高垫;权重像大人 → 给他减速带。
Momentum vs RMSProp Momentum 解决“方向乱”;RMSProp 解决“步子不均匀”。 Momentum = 帮你稳方向;RMSProp = 帮你调步幅。
两者能否结合? 可以,而且非常常用 → Adam = Momentum + RMSProp。 Momentum 是指南针,RMSProp 是鞋子;Adam 直接给你导航 + 智能跑鞋。