梯度下降算法简介
梯度下降算法是深度学习中最为重要的优化算法之一,它被广泛用于神经网络的训练中。梯度下降算法通过寻找损失函数的最小值点来优化模型的参数。本文将介绍三种不同的梯度下降算法:批梯度下降法(Batch Gradient Descent)、随机梯度下降法(Stochastic Gradient Descent)和小批量梯度下降法(Mini-batch Gradient Descent)。
批梯度下降法 (Batch Gradient Descent)
批梯度下降法是最基本的梯度下降算法。它在每一次迭代时使用全部训练样本来计算损失函数关于参数的梯度,并更新参数。其具体算法原理如下:
-
初始化参数: $ \theta = \theta_{0} $
-
重复以下步骤直到收敛:
(a) 对于每个训练样本 $ (x^{(i)}, y^{(i)}) $,计算预测值 $ \hat{y}^{(i)} $
(b) 计算损失函数关于参数的偏导数 $ \dfrac{\partial J}{\partial \theta} $
(c) 更新参数: $ \theta = \theta – \alpha \dfrac{\partial J}{\partial \theta} $ (其中 $ \alpha $ 是学习率)
批梯度下降法计算梯度时需要遍历全部的训练数据,因此每个迭代步骤的计算量较大。优点是可以保证每次迭代都在最优解方向上前进,收敛速度相对较快。然而,对于大数据集而言,批梯度下降法会消耗大量的计算资源,难以处理。
随机梯度下降法 (Stochastic Gradient Descent)
随机梯度下降法是相对于批梯度下降法的一种改进。相比于每次迭代都使用全部训练样本来计算梯度,随机梯度下降法每次迭代只使用一个样本来计算梯度并更新参数。具体算法原理如下:
-
初始化参数: $ \theta = \theta_{0} $
-
重复以下步骤直到收敛:
(a) 随机选取一个训练样本 $ (x^{(i)}, y^{(i)}) $
(b) 计算预测值 $ \hat{y}^{(i)} $
(c) 计算损失函数关于参数的偏导数 $ \dfrac{\partial J^{(i)}}{\partial \theta} $
(d) 更新参数: $ \theta = \theta – \alpha \dfrac{\partial J^{(i)}}{\partial \theta} $
与批梯度下降法不同的是,随机梯度下降法在每次迭代时只需要处理一个样本,因此计算量较小。然而,由于每次迭代只考虑一个样本,随机梯度下降法的梯度估计可能带有较大的方差,收敛性较差,可能会陷入局部最优解。
小批量梯度下降法 (Mini-batch Gradient Descent)
小批量梯度下降法是批梯度下降法和随机梯度下降法的结合。在每次迭代时,小批量梯度下降法使用一小部分(大小为batch_size)的训练样本来计算梯度。具体算法原理如下:
-
初始化参数: $ \theta = \theta_{0} $
-
重复以下步骤直到收敛:
(a) 随机选择一个大小为batch_size的训练样本批次 $ {(x^{(i)}, y^{(i)})} $
(b) 计算预测值 $ \hat{y}^{(i)} $ (对于每个样本)
(c) 计算损失函数关于参数的偏导数 $ \dfrac{1}{batch_size}\sum_{i=1}^{batch_size} \dfrac{\partial J^{(i)}}{\partial \theta} $
(d) 更新参数: $ \theta = \theta – \alpha \dfrac{\partial J}{\partial \theta} $
小批量梯度下降法通过每次迭代只计算一小部分样本的梯度,既能减少计算量,又能减小梯度估计的方差,因此在实际应用中被广泛采用。
梯度下降算法之间的区别
批梯度下降法、随机梯度下降法和小批量梯度下降法是梯度下降算法的三种不同变体。它们在计算梯度的方式上有所不同,批梯度下降法使用全部训练样本,随机梯度下降法使用单个样本,小批量梯度下降法使用一小批训练样本。
批梯度下降法对于大数据集计算量较大,但收敛速度相对较快。随机梯度下降法计算量小,但收敛速度可能较慢,也可能陷入局部最优解。小批量梯度下降法在计算量和收敛速度间取得了平衡,因此被广泛使用。
使用批梯度下降法可以得到最优解,但代价是计算时间较长。使用随机梯度下降法和小批量梯度下降法计算时间较短,但最终得到的结果可能略有不同。因此,在实际应用中可以根据具体情况选择不同的梯度下降算法。
Python代码示例
下面是一个使用小批量梯度下降法训练神经网络的Python代码示例。假设我们要训练一个二分类网络来进行图像分类。
import numpy as np
import matplotlib.pyplot as plt
# 定义神经网络的结构和参数
input_size = 2
hidden_size = 4
output_size = 1
batch_size = 4
learning_rate = 0.1
# 生成虚拟数据集
np.random.seed(0)
X = np.random.rand(10, 2)
y = np.array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1]).reshape(-1, 1)
# 初始化参数
W1 = np.random.randn(input_size, hidden_size)
b1 = np.zeros((1, hidden_size))
W2 = np.random.randn(hidden_size, output_size)
b2 = np.zeros((1, output_size))
# 迭代训练
for epoch in range(1000):
# 随机打乱数据集
permutation = np.random.permutation(X.shape[0])
X = X[permutation]
y = y[permutation]
for i in range(0, X.shape[0], batch_size):
# 前向传播
X_batch = X[i:i+batch_size]
y_batch = y[i:i+batch_size]
hidden = np.dot(X_batch, W1) + b1
hidden_activation = 1 / (1 + np.exp(-hidden))
output = np.dot(hidden_activation, W2) + b2
output_activation = 1 / (1 + np.exp(-output))
# 计算损失函数
loss = np.mean((output_activation - y_batch) artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls 2)
# 反向传播
dLdoutput_activation = 2 artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls (output_activation - y_batch)
doutput_activation_doutput = output_activation artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls (1 - output_activation)
doutput_dW2 = hidden_activation
doutput_db2 = 1
doutput_dhidden_activation = W2
dhidden_activation_dhidden = hidden_activation artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls (1 - hidden_activation)
dhidden_dW1 = X_batch
dhidden_db1 = 1
dLdW2 = np.dot(doutput_dW2.T, dLdoutput_activation artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls doutput_activation_doutput)
dLdb2 = np.sum(dLdoutput_activation artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls doutput_activation_doutput, axis=0, keepdims=True)
dLdhidden_activation = np.dot(dLdoutput_activation artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls doutput_activation_doutput, doutput_dhidden_activation.T)
dLdhidden = dLdhidden_activation artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dhidden_activation_dhidden
dLdW1 = np.dot(dhidden_dW1.T, dLdhidden)
dLdb1 = np.sum(dLdhidden, axis=0, keepdims=True)
# 更新参数
W2 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dLdW2
b2 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dLdb2
W1 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dLdW1
b1 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dLdb1
# 每迭代100次打印损失函数
if (epoch + 1) % 100 == 0:
print(f"Epoch: {epoch+1}, Loss: {loss}")
# 绘制分类结果
h = 0.02
x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = np.dot(np.maximum(0, np.dot(np.c_[xx.ravel(), yy.ravel()], W1) + b1), W2) + b2
Z = np.round(1 / (1 + np.exp(-Z))).reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), cmap=plt.cm.Spectral)
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('Classification Boundary')
plt.show()
以上代码使用小批量梯度下降法训练一个简单的二分类神经网络,并绘制了分类结果。代码中使用了NumPy进行矩阵运算,matplotlib用于绘图。通过不断迭代调整参数,神经网络逐渐学习到了分类边界。其中的参数更新步骤对应着小批量梯度下降法的计算过程。
希望以上解答对您有所帮助!如果还有任何问题,请随时提问。
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/822385/
转载文章受原作者版权保护。转载请注明原作者出处!