RMSProp 和 Adadelta 算法
在深度学习中,RMSProp 和 Adadelta 是两种常见的优化算法。它们都是在 AdaGrad 的基础上做了改进,以适应深度学习中的大规模参数优化需求。
RMSProp 算法
基本思想
RMSProp 对 AdaGrad 进行改进,通过引入衰减率来调整二阶动量的累积。这样可以避免 AdaGrad 中学习率过快减小的问题。
AdaGrad 的二阶动量计算公式如下:
\[ v_t = v_{t-1} + g_t^2 \]
而 RMSProp 采用了带有衰减率的计算方式:
\[ v_t = \beta v_{t-1} + (1 - \beta) g_t^2 \]
其中,\( \beta \) 是衰减率系数。
优缺点
优点:
-
自动调整学习率,加速收敛速度。
-
避免学习率过大或过小的问题。
-
简单适用,适用于各种优化问题。
缺点:
-
在处理稀疏特征时不够优秀。
-
需要调整的超参数较多(衰减率 \( \beta \) 和学习率 \( \alpha \))。
-
收敛速度可能不如某些更先进的优化算法。
代码实现
python
import torch
import matplotlib.pyplot as plt
# 定义超参数
learning_rate = 0.01
epochs = 100
beta = 0.9
# 随机生成数据
x = torch.randn(100, 1)
y = 2 * x + 3 + torch.randn(100, 1) * 0.5
# 初始化参数
w = torch.randn(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
# 定义RMSProp优化器
optimizer = torch.optim.RMSprop([w, b], lr=learning_rate, alpha=beta)
# 记录损失
losses = []
for epoch in range(epochs):
# 预测
y_pred = x * w + b
# 计算损失
loss = torch.mean((y_pred - y) ** 2)
losses.append(loss.item())
# 清空梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 可视化训练过程
plt.plot(range(epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss with RMSProp')
plt.show()
Adadelta 算法
基本思想
Adadelta 是对 RMSProp 的进一步改进,旨在自动调整学习率,避免手动调参。它通过计算梯度和权重更新量的累积值来调整学习率,使得训练过程更加稳定。
Adadelta 的公式如下:
- 梯度的累积:
\[ E[g^2]t = \rho E[g^2]{t-1} + (1 - \rho) g_t^2 \]
- 权重更新量的累积:
\[ E[\Delta x^2]t = \rho E[\Delta x^2]{t-1} + (1 - \rho) (\Delta x_t)^2 \]
- 更新参数:
\[ \Delta x_t = -\frac{\sqrt{E[\Delta x^2]_{t-1} + \epsilon}}{\sqrt{E[g^2]_t + \epsilon}} g_t \]
\[ \theta_{t+1} = \theta_t + \Delta x_t \]
优缺点
优点:
-
不需要手动调整学习率,节省调参时间。
-
避免出现学习率饱和现象,使得训练更加稳定。
缺点:
-
可能收敛较慢。
-
需要维护梯度和权重更新量的累积值,增加了空间复杂度。
代码实现
python
import torch
import matplotlib.pyplot as plt
# 定义超参数
learning_rate = 1.0 # Adadelta 不需要传统的学习率
epochs = 100
rho = 0.9
epsilon = 1e-6
# 随机生成数据
x = torch.randn(100, 1)
y = 2 * x + 3 + torch.randn(100, 1) * 0.5
# 初始化参数
w = torch.randn(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
# 定义Adadelta优化器
optimizer = torch.optim.Adadelta([w, b], rho=rho, eps=epsilon)
# 记录损失
losses = []
for epoch in range(epochs):
# 预测
y_pred = x * w + b
# 计算损失
loss = torch.mean((y_pred - y) ** 2)
losses.append(loss.item())
# 清空梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 可视化训练过程
plt.plot(range(epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss with Adadelta')
plt.show()
接下来,我们将介绍目前常用的梯度下降法中的王者------Adam算法。
Adam 算法
Adam(Adaptive Moment Estimation)是目前深度学习中最常用的优化算法之一。它结合了动量法和 RMSProp 的优点,通过计算一阶和二阶动量来动态调整学习率,具有较快的收敛速度和较高的稳定性。
基本思想
Adam 算法利用梯度的一阶动量(即梯度的指数加权平均)和梯度的二阶动量(即梯度平方的指数加权平均)来调整每个参数的学习率。具体公式如下:
- 梯度的一阶动量:
\[ m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t \]
- 梯度的二阶动量:
\[ v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 \]
- 偏差修正:
\[ \hat{m}_t = \frac{m_t}{1 - \beta_1^t} \]
\[ \hat{v}_t = \frac{v_t}{1 - \beta_2^t} \]
- 更新参数:
\[ \theta_{t+1} = \theta_t - \frac{\alpha \hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} \]
其中:
-
\( \beta_1 \) 和 \( \beta_2 \) 分别是动量和均方根动量的衰减率,常用值为 \( \beta_1 = 0.9 \) 和 \( \beta_2 = 0.999 \)。
-
\( \epsilon \) 是一个很小的常数,用于防止分母为零,常用值为 \( 10^{-8} \)。
优缺点
优点 :
-
自适应调整学习率,训练过程稳定,收敛速度快。
-
能处理稀疏梯度,适用于大规模数据和参数。
-
几乎不需要调整学习率等超参数。
缺点 :
-
对于某些特定问题,可能会出现不稳定的收敛行为。
-
参数调整多,超参数较多,调参复杂度高。
代码实现
python
import torch
import matplotlib.pyplot as plt
# 定义超参数
learning_rate = 0.001
epochs = 100
# 随机生成数据
x = torch.randn(100, 1)
y = 2 * x + 3 + torch.randn(100, 1) * 0.5
# 初始化参数
w = torch.randn(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
# 定义Adam优化器
optimizer = torch.optim.Adam([w, b], lr=learning_rate)
# 记录损失
losses = []
for epoch in range(epochs):
# 预测
y_pred = x * w + b
# 计算损失
loss = torch.mean((y_pred - y) ** 2)
losses.append(loss.item())
# 清空梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 可视化训练过程
plt.plot(range(epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss with Adam')
plt.show()
小结
Adam 算法作为一种自适应的梯度下降优化算法,结合了动量法和 RMSProp 的优点,能够有效地加速模型的收敛,同时保持稳定性。它通过计算一阶和二阶动量来动态调整学习率,使得模型在训练过程中能够快速收敛,并适应不同的优化问题。尽管 Adam 需要调整的超参数较多,但其优越的性能使得它成为深度学习中最广泛使用的优化算法之一。
通过学习 Adam 算法,我们不仅掌握了一种先进的优化技术,还了解了深度学习中优化算法的发展历程和演进过程。希望大家能将这些知识应用到实际项目中,提升模型的性能和训练效率。