目录
回顾与引入
模型是如何更新参数的?
梯度累计
梯度累计的过程
梯度累计的好处
补充:
总结:
回顾与引入
上一节我们提到:梯度是损失函数对模型参数的偏导数,表示每个参数对损失函数的影响程度。
梯度告诉我们,在当前参数值下,如何调整参数才能减少损失函数。
梯度方向告诉我们如何调整参数才能减少损失函数L(θ)的值。
模型是如何更新参数的?
众所周知,训练模型的目的就是找到一组权重参数,使之与预测函数的拟合效果最好,使误差最小(损失函数最小)。
也就是说,我手上有一个模拟真实值的拟合函数,拟合出的结果 与 真实结果 之间存在一个误差,就是损失函数。现在我要减小误差,就是要找到损失函数的最小值。于是对损失函数求导,得到导函数,根据导函数的方向调整拟合函数的参数。
记住!!!我们调整的是拟合函数的参数,而不是调整损失函数的参数!!!(学的时候是我的误区)
请读者反复理解上面一段我尽量通俗的解释。接下来是官方的解释:
前向传播:
输入数据通过模型进行前向计算,得到预测值。计算损失函数 L(θ),衡量预测值与真实值之间的差距。 反向传播:
使用链式法则计算损失函数 LL 对每个模型参数的梯度(即偏导数)。这些梯度告诉我们在当前参数值下,如何调整参数才能减少损失。 参数更新:
根据梯度下降公式,使用梯度来更新模型参数: 我们上一节讲过它,不作解释。
我们得到两条信息:
梯度是手段:用来计算如何调整参数。参数才是目标:真正被更新的对象。
梯度累计
接下来我们便顺理成章引出梯度累计是个什么东西。
想象一下,你在考场里,卷子上有一道线代大题,解一个8元8个方程的线性方程组。已经汗流浃背了吧,虽然每一步的计算不难,但分解出的矩阵可不少,要把常数项代回D的第n行n次,你大概率会把草稿纸写满。
而你培养的模型遇见的不是一整张卷子的少元线代方程组,而是百万个具有动辄上千万个参数的方程组。(当然你的模型不会试图用克拉默法则去解,而是使用 Adam、RMSprop、Adagrad这类优化函数(优化器))
你做这道题已经要写满一页草稿纸了。GPU也一样,他也要打草稿,他除了要记住中间变量,还要记住激活值、梯度信息、优化器状态以及参数信息。
我们大脑无法同时记忆这么多内容,GPU也做不到。因此,我们不能一次给GPU投喂这么多题目(数据),你得一道一道给。
官方语言省流翻译:你显存会爆。
因此我们需要将要训练的数据拆分成一组组子集,就是划分(不交不漏)。
众所周知,误差是累计的,具有可加性,对误差求导也具有可加性。
证明如下,不赘述,你只需知道是这码事就可以了:
我们高数下学过偏导数的加法法则:
推广到多元也成立。
接着我们对 L(θ) 求θ的梯度(导数):
根据梯度算子的线性性(导数的加法法则):
看不懂没关系,我们只要知道导数具有可加性即可。
那么过程如下:
梯度累计的过程
一、先将数据拆分为子集Bi,对Bi计算局部损失函数.
二、直接计算该子集的梯度(损失函数的导数,倒三角就是F')。
三、累加子集的梯度,得到梯度累计值,再根据其方向和自定义的步长调整拟合函数的参数即可。
梯度累计的好处
呈现最重要的两条:
一、当然是解决了记忆不足的问题(显存有限)。
二、而梯度累计可以模拟大批量(large batch)训练的效果。累计 N 个小批量的梯度后更新,等效于直接用批量B×N 训练。
补充:
解析解与数值解是什么?
解析解:找到一组参数正好使等式成立。 省流:你能手搓出解。
数值解:找到一组参数尽量使式子和源式的拟合程度最好(损失函数取得最小值)。 省流:你手搓不出解。
总结:
〇 训练模型的目的:找到一组权重参数,使之与预测函数的拟合效果最好,使误差最小(损失函数最小)。
Ⅰ参数更新的过程:求损失函数,对损失函数求导,得到导函数,根据导函数的方向调整拟合函数的参数,反复迭代。
Ⅱ 为什么要梯度累计:GPU记不下那么多中间变量。
Ⅲ 梯度累计的过程:先划分数据集,分别对每个数据集的损失函数求导(梯度),由导数可加性将各子集的梯度累加起来,得到梯度累加值。也就是Ⅰ中的导函数,根据他的方向调整拟合函数的参数即可。
Ⅳ 梯度累计的好处:解决的显存不足;效果和大批量训练一样;
Ⅴ 解析解你可以手解,数值解你解不了,也是我们让模型去拟合的参数。
参考资料是李沐老师的:Dive-into-DL-PyTorch
这一节书里讲得特别抽象,很多细节对于新手特别不友好,因此星马做了详述。
星马是刚入门的大菜比,有错望指正,有项目可以带带我。