得到 loss function 之后,我们需要一种方法求解其最小值解 \(\theta = \arg \min L(\theta)\). 这种方法最好满足以下条件:
首先看第一个条件. 怎样才能找到对任何函数都能通用的办法呢?想象一下假如我们在下山,但是对周围的路况一无所知,我们如何判断更低的地方在哪里呢?这个 task 太难了,我们得给出一些条件,比如 \(L(\theta)\) 是一阶可微的,这样我们就能环顾四周,从而知道哪个方向比目前所处的位置高,哪个方向比所处的位置低了. 我们猜想顺着低处走就可以下山了,而且步子迈大一点就走得快,迈小一点就走得慢. 把下山整理成数学语言就是:
第 \(t\) 步梯度下降的公式
以上介绍的方法又称为 Vanilla Gradient Descent.
除公式外,梯度下降的结果还受到以下几个因素的影响:
仍以下山为例,如果步子太小,下山得下到猴年马月啊;步子太大,一个筋斗云过去都不知道自己在哪儿了.
而在山顶的时候可以走快一点,到山脚就不用那么着急了.
静态观点要求选择一个合适的初始值,这个值是ad hoc的(或者说是超参数);动态观点要求适当地变化学习率. 一种方法是 Adagrad(注意,很多 Ada 开头的模型指的都是 adaptive 的方法):
里面的 \(\odot\) 表示 element-wise dot,其他运算符也都是 element-wise 操作. 这样梯度越大的方向,分母上的惩罚也就越大,也就是限制往梯度最大的方向移动. 就好像人在山谷中行走,两侧梯度大,Adagrad方法会限制人尽量少地往两边走,这样就能更快地前进. 又比如现在处在斜面上,Vanilla会先顺着斜面冲到底,然后再考虑向左还是向右;Adagrad 会一边横向走一边顺着斜面下降,这样走得距离更短,还有可能避开 local minimum
还有一种解释是类比牛顿法,根号里的内容可以看作是二阶微分大小的一种表示,而且是通过历史的一阶微分来表示的。
类似的定义还有 Online learning 和 Offline learning
总的规律是:一次下降中使用的样本越少,梯度波动也就越大,学习率也要相应的调小,但是 iteration 的次数会更多,下降得更快;反之同理.
调整 batchsize 时,需要相应调整学习率. batch 越大,学习率也越大,这样才能保证 epoch 差不多时结果差不多.
如果某个特征 A 的范围是 0~1000,另一个特征 B 的范围是 0~1,那么特征 A 在损失函数中所占的比重会远远高于特征 B 的比重,梯度下降就会忽略特征 B 而全力学习特征 A. 为了消除这种不平衡,需要对先做 Feature Scaling,把每个特征都转化到大致相等的范围内. 常用的方法有
对于非凸的损失函数,梯度下降可能陷入局部极小值. 目前已知的凸函数模型有:
还有一些著名的优化方法,比如:
SGD with momentum (SGDM)
SGDM 的优点
RMSProp
解决 Adagrad 存在的一些问题:
Adam
Adam相当于 SGDM 和 RMSProp 的结合
到此为止,所有的模型训练方法基本都被囊括了。一般论文中能用到的模型也就是 Adam 和 SGDM,二者的对比如下:
Speed | Generalization | Stable | |
---|---|---|---|
Adam | √ | ||
SGD | √ | √ |
原文:https://www.cnblogs.com/xuruihan/p/13487979.html