【深度学习】优化器详解

深度学习优化器详解

优化器

深度学习模型通过引入损失函数,用来计算目标预测的错误程度。根据损失函数计算得到的误差结果,需要对模型参数(即权重和偏差)进行很小的更改,以期减少预测错误。但问题是如何知道何时应更改参数,如果要更改参数,应更改多少?这就是引入优化器的时候了。简单来说,优化器可以优化损失函数,优化器的工作是以使损失函数最小化的方式更改可训练参数,损失函数指导优化器朝正确的方向移动

优化器即优化算法是用来求取模型的最优解的,通过比较神经网络自己预测的输出与真实标签的差距,也就是Loss函数。

为了找到最小的loss(也就是在神经网络训练的反向传播中,求得局部的最优解),通常采用的是梯度下降(Gradient Descent)的方法,而梯度下降,便是优化算法中的一种。

1. SGD(梯度下降法)

1.1 原理

表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)
在这里插入图片描述

1.2 梯度下降法迭代步骤

梯度下降的一个直观的解释:
比如我们在一座大山上的某处位置,由于我们不知道怎么下山,于是决定走一步算一步,也就是在每走到一个位置的时候,求解当前位置的梯度,沿着梯度的负方向,也就是当前最陡峭的位置向下走一步,然后继续求解当前位置梯度,向这一步所在位置沿着最陡峭最易下山的位置走一步。 这样一步步的走下去,一直走到觉得我们已经到了山脚。当然这样走下去,有可能我们不能走到山脚,而是到了某一个局部的山峰低处。
img-KdzKWPp3-1661424408143)

以MSE为例:
J(θ)=1m∑i=1m(x∗θ−y)2J(\theta)=\frac 1m\sum^m_{i=1}(x*\theta-y)^2J(θ)=m1i=1m(xθy)2
目标是找到一组合适的θ(w1,w2,w3,…,wn)使得目标函数J(θ)值最小。(以最快得速度、最有效的方式来找到最优解)

1.3 三种不同的梯度下降方法

区别在于每次参数更新时计算的样本数据量不同

1.3.1 批梯度下降( Batch gradient descent)

批梯度下降法(Batch Gradient Descent)针对的是整个数据集,通过对所有的样本的计算来求解梯度的方向
θ=θ−η∇θJ(θ)\theta = \theta - \eta \nabla_{\theta}J(\theta )θ=θηθJ(θ)

for i in range(nb_epochs):
	params_grad = evaluate_gradient(loss_function, data, params)
	params = params - learning_rate * params_grad
1.3.2 随机梯度下降(Stochastic gradient descent)

每进行1次参数更新,只需要计算1个随机数据样本
θ=θ−η∇θJ(x(i),y(i);θ)\theta = \theta - \eta \nabla_{\theta}J( x^{(i)}, y^{(i)} ;\theta)θ=θηθJ(x(i),y(i);θ)

for i in range(nb_epochs):
	np.random.shuffle(data)
	for example in data:
		params_grad = evaluate_gradient(loss_function, example, params)
		params = params - learning_rate * params_grad
1.3.3 Mini-batch梯度下降方法(Mini-batch gradient descent)

每进行1次参数更新,需要计算1个mini-batch数据样本
θ=θ−η∇θJ(x(i:i+n),y(i:i+n);θ)\theta = \theta - \eta \nabla_{\theta}J(x^{(i:i+n)}, y^{(i:i+n)}; \theta )θ=θηθJ(x(i:i+n),y(i:i+n);θ)

for i in range(nb_epochs):
	np.random.shuffle(data)
	for batch in get_batches(data, batch_size=50):
		params_grad = evaluate_gradient(loss_function, batch, params)
 		params = params - learning_rate * params_grad
1.3.4 三种方法对比
  • Batch gradient descent的收敛速度太慢,而且会大量多余的计算(比如计算相似的样本)。
  • Stochastic gradient descent虽然大大加速了收敛速度,但是它的梯度下降的波动非常大(high variance)。
  • Mini-batch gradient descent中和了2者的优缺点,所以SGD算法通常也默认是Mini-batch gradient descent
1.3.5 Mini-batch梯度下降法的缺点

然而Mini-batch gradient descent也不能保证很好地收敛。主要有以下缺点:

  • 选择一个合适的learning rate是非常困难的 学习率太低会收敛缓慢,学习率过高会使收敛时的波动过大。

  • 所有参数都是用同样的learning rate 对于稀疏数据或特征,有时我们希望对于不经常出现的特征的参数更新快一些,对于常出现的特征更新慢一些。这个时候SGD就不能满足要求了。

  • sgd容易收敛到局部最优解,并且在某些情况可能被困在鞍点 在合适的初始化和step size的情况下,鞍点的影响没那么大。

1.3.6 调节 Batch_Size 对训练效果影响到底如何?
  • Batch_Size 太小,模型表现效果极其糟糕(error飙升)。
  • 随着 Batch_Size 增大,处理相同数据量的速度越快。
  • 随着 Batch_Size 增大,达到相同精度所需要的 epoch 数量越来越多。

由于上述两种因素的矛盾, Batch_Size 增大到某个时候,达到时间上的最优;由于最终收敛精度会陷入不同的局部极值,因此 Batch_Size 增大到某些时候,达到最终收敛精度上的最优。如果训练集较小(小于 2000 个样本),直接使用BGD法

正是因为SGD这些缺点,才有后续提出的各种算法。

1.4 pytorch中SGD:

torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False, *, maximize=False, foreach=None)

参数:

  • params(iterable): 需要优化的参数
  • lr(float): 学习率
  • momentum (float, optional) : 动量因子 默认 0
  • weight_decay (float, optional) – 权值衰减 (L2 penalty) (default: 0)
  • dampening (float, optional) – 动量抑制 (default: 0)
  • nesterov (bool, optional) – 是否使用 Nesterov momentum (default: False)
  • maximize (bool, optional) – 根据目标最大化参数,而不是最小化 (default: False)
  • foreach (bool, optional) – 是否为每一个优化器实现 (default: None)

2. Momentum

momentum利用了物理学中动量的思想,通过积累之前的动量(mt−1)来加速当前的梯度。
mt=μ∗mt−1+η∇θJ(θ)θt=θt−1−mtm_t = \mu*m_{t-1}+\eta \nabla_{\theta}J(\theta) \\ \theta_{t} = \theta_{t-1} - m_tmt=μmt1+ηθJ(θ)θt=θt1mt
其中,μ是动量因子,通常被设置为0.9或近似值。

特点

  • 参数下降初期,加上前一次参数更新值;如果前后2次下降方向一致,乘上较大的μ能够很好的加速。
  • 参数下降中后期,在局部最小值附近来回震荡时,gradient→0,μ使得更新幅度增大,跳出陷阱。
  • 在梯度方向改变时,momentum能够降低参数更新速度,从而减少震荡;在梯度方向相同时,momentum可以加速参数更新, 从而加速收敛。
  • 总而言之,momentum能够加速SGD收敛,抑制震荡。

3. NAG

牛顿加速梯度动量优化方法(NAG, Nesterov accelerated gradient):用上一步的速度先走一小步,再看当前的梯度然后再走一步。

尝试这么去理解:在momentum中小球会盲目的跟从下坡的梯度,容易发生错误,所以需要一个更聪明的小球,能提前知道它要去哪,还有知道走到坡地的时候速度慢下来,而不是又崇尚另一坡。

  • 优点: 梯度下降的方向更加准确
  • 缺点: 对收敛率作用不是很大

NAG在梯度更新时做一个矫正,避免前进太快,同时提高灵敏度。

Momentum并没有直接影响当前的梯度∇θJ(θ)\nabla_{\theta}J(\theta)θJ(θ),所以NAG的改进就是用上一次的动量(−μ∗mt−1)当前的梯度∇θJ(θ)\nabla_{\theta}J(\theta)θJ(θ)做了一个矫正。

mt=μ∗mt−1+η∇θJ(θ−μ∗mt−1)θt=θt−1−mtm_t = \mu*m_{t-1}+\eta \nabla_{\theta}J(\theta-\mu*m_{t-1})\\\theta_{t} = \theta_{t-1} - m_tmt=μmt1+ηθJ(θμmt1)θt=θt1mt

Momentum 与 NAG 的对比,如下图:
image_3

  • Momentum: 蓝色向量
    Momentum首先计算当前的梯度值(短的蓝色向量),然后加上之前累计的梯度/动量(长的蓝色向量)。
  • NAG: 绿色向量
    NAG 首先先计算之前累计的梯度/动量(长的棕色向量),然后加上当前梯度值进行矫正后(−μ∗mt−1)的梯度值(红色向量),得到的就是最终 NAG 的更新值(绿色向量)。

Momentum 和 NAG 都是为了使梯度更新更灵活。但是人工设计的学习率总是有些生硬,下面介绍几种自适应学习率的方法。


4. Adagrad

Adagrad

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值