Pytorch中的autograd详解

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pytorch中的autograd详解相关的知识,希望对你有一定的参考价值。

学习目标

  • 掌握自动求导中的Tensor概念和操作.

  • 掌握自动求导中的梯度Gradients概念和操作.

  • 在整个Pytorch框架中, 所有的神经网络本质上都是一个autograd package(自动求导工具包)

    • autograd package提供了一个对Tensors上所有的操作进行自动微分的功能.

1. 关于torch.Tensor

  • torch.Tensor是整个package中的核心类, 如果将属性.requires_grad设置为True, 它将追踪在这个类上定义的所有操作. 当代码要进行反向传播的时候, 直接调用.backward()就可以自动计算所有的梯度. 在这个Tensor上的所有梯度将被累加进属性.grad中.

  • 如果想终止一个Tensor在计算图中的追踪回溯, 只需要执行.detach()就可以将该Tensor从计算图中撤下, 在未来的回溯计算中也不会再计算该Tensor.

  • 除了.detach(), 如果想终止对计算图的回溯, 也就是不再进行方向传播求导数的过程, 也可以采用代码块的方式with torch.no_grad():, 这种方式非常适用于对模型进行预测的时候, 因为预测阶段不再需要对梯度进行计算.

  • 关于torch.Function

  • Function类是和Tensor类同等重要的一个核心类, 它和Tensor共同构建了一个完整的类, 每一个Tensor拥有一个.grad_fn属性, 代表引用了哪个具体的Function创建了该Tensor.

  • 如果某个张量Tensor是用户自定义的, 则其对应的grad_fn is None.

2. 关于Tensor的操作

x1 = torch.ones(3, 3)
print(x1)

x = torch.ones(2, 2, requires_grad=True)
print(x)

输出结果:

tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])

tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

在具有requires_grad=TrueTensor上执行一个加法操作:

y = x + 2
print(y)

输出结果:

tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)

打印Tensor的grad_fn属性:

print(x.grad_fn)
print(y.grad_fn)

输出结果:

None
<AddBackward0 object at 0x10db11208>

在Tensor上执行更复杂的操作:

z = y * y * 3
out = z.mean()
print(z, out)

输出结果:

tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)

关于方法.requires_grad_():该方法可以原地改变Tensor的属性.requires_grad的值. 如果没有主动设定默认为False.

a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)

输出结果:

False
True
<SumBackward0 object at 0x7f191afd6be0>

3. 关于梯度Gradients

Pytorch中, 反向传播是依靠.backward()实现的.

out.backward()
print(x.grad)

输出结果:

tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])
  • 关于自动求导的属性设置: 可以通过设置.requires_grad=True来执行自动求导, 也可以通过代码块的限制来停止自动求导.
print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
    print((x ** 2).requires_grad)

输出结果:

True
True
False

可以通过.detach()获得一个新的Tensor, 拥有相同的内容但不需要自动求导.

print(x.requires_grad)
y = x.detach()
print(y.requires_grad)
print(x.eq(y).all())

输出结果:

True
False
tensor(True)

4. 总结

  • 学习了torch.Tensor类的相关概念.
    • torch.Tensor是整个package中的核心类, 如果将属性.requires_grad设置为True, 它将追踪在这个类上定义的所有操作. 当代码要进行反向传播的时候, 直接调用.backward()就可以自动计算所有的梯度. 在这个Tensor上的所有梯度将被累加进属性.grad中.
    • 执行.detach()命令, 可以将该Tensor从计算图中撤下, 在未来的回溯计算中不会再计算该Tensor.
    • 采用代码块的方式也可以终止对计算图的回溯
      • with torch.no_grad():
  • 学习了关于Tensor的若干操作:
    • torch.ones(n, n, requires_grad=True)
    • x.grad_fn
    • a.requires_grad_(True)
  • 学习了关于Gradients的属性:
    • x.grad
    • 可以通过.detach()获得一个新的Tensor, 拥有相同的内容但不需要自动求导.

加油!

感谢!

努力!

以上是关于Pytorch中的autograd详解的主要内容,如果未能解决你的问题,请参考以下文章

Pytorch 文档中的 Autograd 函数

WGAN-GP 的 Pytorch Autograd 中的内存泄漏

pytorch 中的 autograd 可以处理同一模块中层的重复使用吗?

[Pytorch系列-22]:Pytorch基础 - Autograd库 Autograd.Function与反向自动求导机制

PyTorch autograd -- 只能为标量输出隐式创建 grad

pytorch 中张量的 Autograd.grad()