Pytorch使用optim模块训练线性回归模型
About-简介
在上一篇中利用PyTorch Autograd自动求导训练线性回归模型我们完成的程序,
其实还有进一步优化的空间,主要使用的就是PyTorch optim模块
所以我们本篇文章主要讲述通过optim模块优化此前的线性模型,主要包括以下几点:
- optim模块使用简介
- SGD 使用
- Adam 使用
optim模块使用简介
optim 是PyTorch中一系列优化算法的实现
主要包括以下几个方法:
import torch.optim as optim
dir(optim)
# Out
['ASGD',
'Adadelta',
'Adagrad',
'Adam',
'Adamax',
'LBFGS',
'Optimizer',
'RMSprop',
'Rprop',
'SGD',
'SparseAdam',
...
]
所有的优化算法接收 模型参数作为第一个参数,所有参数传递给 optimizer
后, optimizer自动更新参数以及其grad值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O8kdgana-1589374604646)(https://cdn.jsdelivr.net/gh/austinxishou/pics/feimao/20200513204541.png)]
每个 optimizer
都有两个对外方法 zero_grad
和 step
zero_grad
用于重置 grad 值为 0step
用于根据最新计算的grad值更新 parameters 参数值
基本使用如下
for input, target in dataset:
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
SGD 使用
SGD (Stochastic Gradient Descent) 随机梯度递减算法
简单的使用如下:
import torch.optim as optim
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-5
# SGD stands for Stochastic Gradient Descent. 随机梯度递减
optimizer = optim.SGD([params], lr=learning_rate)
# 执行 step 更新 params
t_p = model(t_u, *params)
loss = loss_fn(t_p, t_c)
loss.backward()
optimizer.step()
print(params)
代入loop循环
# 代入循环
def training_loop(n_epochs, optimizer, params, t_u, t_c):
for epoch in range(1, n_epochs + 1):
t_p = model(t_u, *params)
loss = loss_fn(t_p, t_c)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 500 == 0:
print('Epoch %d, Loss %f' % (epoch, float(loss)))
return params
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-2
optimizer = optim.SGD([params], lr=learning_rate)
params = training_loop(
n_epochs = 5000,
optimizer = optimizer,
params = params,
t_u = t_un,
t_c = t_c)
得到的结果跟我们前两篇文章一致
Adam 使用
Adam 优化算法提供了 学习速率的自适应,以及对模型参数的缩放不敏感;
这就使得我们在第一篇文章中遇到的梯度递减震荡,以及特征参数缩放的问题;
# 使用 Adam
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-1
optimizer = optim.Adam([params], lr=learning_rate)
params = training_loop(
n_epochs = 2000,
optimizer = optimizer,
params = params,
t_u = t_u,
t_c = t_c)
得到的结果也是一致
完整代码
"""
PyTorch 基础入门三: Pytorch使用optim模块训练线性回归模型
"""
import torch
# 定义输入数据
t_c = [0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0]
t_u = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]
t_c = torch.tensor(t_c)
t_u = torch.tensor(t_u)
# 对应的线性模型为
# t_c = w * t_u + b
def model(t_u, w, b):
return w*t_u + b
# 定义损失函数
# t_p 为模型估计值
# t_c 为实验数据
def loss_fn(t_p, t_c):
squared_diffs = (t_p - t_c)**2
return squared_diffs.mean()
# 以上跟第一篇保持一致
#########################################################################
import torch.optim as optim
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-5
# SGD stands for Stochastic Gradient Descent. 随机梯度递减
optimizer = optim.SGD([params], lr=learning_rate)
# 执行 step 更新 params
t_p = model(t_u, *params)
loss = loss_fn(t_p, t_c)
loss.backward()
optimizer.step()
print(params)
# 在每一步之前 执行 zero_grad
t_un = 0.1 * t_u
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-2
optimizer = optim.SGD([params], lr=learning_rate)
t_p = model(t_un, *params)
loss = loss_fn(t_p, t_c)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(params)
# 代入循环
def training_loop(n_epochs, optimizer, params, t_u, t_c):
for epoch in range(1, n_epochs + 1):
t_p = model(t_u, *params)
loss = loss_fn(t_p, t_c)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 500 == 0:
print('Epoch %d, Loss %f' % (epoch, float(loss)))
return params
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-2
optimizer = optim.SGD([params], lr=learning_rate)
params = training_loop(
n_epochs = 5000,
optimizer = optimizer,
params = params,
t_u = t_un,
t_c = t_c)
# 使用 Adam
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-1
optimizer = optim.Adam([params], lr=learning_rate)
params = training_loop(
n_epochs = 2000,
optimizer = optimizer,
params = params,
t_u = t_u,
t_c = t_c)
# 画出图示
import matplotlib.pyplot as plt
t_p = model(t_u, *params)
fig = plt.figure()
plt.title(u"PyTorch linear model")
plt.xlabel("Fahrenheit")
plt.ylabel("Celsius")
plt.plot(t_u.numpy(), t_p.detach().numpy())
plt.plot(t_u.numpy(), t_c.numpy(), 'o')
plt.show()