CS231n Lecture 8: Training Neural Networks Part2

Optimization

动量版SGD

SGD仍然还有一些问题:当损失函数在一个方向快速改变,另一个方向很慢地改变时,梯度下降会变成非常慢地一个过程

CS231n Lecture 8: Training Neural Networks Part2_第1张图片

同时,SGD对于驻点和局部最小值的表现并不好,在那些地方会堵住。因此,现在考虑一种SGD+动量的方法:

CS231n Lecture 8: Training Neural Networks Part2_第2张图片

现在的速度 = 摩擦系数 * 之前的速度+梯度

新的权重 = 旧的权重 - 学习率 * 新的速度

摩擦系数一般取0.9或0.99

Nesterov 动量

v t + 1 = ρ v t − α ∇ f ( x t + ρ v t ) x t + 1 = x t + v t + 1 \begin{aligned}v_{t+1} &=\rho v_{t}-\alpha \nabla f\left(x_{t}+\rho v_{t}\right) \\x_{t+1} &=x_{t}+v_{t+1}\end{aligned} vt+1xt+1=ρvtαf(xt+ρvt)=xt+vt+1

相当于在动量改变前,我先用现在的速度到未来的位置看未来的梯度,这样就可以提前知道梯度的变化了。

换元后,可以看到是这样的

v t + 1 = ρ v t − α ∇ f ( x ~ t ) x ~ t + 1 = x ~ t − ρ v t + ( 1 + ρ ) v t + 1 = x ~ t + v t + 1 + ρ ( v t + 1 − v t ) \begin{aligned}v_{t+1} &=\rho v_{t}-\alpha \nabla f\left(\tilde{x}_{t}\right) \\\tilde{x}_{t+1} &=\tilde{x}_{t}-\rho v_{t}+(1+\rho) v_{t+1} \\&=\tilde{x}_{t}+v_{t+1}+\rho\left(v_{t+1}-v_{t}\right)\end{aligned} vt+1x~t+1=ρvtαf(x~t)=x~tρvt+(1+ρ)vt+1=x~t+vt+1+ρ(vt+1vt)

dx = compute_gradient(x)
old_v = v
v = rho * v - learning_rate * dx
x += -rho * old_v + (1 + rho) * v

AdaGrad

CS231n Lecture 8: Training Neural Networks Part2_第3张图片

可以看到,这里加上了dx的平方作为梯度,可以起到加大步长的效果。但是,随着训练时间的延长,步长会越来越小。

因此,就会有新的RMSProp梯度更新法

RMSPropCS231n Lecture 8: Training Neural Networks Part2_第4张图片

这里是用了衰减率来限制住学习率不会随时间的延长而缩小

Adam

该算法集百家之所长,究极缝合怪算法

first_moment = 0
second_moment = 0
for t in range(1, num_iterations):
	first_moment = beta1 * first_moment + (1 - beta1) * dx
	second_moment= beta2 * second_moment + (1 - beta2) * dx * dx
	first_unbias = first_moment / (1 - beta1 ** t)
	second_unbias = second_moment / (1 - beta2 ** t)
	x -= learning_rate * first_unbias / (np.sqrt(second_unbias) + 1e-7)

unbias存在的意义是first和second moment的值在开始的时候都是0,这会让更新的值存在一些不可控的影响

Adam在开始时,beta1 = 0.9, beta2 = 0.999, lr = 1e-3 或 5e-4 是一个不错的初始设置

学习率衰减

CS231n Lecture 8: Training Neural Networks Part2_第5张图片

好的学习率是能非常快的收敛,并且慢慢地逼近loss最小值

因此,我们希望学习率在前期很大,后期慢慢变小。所以需要学习率衰减。

一阶优化-》二阶优化

一阶优化求的是当前坡度最大的方向,而二阶优化还会考虑到走了一步后,坡度是否会变得更大。

二阶优化收敛得更快,而且不需要学习率。

二阶泰勒展开,一元的时候即是这种情况

J ( θ ) ≈ J ( θ 0 ) + ( θ − θ 0 ) ⊤ ∇ θ J ( θ 0 ) + 1 2 ( θ − θ 0 ) ⊤ H ( θ − θ 0 ) J(\boldsymbol{\theta}) \approx J\left(\boldsymbol{\theta}_{0}\right)+\left(\boldsymbol{\theta}-\boldsymbol{\theta}_{0}\right)^{\top} \nabla_{\boldsymbol{\theta}} J\left(\boldsymbol{\theta}_{0}\right)+\frac{1}{2}\left(\boldsymbol{\theta}-\boldsymbol{\theta}_{0}\right)^{\top} \boldsymbol{H}\left(\boldsymbol{\theta}-\boldsymbol{\theta}_{0}\right) J(θ)J(θ0)+(θθ0)θJ(θ0)+21(θθ0)H(θθ0)

这是多元的情况

θ ∗ = θ 0 − H − 1 ∇ θ J ( θ 0 ) \boldsymbol{\theta}^{*}=\boldsymbol{\theta}_{0}-\boldsymbol{H}^{-1} \nabla_{\boldsymbol{\theta}} J\left(\boldsymbol{\theta}_{0}\right) θ=θ0H1θJ(θ0)

但该方法在深度学习时不常用,因为要求的海森矩阵太大了!

综上,Adam是默认的比较好的选择。

Model Ensembles

类似于用多个不同的独立模型来训练,最后测试时平均测试结果,大概可以多2%的准确率。

就好像,相比于1个人有a专业知识的人做一项工作,5个分别有a,b,c,d,e专业知识的人一起做一项工作效果会更好。

除了训练不同的模型,我们还可以将单个模型在不同时间点的状态保存下来,最后一起测试

正则化

平常使用的方法有L2、L1、L2+L1正则化。现在要介绍的是Dropout正则化。

意思是,在每一个前向传播的过程中,随机的将一些神经元置0.概率一般是0.5

CS231n Lecture 8: Training Neural Networks Part2_第6张图片

为什么Dropout是一种好的方法?因为它通过随机置0,打断了原有某些特征的连接,可以防止过拟合

但同时,dropout也会让我们的输出随机。由测试时和训练时的数学期望可以推出,我们在测试时的dropout概率需要翻倍

同时,正则化还有另外的方法,可以将输入的数据进行翻转等微小地改动操作,或者随机地取某块区域进行训练。

还可以加入随机的噪声等。

迁移学习

在训练 / 使用CNN时不需要大量的数据!

我们根据需要取更改最后的几层即可。

CS231n Lecture 8: Training Neural Networks Part2_第7张图片

你可能感兴趣的:(CS231n,学习笔记)