梯度
梯度下降(Gradient Descent)是一种迭代的优化算法,用于寻找函数的局部最小值。在机器学习和深度学习中,梯度下降常被用于优化损失函数以训练模型。以下是梯度下降的一些常见变种:
- 批量梯度下降(Batch Gradient Descent):
- 使用整个训练集计算梯度。
- 确定的收敛路径,但可能在大数据集上很慢。
- 随机梯度下降(Stochastic Gradient Descent, SGD):
- 在每次迭代中只使用一个训练样本来计算梯度。
- 更快,但收敛路径可能会有很大的波动。
- 通常使用学习率衰减策略来帮助算法收敛。
- 小批量梯度下降(Mini-batch Gradient Descent):
- 使用一个小批量的训练样本计算梯度,这个小批量的大小介于批量梯度下降和随机梯度下降之间。
- 常用于实践中,因为它结合了批量梯度下降和随机梯度下降的优点。
- 动量梯度下降(Momentum):
- 结合了之前的梯度来加速收敛,并克服了波动。
- 使用“动量”项,该项是之前梯度的加权平均,以获得更平滑的更新路径。
- Adagrad:
- 对每个参数都有一个独特的学习率。
- 适用于稀疏数据。
- RMSprop(Root Mean Square Propagation):
- 是Adagrad的改进版本,通过移动平均来解决Adagrad学习率急剧下降的问题。
- Adam(Adaptive Moment Estimation):
- 结合了动量和RMSprop的思想。
- 在实践中被广泛使用,因为它通常表现得很好。
- Adadelta:
- 是Adagrad的另一个改进版本,不需要设置默认学习率。
- Nadam:
- 结合了Adam和Nesterov的动量。
以上只是梯度下降的一些常见变种。在实践中,通常需要根据具体的问题和数据集来选择和调整合适的优化算法。
- 结合了Adam和Nesterov的动量。
批量梯度下降
好的,我将为您实现批量梯度下降(Batch Gradient Descent)算法。为了简化,我们将使用线性回归作为示例。
考虑线性回归的损失函数(均方误差):
其中:
是训练样本的数量。 是假设函数,定义为 。 是模型的参数。 是特征向量,其中 。
梯度更新规则为:
其中
对于线性回归,梯度为:
接下来,我将实现批量梯度下降算法:
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
使用批量梯度下降算法优化线性回归模型后,我们得到了以下结果:
- 参数
的估计值为: - 在最后五次迭代中,损失函数的值为:
- 0.00039373378337961677
- 0.0003925558650595537
- 0.0003913814706727389
- 0.00039021058967674856
- 0.00038904321156071344
这些损失值表明,随着迭代的进行,模型的损失在逐渐减小,这意味着梯度下降算法正在有效地优化模型。
请注意,本示例使用了一个简单的线性数据集。在实际应用中,可能需要更多的迭代次数和调整学习率来达到最优解。
随机梯度下降(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
使用随机梯度下降算法优化线性回归模型后,我们得到了以下结果:
- 参数
的估计值为:8.34110758e-04, 9.99673778e-01 - 在最后五次迭代中,平均损失函数的值为:
请注意,与批量梯度下降相比,随机梯度下降的收敛路径可能更加嘈杂,并且可能不会像批量梯度下降那样平滑地逼近最小值。这是因为每次迭代时只使用一个训练样本来更新权重。
在实践中,随机梯度下降常常结合学习率衰减策略使用,以帮助算法更好地收敛。
Adam
当然可以。Adam(Adaptive Moment Estimation)是一种非常受欢迎的优化算法,特别是在深度学习领域。Adam 结合了 Momentum 和 RMSprop 的思想,因此经常被认为是这两种方法的变种。
以下是 Adam 算法的主要步骤:
- 计算梯度:
首先,我们需要计算损失函数关于参数 的梯度。 - 计算第一矩估计 (与 Momentum 相似):
这实际上是过去梯度的指数加权平均值。其中: 是第 次迭代的第一矩估计。 是第一矩的指数衰减速率,通常接近 1。 是第 次迭代的梯度。
- 计算第二矩估计 (与 RMSprop 相似):
这实际上是过去梯度平方的指数加权平均值
其中:
是第 次迭代的第二矩估计。 是第二矩的指数衰减速率,通常也很接近 1。
- 修正第一矩和第二矩的偏差:
由于和 都被初始化为零,它们可能在开始时有偏差。为了纠正这种偏差,我们进行以下调整:
- 更新参数:
使用修正后的第一矩和第二矩来更新参数:其中: 是学习率。 是一个非常小的数(例如 ),以防止分母为零。
Adam 的主要优点之一是其自适应性。这意味着它可以自动调整每个参数的学习率,这使得它在许多问题上都表现得很好,尤其是在大规模和/或高维度的问题上。
常用的默认参数设置是:
这只是一个简要概述,Adam 算法还有许多细节和变种,但上述内容提供了其核心思想的概述。