局部极小值与鞍点
在优化过程中,模型可能会遇到局部极小值(local minima)或鞍点(saddle point),这些位置梯度为零,使得模型停止进步或训练缓慢。
局部极小值是损失函数的局部最低点,而鞍点则是梯度为零但不是局部极小/极大值的点。
判断一个点是局部极小值还是鞍点需要分析损失函数的海森矩阵(二阶导数矩阵)的特征值。若海森矩阵的所有特征值都为正,则该点为局部极小值;若有正有负,则为鞍点。
形象一点的说法就是可以通过海森矩阵得到这个函数图像的地貌,显而易见下面两种点虽然在各个维度上梯度都为0,但地貌明显不一样。鞍点很明显在两个正交的方向上,一个向上U,一个向下U。而极值点的四周,U均朝上或朝下
分析海森矩阵可以找到负特征值对应的特征向量,沿着这个方向更新参数可以逃离鞍点。但计算量较大,几乎不使用。
实际上,对于深层次的神经网络,几乎不存在完全的局部极小值点,由于参数量非常大(训练的维度多),可能有几个维度到达它的极小值,但其他维度未达到,仍然可以获得有效梯度并继续降低损失。如果真的训练缓慢时,往往只是遇到了鞍点。所以逃离鞍点就是接下来的优化手段。
批量梯度下降
在实际训练时,会将训练集分为多个batch,如将1000个样本分为8个batch(批),每次拿1个batch即125个样本进行训练。将所有batch(当前为8个)全部训练完一次,就是一个epoch(回合)。每个epoch都会打乱batch顺序。这种方式既可以减少内存每次读入的数据量,也可以利用到并行计算。
如果batch_size=整个训练集,即每次直接用所有样本进行训练,称为批量梯度下降(BGD, Batch Gradient Descent)
如果batch_size=1,即每次拿一个样本训练,称为随机梯度下降法(SGD, Stochastic Gradient Descent)
当然还有折中策略,1<batch_size<整个训练集大小,小批量梯度下降(Mini-Batch Gradient Descent, MBGD)
下图为前两者的对比
红线为批量梯度下降,是较为合理的直线
紫红线为随机梯度下降,总的来看,参数朝着全局最小的方向移动,偶尔也有例外。
对比:
- 一次看20条数据,和一次只看一条数据,后者带来的波动明显会更大(带有更多噪声)。就像看远方走路和只看脚底走路。在非凸优化问题中,其相比批量梯度下降(前者)更容易逃离局部最小值(可能乱走就正好走出局部最小点了)。但相对的,前者在准确率上会更好、方向更稳定。
- 虽然批量梯度下降要看全部样本,但是他可以利用并行计算,即同时处理多条数据(参考tensor和ndarray进行矩阵运算等),所以时间不一定比batch_size小的运算更耗时(虽然batch_size大时还是明显更耗时),甚至有时更省时。
- 总结一下:大的batch_size能使损失下降的更平缓、更准确,借助并行计算训练反而更快,但在优化上容易出现问题或有过拟合现象。小的batch_size通过引入更多噪音,更能让模型跳出局部最小点,且泛化能力更强,模型效果可能更好。
动量梯度下降
相比较传统的梯度下降,每次计算模型参数的变化值时,除了计算梯度,还使用了上一次的动量,两者之向量和(这里为了表达方便忽略了他们各自的学习率超参数)就是本次的动量(也是动量梯度下降中的模型参数变化值)。
公式虽然只用了上一次下降时的动量,但由于是向量,实际上是用到了历史所有动量的累积影响。
因为动量的累积影响构成的向量和本次梯度的方向可能不一致,当两者夹角小时,动量起到的就是加速的作用,可以越过局部最小点,并加快训练。而两者夹角较大时,则能减少下降幅度(甚至从已经越过的最小值点再折回来),加速收敛。当然,动量也会减少梯度的变化幅度,让乱动的梯度向量与历史动量方向相结合,使变化更稳定平缓。
动量就像是滑雪。如果你滑到平缓的斜坡上(鞍点或局部极小值),没有足够的动量(过去的梯度方向)你就可能停在那里。通过积累动量,你可以滑过这些平坦区域,继续向前。