目录标题
一、AdaGrad
AdaGrad(Adaptive Gradient,自适应梯度)会为每个参数适当地调整学习率,并且随着学习的进行,梯度会逐渐减小。
H ← H + ∇ 2 H \leftarrow H + \nabla^2 H←H+∇2
W ← W − η 1 H ∇ W \leftarrow W - \eta \frac{1}{\sqrt{H}} \nabla W←W−ηH 1∇
H H H:历史梯度的平方和
可以通过 torch.optim.Adagrad() 来使用 AdaGrad。
同样以寻找 f ( x 1 , x 2 ) = 0.05 x 1 2 + x 2 2 f(x_1, x_2) = 0.05x_1^2 + x_2^2 f(x1,x2)=0.05x12+x22 的最小值为例:

python
import torch
import numpy as np
import matplotlib.pyplot as plt
from torch.optim import SGD,Adagrad
# 定义函数
def f(X):
return 0.05 * X[0] ** 2 + X[1] ** 2
# 定义函数,实现梯度下降法
def gradient_descent(X, optimizer, num_iters):
# 拷贝当前X的值,放入列表中
X_arr = X.detach().numpy().copy()
for i in range(num_iters):
# 1. 前向传播,得到"损失值"
y = f(X)
# 2. 反向传播
y.backward()
# 3. 更新参数
optimizer.step()
# 4. 梯度清零
optimizer.zero_grad()
# 将更新之后的X,保存到列表中
X_arr = np.vstack((X_arr, X.detach().numpy()))
return X_arr
# 主流程
# 1. 参数X初始化
X = torch.tensor(data=[-7.0, 2.0], requires_grad=True)
# 2. 定义超参数
lr = 0.9
num_iters = 500
# 3. 优化器对比
# 3.1 SGD
X_clone = X.clone().detach().requires_grad_(True)
optimizer = SGD(params=[X_clone], lr=lr)
# 梯度下降
X_arr1 = gradient_descent(X_clone, optimizer, num_iters)
# 画出点轨迹
plt.plot(X_arr1[:, 0], X_arr1[:, 1], 'r')
# 3.2 AdaGrad法
X_clone = X.clone().detach().requires_grad_(True)
optimizer = Adagrad(params=[X_clone], lr=lr)
# 梯度下降
X_arr2 = gradient_descent(X_clone, optimizer, num_iters)
# 画出点轨迹
plt.plot(X_arr2[:, 0], X_arr2[:, 1], 'b')
# 画出等高线
x1_grid, x2_grid = np.meshgrid(np.linspace(-7, 7, 100), np.linspace(-2, 2, 100))
y_grid = 0.05 * x1_grid ** 2 + x2_grid ** 2
plt.contour(x1_grid, x2_grid, y_grid, levels=30, colors='gray')
plt.legend(["SGD", "AdaGrad"])
# plt.show()
plt.savefig('AdaGrad_result.png')
二、RMSProp
RMSProp(Root Mean Square Propagation,均方根传播)是在 AdaGrad 基础上的改进,它并非将过去所有梯度一视同仁的相加,而是逐渐遗忘过去的梯度,采用指数移动加权平均,呈指数地减小过去梯度的尺度。
H ← α H + ( 1 − α ) ∇ 2 H \leftarrow \alpha H + (1 - \alpha)\nabla^2 H←αH+(1−α)∇2
W ← W − η 1 H ∇ W \leftarrow W - \eta \frac{1}{\sqrt{H}} \nabla W←W−ηH 1∇
H H H:历史梯度平方和的指数移动加权平均
α \alpha α:权重
可以通过 torch.optim.RMSprop() 并设置 alpha 权重参数来使用 RMSprop。
同样以寻找 f ( x 1 , x 2 ) = 0.05 x 1 2 + x 2 2 f(x_1, x_2) = 0.05x_1^2 + x_2^2 f(x1,x2)=0.05x12+x22 的最小值为例:

python
import torch
import numpy as np
import matplotlib.pyplot as plt
from torch.optim import SGD,RMSprop
# 定义函数
def f(X):
return 0.05 * X[0] ** 2 + X[1] ** 2
# 定义函数,实现梯度下降法
def gradient_descent(X, optimizer, num_iters):
# 拷贝当前X的值,放入列表中
X_arr = X.detach().numpy().copy()
for i in range(num_iters):
# 1. 前向传播,得到"损失值"
y = f(X)
# 2. 反向传播
y.backward()
# 3. 更新参数
optimizer.step()
# 4. 梯度清零
optimizer.zero_grad()
# 将更新之后的X,保存到列表中
X_arr = np.vstack((X_arr, X.detach().numpy()))
return X_arr
# 主流程
# 1. 参数X初始化
X = torch.tensor(data=[-7.0, 2.0], requires_grad=True)
# 2. 定义超参数
lr = 0.1
num_iters = 500
# 3. 优化器对比
# 3.1 SGD
X_clone = X.clone().detach().requires_grad_(True)
optimizer = SGD(params=[X_clone], lr=lr)
# 梯度下降
X_arr1 = gradient_descent(X_clone, optimizer, num_iters)
# 画出点轨迹
plt.plot(X_arr1[:, 0], X_arr1[:, 1], 'r')
# 3.2 RMSprop法
X_clone = X.clone().detach().requires_grad_(True)
optimizer = RMSprop(params=[X_clone], lr=lr,alpha=0.9)
# 梯度下降
X_arr2 = gradient_descent(X_clone, optimizer, num_iters)
# 画出点轨迹
plt.plot(X_arr2[:, 0], X_arr2[:, 1], 'b')
# 画出等高线
x1_grid, x2_grid = np.meshgrid(np.linspace(-7, 7, 100), np.linspace(-2, 2, 100))
y_grid = 0.05 * x1_grid ** 2 + x2_grid ** 2
plt.contour(x1_grid, x2_grid, y_grid, levels=30, colors='gray')
plt.legend(["SGD", "RMSProp"])
# plt.show()
plt.savefig('RMSProp_result.png')