问题提出
大多数机器学习或者深度学习算法都涉及某种形式的优化,即通过改变x x x 以最小化损失函数f ( x ) f(x) f ( x ) 。
小批量随机梯度下降(mini-batch stochastic gradient descent)是Dive into Deep Learning中提出的第一个优化方法,3.2节线性回归的从零开始实现中要求实现一个sgd
函数以完成参数的优化。因此记录以下关于理解梯度下降的笔记。
梯度下降
梯度下降法主要分为以下三种。
批量梯度下降BGD
首先假设一个损失函数:
J ( θ ) = 1 2 ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 \begin{equation}
J(\theta)=\frac{1}{2}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})^2
\end{equation}
J ( θ ) = 2 1 i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) 2
其中h θ ( x ) h_{\theta}(x) h θ ( x ) 表示预测值,由以下函数得到:
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + . . . + θ n x n \begin{equation}
h_{\theta}(x)=\theta_0+\theta_1x_1+\theta_2x_2+...+\theta_nx_n
\end{equation}
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + ... + θ n x n
根据高等数学的知识,曲面上方向导数最大值的方向就是梯度的方向。因此在进行梯度下降的操作时,只需沿着梯度的反方向进行权重的更新,最终就能找到全局的最优解。对于一个样本点( X , y ) (X, y) ( X , y ) 的各参数θ i \theta_i θ i ,权重的更新可以表示为:
θ j ′ = θ j − α ∂ ∂ θ j J ( θ ) = θ j − α ( h θ ( x ) − y ) x j \begin{equation}
\begin{aligned}
\theta_j'&=\theta_j-\alpha \frac{\partial}{\partial\theta_j}J(\theta)\\
&= \theta_j-\alpha(h_\theta(x)-y)x_j
\end{aligned}
\end{equation}
θ j ′ = θ j − α ∂ θ j ∂ J ( θ ) = θ j − α ( h θ ( x ) − y ) x j
其中,α \alpha α 表示每次沿反方向进行权重更新时的步长,也就是超参中的学习率(learning rate)。
上述公式表示了一个样本点的更新方式,对于全部样本,采用取平均的方式更新:
θ j ′ = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j \begin{equation}
\theta_j'=\theta_j-\alpha\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j
\end{equation}
θ j ′ = θ j − α m 1 i = 1 ∑ m ( h θ ( x ( i ) ) − y ( i ) ) x j
BGD更新每个参数时都会使用全部样本,在样本量非常大时,效率较低。
随机梯度下降SGD
为了解决BGD训练速度随样本量增加减慢的问题,提出了随机梯度下降的方法。在随机梯度下降的每次迭代中,我们随机均匀采样的一个样本索引i ∈ { 1 , 2 , 3 , . . . , n } i\in \{1,2,3,...,n\} i ∈ { 1 , 2 , 3 , ... , n } ,并计算该样本的损失函数梯度∂ ∂ θ j J ( θ ) \frac{\partial}{\partial\theta_j}J(\theta) ∂ θ j ∂ J ( θ ) 来更新参数θ j \theta_j θ j :
θ j ′ = θ j − α ( h θ ( x ( i ) ) − y ( i ) ) x j \begin{equation}
\theta_j'=\theta_j-\alpha(h_\theta(x^{(i)})-y^{(i)})x_j
\end{equation}
θ j ′ = θ j − α ( h θ ( x ( i ) ) − y ( i ) ) x j
由于损失函数随机梯度是对其梯度的无偏估计,因此平均来说,随机梯度是对梯度的一个良好的估计。
SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向,但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。
小批量随机梯度下降MBGD
该方法是对上述两种方法的折衷,每次随机选取样本时,样本数从1个增加至batch_size
个:
θ j ′ = θ j − α 1 ∣ B ∣ ∑ i = 1 ∣ B ∣ ( h θ ( x ( i ) ) − y ( i ) ) x j \begin{equation}
\theta_j'=\theta_j-\alpha\frac{1}{|\Beta|}\sum_{i=1}^{|\Beta|}(h_\theta(x^{(i)})-y^{(i)})x_j
\end{equation}
θ j ′ = θ j − α ∣ B ∣ 1 i = 1 ∑ ∣ B ∣ ( h θ ( x ( i ) ) − y ( i ) ) x j
这样既保证了算法的训练速度,而且也要保证了最终参数训练的准确率。
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 for epoch in range (epochs): for X, y in data_generation(batch_size, features, labels): l = squared_loss(model(X, w, b), y) l.sum ().backward() with torch.no_grad(): for param in [w, b]: param -= lr * param.grad / batch_size param.grad.zero_() with torch.no_grad(): train_l = squared_loss(model(features, w, b), labels) print (f"epoch {epoch + 1 } , loss {float (train_l.mean()):f} " )