4.3 PyTorch便利的优化器

Posted 王小小小草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4.3 PyTorch便利的优化器相关的知识,希望对你有一定的参考价值。

欢迎订阅本专栏:《PyTorch深度学习实践》
订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html

  • 第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础。
  • 第三章:学习PyTorch如何读入各种外部数据
  • 第四章:利用PyTorch从头到尾创建、训练、评估一个模型,理解与熟悉PyTorch实现模型的每个步骤,用到的模块与方法。
  • 第五章:学习如何利用PyTorch提供的3种方法去创建各种模型结构。
  • 第六章:利用PyTorch实现简单与经典的模型全过程:简单二分类、手写字体识别、词向量的实现、自编码器实现。
  • 第七章利用PyTorch实现复杂模型:翻译机(nlp领域)、生成对抗网络(GAN)、强化学习(RL)、风格迁移(cv领域)。
  • 第八章:PyTorch的其他高级用法:模型在不同框架之间的迁移、可视化、多个GPU并行计算。

4.2节介绍了自动求导机制,求出梯度(params.grad)后,我们进行了手动更新:params = (params - learning_rate * params.grad).detach().requires_grad_(), 这里使用的是最常用的SGD梯度优化方法。

Pytorch封装了多种多样的优化器供大家使用,无需手动写出优化的公式,只需要调用接口定义即可。来看一看吧~

4.3.1 初识

首先来看看pytorch提供了哪些优化器:

import torch.optim as optim

print(dir(optim))
['ASGD', 'Adadelta', 'Adagrad', 'Adam', 'Adamax', 'LBFGS', 'Optimizer', 'RMSprop', 'Rprop', 'SGD', 'SparseAdam', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'lr_scheduler']

每个优化器都提供两个方法:

  • zero_grad: 将传给优化器的所有变量的梯度都置零
  • step: 更具优化器的优化策略来更新传入的变量的值

仍然沿用之前的例子:

import torch

# 构建模型函数
def model(x, w, b):
    return w*x + b

# 构建损失函数
def loss_fn(y_p, y):
    squared_diffs = (y_p - y) ** 2
    return squared_diffs.mean()

# x与y
x = [0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0]
y = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]
x = torch.tensor(x)
y = torch.tensor(y)
x = 0.1 * x

# 初始化参数
params = torch.tensor([1.0, 0.0], requires_grad=True)

# 构建优化器
learning_rate = 1e-5
optimizer = optim.SGD([params], lr=learning_rate)  # 注意这里(新增步骤)

# 前向计算
y_p = model(x, *params)
loss = loss_fn(y_p, y)

# 后向计算
optimizer.zero_grad()  # 将优化器中的所有变量的梯度都置零
loss.backward()  # 反向计算
optimizer.step()  # 更新参数

print(params)


tensor([1.0013, 0.0010], requires_grad=True)

以上过程中,我们没有手动更新params,而是通过optimizer.step()进行自动更新,打印出来的pramas也确实被更新了。

4.3.2 完整迭代过程

上面是进行了一次迭代,下面来看看完整的迭代过程:

def training_loop(n_epochs, optimizer, params, x, y):
    for epoch in range(1, n_epochs+1):
        y_p = model(x, *params)
        loss = loss_fn(y_p, y)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if epoch % 100 == 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)

training_loop(
    n_epochs = 1000,
    optimizer = optimizer,
    params = params,
    x = x,
    y = y
)
Epoch 100, Loss 39.538250
Epoch 200, Loss 18.696901
Epoch 300, Loss 12.456582
Epoch 400, Loss 10.581183
Epoch 500, Loss 10.017575
Epoch 600, Loss 9.848182
Epoch 700, Loss 9.797276
Epoch 800, Loss 9.781981
Epoch 900, Loss 9.777378
Epoch 1000, Loss 9.776002





tensor([17.9473, 32.9443], requires_grad=True)

总结:

  • torch.optim 提供多类优化器
  • 优化器有2个方法:zero_grad, step

以上是关于4.3 PyTorch便利的优化器的主要内容,如果未能解决你的问题,请参考以下文章

PyTorch-18 使用Torchtext进行语言翻译(德语到英语)

翻译: 3.2. 从零开始实现线性回归 深入神经网络 pytorch

翻译: 4.多层感知器 pytorch

以optim.SGD为例介绍pytorch优化器

Pytorch优化器全总结常用优化器性能对比 含代码

翻译: 4.2. 从零开始实现多层感知器MLP pytorch