03.PyTorch:张量 与 Autograd

0.引言

书接上回:

02.PyTorch张量_江湖人称桂某人的博客-CSDN博客PyTorch官方文档教程详解第二节,适合新手入门,非常详细https://blog.csdn.net/qq_39837305/article/details/128645166

在上一篇文章中,我们学习了如何使用pytorch网络的tensor实现正向传播以及用loss实现反向传播。今天继续来看看自动求导Autograd如何进行实现。

解决的问题还是一样:我们准备一个三阶多项式,通过最小化平方欧几里得距离来训练,并预测函数 y = sin(x) 在-pipi上的值。

1.造数据

import torch
import math
 
dtype = torch.float
device = torch.device("cpu")

x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype)
y = torch.sin(x)

和上一篇文章一样,不多说,造就完了。

2.随机初始化权重

a = torch.randn((), device=device, dtype=dtype, requires_grad=True)
b = torch.randn((), device=device, dtype=dtype, requires_grad=True)
c = torch.randn((), device=device, dtype=dtype, requires_grad=True)
d = torch.randn((), device=device, dtype=dtype, requires_grad=True)

这里就有所不同了,回忆一下上篇文章的写法:


a = torch.randn((), device=device, dtype=dtype)
b = torch.randn((), device=device, dtype=dtype)
c = torch.randn((), device=device, dtype=dtype)
d = torch.randn((), device=device, dtype=dtype)

 发现:多了一个参数,requires_grad=True,这个参数就是用于自动求导的参数。

3.训练

leatning_rate = 1e-6
for t in range(2000):
    # 正向传递:使用张量运算计算预测的y。
    y_pred = a + b * x + c * x ** 2 + d * x ** 3
    
    # 使用Tensors上的操作计算和打印损失。
    # 现在损失是形状(1,)的张量
    # loss.item()获取损失中保存的标量值。
    loss = (y_pred - y).pow(2).sum()
    if t % 100 == 99:
        print(t, loss.item())
    
    # 使用autograd计算反向通过。
    # 此调用将计算所有张量的损失梯度,其中requires_grad=True。
    # 在这一调用之后,a.grad、b.grad、c.grad和d.grad将分别是张量,
    # 分别保持损失相对于a、b、c、d的梯度。
    loss.backward()
    with torch.no_grad():
        a -= leatning_rate * a.grad
        b -= leatning_rate * b.grad
        c -= leatning_rate * c.grad
        d -= leatning_rate * d.grad
        # 更新权重后手动归零梯度
        a.grad = None
        b.grad = None
        c.grad = None
        d.grad = None

代码的注释我写的很详细,大家看一下就明白了。

这里我们再和上篇手动实现前向传播的过程进行对比:

learning_rate = 1e-6
for t in range(2000):
    # 正向传递:计算预测y
    y_pred = a + b * x + c * x ** 2 + d * x ** 3
 
    # 计算输出loss
    loss = (y_pred - y).pow(2).sum().item()
    if t % 100 == 99:
        print(t, loss)
 
    # 反向传播计算a,b,c,d的梯度损失
    grad_y_pred = 2.0 * (y_pred - y)
    grad_a = grad_y_pred.sum()
    grad_b = (grad_y_pred * x).sum()
    grad_c = (grad_y_pred * x ** 2).sum()
    grad_d = (grad_y_pred * x ** 3).sum()
 
    # 使用梯度下降更新权重
    a -= learning_rate * grad_a
    b -= learning_rate * grad_b
    c -= learning_rate * grad_c
    d -= learning_rate * grad_d

区别一目了然:

手动的过程中需要自己计算四个权重不断变化的值,而使用了自动求导,直接更新权重就可以了。

但是一定要注意的是:

在梯度计算前要加上loss.backward(),反向传播。

pytorch进行自动求导后的梯度是不会自动清零的,如果不手动清零会不断的叠加。

所以一定要在梯度更新后手动清零:a.grad=None或zero_grad()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值