我们将使用下方程描述的均方误差作为目标函数,将使用这些优化算法来最小化损失函数。

$$ f(m, b)=\frac{1}{n} \sum_{i=1}^n\left(y_i-\left(m x_i+b\right)\right)^2 $$

在梯度下降中,计算目标函数(L)相对于参数 theta(θ)的梯度,然后沿目标函数梯度的反方向更新参数。学习率 α 决定了达到局部最小值所需采取的步长。

$$ \theta_j \leftarrow \theta_j-\alpha \frac{\partial}{\partial \theta_j} J(\theta) $$

根据用于计算权重更新梯度的数据量,我们有不同的变体,我们将详细讨论这些变体。在批量梯度下降中,对于每个时期,我们计算整个数据集的目标函数相对于参数的梯度。因此,参数的更新每时期发生一次。批量梯度下降也称为 普通梯度下降。

对于我们的均方误差目标函数,m 和 b 的梯度如下所示。

$$ \frac{\partial f}{\partial m}=\frac{1}{n} \sum_{i=1}^n-2 x_i\left(y_i-\left(m x_i+b\right)\right) $$

$$ \frac{\partial f}{\partial b}=\frac{1}{n} \sum_{i=1}^n-2\left(y_i-\left(m x_i+b\right)\right) $$

 import numpy as np
 from sklearn.metrics import mean_squared_error
 def batch_gradient_descent(X, y, lr, epochs):
     m, b = 0.33, 0.48
 ​
     log, mse = [], []
     N = len(X)
 for _ in range(epochs):
         f = y - (m*X + b)
 ​
         m -= lr * (-2 * X.dot(f).sum() / N)
         b -= lr * (-2 * f.sum() / N)
 log.append((m, b))
         mse.append(mean_squared_error(y, (m*X + b)))
     return m, b, log, mse

在随机梯度下降中,从一个时期的整个集合中随机选择一个样本。计算该特定的梯度并更新样本和权重。

 import numpy as np
 from sklearn.metrics import mean_squared_error
 def SGD(X, y, lr, epochs):
     m, b = 0.5, 0.5
     log, mse = [], []
 for _ in range(epochs):
         indexes = np.random.randint(0, len(X))
         Xs = np.take(X, indexes)
         ys = np.take(y, indexes)
         N = len(X)
         f = ys - (m*Xs + b)
 ​
         m -= lr * (-2 * Xs*(f).sum() / N)
         b -= lr * (-2 * f.sum() / N)
 log.append((m, b))
         mse.append(mean_squared_error(y, m*X+b))
 return m, b, log, mse

在小批量梯度下降中,更新是针对小批量样本进行的。在我们的示例中,我们有 100 个样本。因此,如果批量大小为 10,则我们在 10 个时期内有 100 次更新。小批量梯度下降是训练神经网络时的首选算法。

 def minibatchgd(X, y, lr, epochs, batch_size):
     m, b = 0.5, 0.5
     log, mse = [], []
     for _ in range(epochs):
         total_len = len(X)
         for i in range(0, total_len, batch_size):
             Xs = X[i:i+batch_size]
             ys = y[i:i+batch_size]
             N = len(Xs)
             f = ys - (m*Xs + b)
             m -= lr * (-2 * Xs.dot(f).sum() / N)
             b -= lr * (-2 * f.sum() / N)
             log.append((m, b))
             mse.append(mean_squared_error(y, m*X+b))
 return m, b, log, mse

动量和涅斯特罗夫动量

$$ \begin{gathered} V_t=\beta V_{t-1}+(1-\beta) \nabla_w L(W, X, y) \\ W=W-\alpha V_t \end{gathered} $$

如果学习率按 $(1-\beta)$ 缩放,则上式可以写为

$$ \begin{gathered} V_t=\beta V_{t-1}+\alpha \nabla_w L(W, X, y) \\ W=W-V_t \end{gathered} $$

基本上,我们正在计算 W 导数的移动平均线。这有助于减少振荡。

https://embed.notionlytics.com/wt/ZXlKM2IzSnJjM0JoWTJWVWNtRmphMlZ5U1dRaU9pSlhiRWhvWlV4VVQxbHNjMlZYV2tKbU9URndaU0lzSW5CaFoyVkpaQ0k2SWpNME56QXdNV0ptTkRkbVlUUXlNbU01TkRCak1USTROMlJrWWpnM05UZG1JbjA9