参考
L2正则化的目的就是为了让权重衰减到更小的值,在一定程度上减少模型过拟合的问题。
weight decay(权值衰减)的使用既不是为了提高收敛精确度也不是为了提高收敛速度,其最终目的是防止过拟合。在损失函数中,weight decay是放在正则项(regularization)前面的一个系数,正则项一般指示模型的复杂度,所以weight decay的作用是调节模型复杂度对损失函数的影响,若weight decay很大,则复杂的模型损失函数的值也就大。
L2正则化就是在代价函数后面再加上一个正则化项:
C = C 0 + λ 2 n ∑ w w 2 C=C_0+\frac{\lambda}{2n}\sum_ww^2 C=C0+2nλ∑ww2
其中 C 0 C_0 C0 代表原始的代价函数,后面那一项是 l2 正则化项:所有参数 w 的平方和,除以训练集的样本大小 n , λ 就是正则项系数,权衡正则项与 C 0 C_0 C0 项的比重,另外还有一个系数1/2,主要是为了后面求导的结果方便,系数 λ 就是权重衰减系数。
为什么可以对权重进行衰减?
我们对加入正则化的代价函数进行求导:
∂ C ∂ w = ∂ C 0 ∂ w + λ n \frac{\partial C}{\partial w}=\frac{\partial C_0}{\partial w}+\frac{\lambda}{n} ∂w∂C=∂w∂C0+nλ
∂ C ∂ b = ∂ C 0 ∂ b \frac{\partial C}{\partial b}=\frac{\partial C_0}{\partial b} ∂b∂C=∂b∂C0
可以发现L2正则化项对b的更新没有影响,但是对于w的更新有影响:
w → w − η ∂ C 0 ∂ w − η λ n w = ( 1 − η λ n ) w − η ∂ C 0 ∂ w w\rightarrow w-\eta\frac{\partial C_0}{\partial w}-\frac{\eta\lambda}{n}w=(1-\frac{\eta\lambda}{n})w-\eta\frac{\partial C_0}{\partial w} w→w−η∂w∂C0−nηλw=(1−nηλ)w−η∂w∂C0
在不使用L2正则化时,求导结果中w前系数为1,现在w前面系数为 ( 1 − η λ n ) (1-\frac{\eta\lambda}{n}) (1−nηλ),并且该项小于1,它的效果是减小w,这也是权重衰减的由来。考虑到后面的导数项,w最终的值可能增大也可能减小。
更复杂的数据集需要较少的正则化,因此设置为较小的权重衰减值
浅层结构需要更多的正则化,因此设置更大的权重衰减值
作用:避免模型过拟合
思考:L2正则化有让w变小的效果,但是为什么w变小可以防止过拟合呢?
原理:
动量来源于牛顿定律,基本思想是为了找到最优加入“惯性”的影响,当误差曲面中存在平坦区域,SGD就可以更快的学习。
对于一般的SGD,其表达式为:
x → x − α × d x x\rightarrow x - \alpha\times dx x→x−α×dx
x沿负梯度方向下降,而带momentum的SGD则写成如下形式:
v = β × v + α × d x v=\beta \times v + \alpha\times dx v=β×v+α×dx
x → x − v x\rightarrow x - v x→x−v
其中β为momentum系数,如果上次的momentum(即v)与这一次的负梯度方向相同,那么这次下降的幅度就会加大,所以这样能够达到加速收敛的过程。
optimizer = optim.SGD(net.parameters(), lr=learning_rate, momentum=0.78)
momentum取值越大则考虑之前的更新方向的程度就越大,取值为0时即相当于没有惯性。
在训练模型的时候,通常会遇到这种情况:我们平衡模型的训练速度和损失(loss)后选择了相对合适的学习率(learning rate),但是训练集的损失下降到一定的程度后就不在下降了,比如training loss一直在0.7和0.9之间来回震荡,不能进一步下降。
遇到这种情况通常可以通过适当降低学习率(learning rate)来实现。但是,降低学习率又会延长训练所需的时间。
学习率衰减(learning rate decay)就是一种可以平衡这两者之间矛盾的解决方案。学习率衰减的基本思想是:学习率随着训练的进行逐渐衰减。
学习率衰减基本有两种实现方法:
decayed_learning_rate=learning_rate*decay_rate^(global_step/decay_steps)
与学习率不同,其值不影响计算训练时间。批量大小受硬件内存的限制,而学习率则不然。建议使用适合硬件内存的较大批量大小,并使用更大的学习速率。 如果服务器有多个GPU,则总批量大小是单个GPU上的批量大小乘以GPU的数量。
关于增大batch size对于梯度估计准确度的影响,分析如下:
假设batch size为m,对于一个minibatch,loss为:
梯度
整个minibatch的梯度方差为:
由于每个样本( x i x_i xi, y i y_i yi)是随机从训练样本集sample得到的,满足i.i.d.假设,因此样本梯度的方差相等,为
等价于SGD的梯度方差,可以看到batch size增大m倍,相当于将梯度的方差减少m倍,因此梯度更加准确。
如果要保持方差和原来SGD一样,相当于给定了这么大的方差带宽容量,那么就可以增大lr,充分利用这个方差容量,在上式中添加lr,同时利用方差的变化公式,得到等式
因此可将lr增加sqrt(m)倍,以提高训练速度,这也是在linear scaling rule之前很多人常用的增大lr的方式。
在分布式训练中,batch size 随着数据并行的worker增加而增大,假设baseline的batch size为B,learning rate为lr,训练epoch数为N。如果保持baseline的learning rate,一般不会有较好的收敛速度和精度。原因如下:对于收敛速度,假设k个worker,每次过的sample数量为kB,因此一个epoch下的更新次数为baseline的1/k,而每次更新的lr不变,所以要达到baseline相同的更新次数,则需要增加epoch数量,最大需要增加k*N个epoch,因此收敛加速倍数会远远低于k。对于收敛精度,由于增大了batch size使梯度估计相较于badeline的梯度更加准确,噪音减少,更容易收敛到附近的local minima,类似于GD的效果。
为了解决这个问题,一个方法就是增大lr,因为batch变大梯度估计更准,理应比baseline的梯度更确信一些,所以增大lr,利用更准确的梯度多走一点,提高收敛速度。同时增大lr,让每次走的幅度尽量大一些,如果遇到了sharp local minima,还有可能逃出收敛到更好的地方。