梯度下降算法(SGD)、学习率
梯度下降算法(SGD)、学习率
梯度下降算法是机器学习和深度学习中最基础也是最重要的优化算法之一。它通过迭代调整模型参数,使得损失函数最小化,从而优化模型的预测性能。本文将从梯度下降的基本概念出发,详细讲解其工作原理、局部最优值问题、学习率的设置方法,以及如何判断梯度下降是否收敛。
一、什么是梯度下降
模型训练的目标是在训练集上获得使得损失最小的参数值组合。因此,在训练过程中需要不断调整参数值。那么,如何调整参数值呢?答案就是梯度下降算法。
梯度下降算法通过计算当前损失下降最快的方向来调整参数值(想象成从山顶到山谷每一步都要选择最优方案)。使用梯度下降的优势是每一次调整超参数都是当前的最优方案,所以可以在计算量最小的情况下从初始参数值调整到使得损失最小的最优参数值组合(即山顶到山谷的步数最少,是最优方案)。
对于两个参数w、b的情况,当选择初始参数值后,使用梯度下降算法从初始参数值到最优参数值(损失最小,即等高线最低点)的路线如下图所示,其中每个星号表示选择的一组参数值组合。
二、局部最优值
局部最优值可以理解成贪心算法的思想,因为每次梯度下降都是当前位置的最优值。
每次梯度下降时这种只考虑当前最优值(类似贪心算法)而不考虑全局最优值(类似动态规划算法)的情况显然不一定会获得最优解,即如果选择不同初始参数值时,使用梯度下降算法最终获得的最优参数值组合(损失最小,等高线最低点)会不同,这就是局部最优值。
如下图所示,选择不同初始参数值时使用梯度下降算法获得的最优参数值不同,显然左边的选法获得的是总体最优解,而右边的选法因为初始参数值的原因就不能获得总体最优解。像这两种使用梯度下降算法将初始参数值优化为最优参数值的情况,最优参数值结果都叫做局部最优值。
可见初始参数值对于训练的损失也起到了非常关键的作用,合理选择初始参数值可以大大减少训练损失。
三、梯度下降算法解释
对于参数w,梯度下降算法执行步骤如下图:
解释如下:
- 对参数w的等高线损失图如右图所示。
- wt-1表示当前参数值是几。
- wt表示使用梯度下降算法计算得到的下一个参数值是几。
- η为学习率,表示参数变化的快慢。学习率在一次训练过程中是一个固定值,大小通常在0~1之间。
- 当学习率设置非常小时,参数收敛为最优参数的速度就会很慢,耗时很长,因此不可取。
- 当学习率设置非常大时 ,由于每次梯度下降都是局部最优,所以可能导致永远不可能收敛。
- 损失函数L对参数w求偏导表示梯度,参数值沿梯度方向变化时损失值增加最快,参数值沿梯度负方向变化时损失值减少最快。(这是高数知识,沿着某个自变量的当前偏导数方向增大该自变量的值时因变量变化最快)
- 因此公式(w1=w0–学习率*梯度)表示当前参数值w=w0沿损失值减少最快的方向变化η大小即为下一步参数值w=w1。(通俗理解:下山时选取的下一步位置w1=当前所在的w0位置朝着负梯度方向走η单位的长度)这就是梯度下降的关键公式。
- 不断重复上述操作,直到找到使得损失L最小的局部最优参数值w(到达某个山谷),此时计算梯度为0,公式变为wt=wt-1,参数值停止变化,当参数值达到earlystopping次不变时训练完成(这也就解释了为什么到达局部最优值后参数就不再更新)。
- 注意:一般很难真正达到局部最优值,正常训练时损失下降小于ε(一般10的负三次方)就默认收敛,停止训练了。
- 研究完一个参数w的情况,对于两个参数w、b的操作其实也是类似的,对不同自变量w、b求偏导计算梯度(下山方向)就好了。因为两个参数时损失函数为三维图像,在移动时需要选择两个方向。如下图。
- 注意:多参数情况中参数要同步更新,使用tmp来暂存防止错误的异步更新。
四、学习率
1.什么是学习率
学习率是梯度下降算法中的一个参数,用来规定每次梯度下降过程中参数值变化的快慢。学习率在一次训练过程中是一个固定值,大小通常在0~1之间。
- 学习率大参数值变化快,学习率小参数值变化慢。(变化快慢≠收敛快慢,因为变化可能不正常的梯度上升)
2.学习率太大/太小带来的问题
为什么学习率太大或太小都会导致参数值难以收敛?
3.如何设置学习率
在保证代码编写无误的情况下,从0.001开始调试,十倍增加,直到找到一个最大值(使得梯度在训练过程中不降反升),然后在0.001~最大值之间进行微调,找到尽量大(参数收敛速度快,耗时少)但又不会导致梯度上升的学习率。
五、如何判断梯度下降是否收敛、是否正确运行
程序中的epoch值即为梯度下降算法执行修改参数值的次数。
1.绘制迭代次数–损失值的图像
- 训练过程中训练集batch经过一次梯度下降即为一次迭代。
- 通过图像可以实时查看梯度下降是否正常执行:若随着迭代次数增加损失不减反增说明梯度下降执行错误,可能的原因是:学习率过大(上面讲了),代码有错误。
- 当梯度下降图像趋于平稳时说明参数值基本接近收敛(注意是接近,一般很难真正达到局部最优值),结束训练。
- 梯度下降非正常工作的情况:损失值不减反增
- 调试梯度下降代码是否正常运行的技巧:学习率设置足够小,这样损失虽然减少很慢,但是会一直减少。如果不减反增,肯定是代码有问题咯。(实际训练不能用很小的学习率)
2.自动收敛测试
- 在代码中加入自动收敛测试,每次迭代时都进行测试,当梯度减少小于设置值ε时默认收敛(一般很难真正达到局部最优值),结束训练。