梯度

梯度下降(Gradient Descent)是一种迭代的优化算法,用于寻找函数的局部最小值。在机器学习和深度学习中,梯度下降常被用于优化损失函数以训练模型。以下是梯度下降的一些常见变种:

  1. 批量梯度下降(Batch Gradient Descent):
    • 使用整个训练集计算梯度。
    • 确定的收敛路径,但可能在大数据集上很慢。
  2. 随机梯度下降(Stochastic Gradient Descent, SGD):
    • 在每次迭代中只使用一个训练样本来计算梯度。
    • 更快,但收敛路径可能会有很大的波动。
    • 通常使用学习率衰减策略来帮助算法收敛。
  3. 小批量梯度下降(Mini-batch Gradient Descent):
    • 使用一个小批量的训练样本计算梯度,这个小批量的大小介于批量梯度下降和随机梯度下降之间。
    • 常用于实践中,因为它结合了批量梯度下降和随机梯度下降的优点。
  4. 动量梯度下降(Momentum):
    • 结合了之前的梯度来加速收敛,并克服了波动。
    • 使用“动量”项,该项是之前梯度的加权平均,以获得更平滑的更新路径。
  5. Adagrad:
    • 对每个参数都有一个独特的学习率。
    • 适用于稀疏数据。
  6. RMSprop(Root Mean Square Propagation):
    • 是Adagrad的改进版本,通过移动平均来解决Adagrad学习率急剧下降的问题。
  7. Adam(Adaptive Moment Estimation):
    • 结合了动量和RMSprop的思想。
    • 在实践中被广泛使用,因为它通常表现得很好。
  8. Adadelta:
    • 是Adagrad的另一个改进版本,不需要设置默认学习率。
  9. Nadam:
    • 结合了Adam和Nesterov的动量。
      以上只是梯度下降的一些常见变种。在实践中,通常需要根据具体的问题和数据集来选择和调整合适的优化算法。

批量梯度下降

好的,我将为您实现批量梯度下降(Batch Gradient Descent)算法。为了简化,我们将使用线性回归作为示例。
考虑线性回归的损失函数(均方误差):

J(θ)=12mi=1m(hθ(x(i))y(i))2

其中:

θj:=θjαθjJ(θ)

其中 α是学习率。
对于线性回归,梯度为:

θjJ(θ)=1mi=1m(hθ(x(i))y(i))xj(i)

接下来,我将实现批量梯度下降算法:

import numpy as np

def batch_gradient_descent(X, y, learning_rate=0.01, epochs=1000):
    m, n = X.shape  # m is number of samples, n is number of features
    theta = np.zeros(n)  # initialize weights to zeros
    cost_history = []  # to store cost at each iteration

    for epoch in range(epochs):
        # Calculate predictions
        predictions = np.dot(X, theta)
        
        # Calculate error
        errors = predictions - y

        # Update weights using Batch Gradient Descent formula
        gradient = (1/m) * np.dot(X.T, errors)
        theta -= learning_rate * gradient
        
        # Calculate and store cost
        cost = (1/(2*m)) * np.sum(errors**2)
        cost_history.append(cost)

    return theta, cost_history

# Sample data
X_sample = np.array([[1, 1], [1, 2], [1, 3], [1, 4]])
y_sample = np.array([1, 2, 3, 4])

# Add bias term (x0 = 1) to X
X_sample_with_bias = np.c_[np.ones((X_sample.shape[0], 1)), X_sample[:, 1:]]

theta, cost_history = batch_gradient_descent(X_sample_with_bias, y_sample)

theta, cost_history[-5:]  # Display final weights and last 5 costs

使用批量梯度下降算法优化线性回归模型后,我们得到了以下结果:

这些损失值表明,随着迭代的进行,模型的损失在逐渐减小,这意味着梯度下降算法正在有效地优化模型。

请注意,本示例使用了一个简单的线性数据集。在实际应用中,可能需要更多的迭代次数和调整学习率来达到最优解。

随机梯度下降(SGD)

当然可以。随机梯度下降(Stochastic Gradient Descent, SGD)与批量梯度下降的主要区别在于,每次更新参数时,SGD 只使用一个训练样本来计算梯度,而不是使用整个训练集。

以下是随机梯度下降算法的实现:

def stochastic_gradient_descent(X, y, learning_rate=0.01, epochs=1000):
    m, n = X.shape  # m is number of samples, n is number of features
    theta = np.zeros(n)  # initialize weights to zeros
    cost_history = []  # to store cost at each iteration

    for epoch in range(epochs):
        total_cost = 0
        for i in range(m):
            random_idx = np.random.randint(m)  # Randomly select one sample
            xi = X[random_idx:random_idx+1]
            yi = y[random_idx:random_idx+1]
            
            # Calculate prediction
            prediction = np.dot(xi, theta)
            
            # Calculate error
            error = prediction - yi

            # Update weights using Stochastic Gradient Descent formula
            gradient = np.dot(xi.T, error)
            theta -= learning_rate * gradient
            
            # Calculate and accumulate cost
            cost = (1/2) * np.sum(error**2)
            total_cost += cost
        
        # Average cost for the epoch
        avg_cost = total_cost / m
        cost_history.append(avg_cost)

    return theta, cost_history

theta_sgd, cost_history_sgd = stochastic_gradient_descent(X_sample_with_bias, y_sample)

theta_sgd, cost_history_sgd[-5:]  # Display final weights and last 5 costs

使用随机梯度下降算法优化线性回归模型后,我们得到了以下结果:

请注意,与批量梯度下降相比,随机梯度下降的收敛路径可能更加嘈杂,并且可能不会像批量梯度下降那样平滑地逼近最小值。这是因为每次迭代时只使用一个训练样本来更新权重。

在实践中,随机梯度下降常常结合学习率衰减策略使用,以帮助算法更好地收敛。

Adam

当然可以。Adam(Adaptive Moment Estimation)是一种非常受欢迎的优化算法,特别是在深度学习领域。Adam 结合了 Momentum 和 RMSprop 的思想,因此经常被认为是这两种方法的变种。

以下是 Adam 算法的主要步骤:

  1. 计算梯度:
    首先,我们需要计算损失函数 J(θ) 关于参数 θ 的梯度。
  2. 计算第一矩估计 (与 Momentum 相似):
    这实际上是过去梯度的指数加权平均值。mt=β1mt1+(1β1)gt其中:
    • mt 是第 t 次迭代的第一矩估计。
    • β1 是第一矩的指数衰减速率,通常接近 1。
    • gt 是第 t 次迭代的梯度。
  3. 计算第二矩估计 (与 RMSprop 相似):
    这实际上是过去梯度平方的指数加权平均值
vt=β2vt1+(1β2)gt2

其中:

  1. 修正第一矩和第二矩的偏差:
    由于 mtvt 都被初始化为零,它们可能在开始时有偏差。为了纠正这种偏差,我们进行以下调整:
m^t=mt1β1tv^t=vt1β2t
  1. 更新参数:
    使用修正后的第一矩和第二矩来更新参数:θt=θt1αm^tv^t+ϵ其中:
    • α 是学习率。
    • ϵ 是一个非常小的数(例如 107),以防止分母为零。
      Adam 的主要优点之一是其自适应性。这意味着它可以自动调整每个参数的学习率,这使得它在许多问题上都表现得很好,尤其是在大规模和/或高维度的问题上。

常用的默认参数设置是:

这只是一个简要概述,Adam 算法还有许多细节和变种,但上述内容提供了其核心思想的概述。