PyTorch 自动微分示例

autograd 包是 PyTorch 中所有神经网络的核心。首先简要地介绍,然后训练第一个神经网络。autograd 软件包为 Tensors 上的所有算子提供自动微分。这是一个由运行定义的框架,以代码运行方式定义后向传播,并且每次迭代都可以不同。从 tensor 和 gradients 来举一些例子。

1、TENSOR

torch.Tensor 是包的核心类。如果将其属性 .requires_grad 设置为 True,则会开始跟踪针对 tensor 的所有操作。完成计算后,可以调用 .backward() 来自动计算所有梯度。该张量的梯度将累积到 .grad 属性中。

要停止 tensor 历史记录的跟踪,可以调用 .detach(),将其与计算历史记录分离,防止将来的计算被跟踪。

要停止跟踪历史记录(和使用内存),还可以将代码块使用 with torch.no_grad(): 包装起来。在评估模型时,这是特别有用,因为模型在训练阶段具有 requires_grad = True ,可训练参数有利于调参,但在评估阶段不需要梯度。

还有一个类对于 autograd 实现非常重要那就是 Function。Tensor 和 Function 互相连接并构建一个非循环图,保存整个完整的计算过程的历史信息。每个张量都有一个 .grad_fn 属性,保存着创建了张量的 Function 的引用,(如果用户自己创建张量,则g rad_fn 是 None )。

如果想计算导数,可以调用 Tensor.backward()。如果 Tensor 是标量(即包含一个元素数据),则不需要指定任何参数backward(),如果有更多元素,则需要指定一个gradient 参数来指定张量的形状。

import torch

创建一个张量,设置 requires_grad=True 来跟踪相关的计算

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

print(x)

输出:

tensor([[1., 1.],

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

针对张量做一个操作

y = x + 2

print(y)

输出:

tensor([[3., 3.],

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

y 作为操作的结果被创建,所以它有 grad_fn

print(y.grad_fn)

输出:

<AddBackward0 object at 0x7fe1db427470>

针对 y 做更多的操作:

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_( ... ) 会改变张量的 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 0x7fe1db427dd8>

梯度:

现在后向传播,因为输出包含了一个标量,out.backward() 等同于out.backward(torch.tensor(1.))。

out.backward()

打印梯度 d(out)/dx

print(x.grad)

输出:

tensor([[4.5000, 4.5000],

[4.5000, 4.5000]])

原理解释:

看一个雅可比向量积的例子:

x = torch.randn(3, requires_grad=True)

y = x * 2

while y.data.norm() < 1000:

y = y * 2

print(y)

输出:

tensor([ -444.6791,   762.9810, -1690.0941], grad_fn=<MulBackward0>)

在这种情况下,y 不再是一个标量。torch.autograd 不能够直接计算整个雅可比,但是如果想要雅可比向量积,需要简单的传递向量给 backward 作为参数。

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)

y.backward(v)

print(x.grad)

输出:

tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])

可以通过将代码包裹在 with torch.no_grad(),来停止对从跟踪历史中 的 .requires_grad=True 的张量自动求导。

print(x.requires_grad)

print((x ** 2).requires_grad)

with torch.no_grad():

print((x ** 2).requires_grad)

输出:

True

True

False

PyTorch 自动微分示例的更多相关文章

  1. PyTorch自动微分基本原理

    序言:在训练一个神经网络时,梯度的计算是一个关键的步骤,它为神经网络的优化提供了关键数据.但是在面临复杂神经网络的时候导数的计算就成为一个难题,要求人们解出复杂.高维的方程是不现实的.这就是自动微分出 ...

  2. PyTorch 自动微分

    PyTorch 自动微分 autograd 包是 PyTorch 中所有神经网络的核心.首先简要地介绍,然后将会去训练的第一个神经网络.该 autograd 软件包为 Tensors 上的所有操作提供 ...

  3. pytorch学习-AUTOGRAD: AUTOMATIC DIFFERENTIATION自动微分

    参考:https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#sphx-glr-beginner-blitz-autog ...

  4. <转>如何用C++实现自动微分

    作者:李瞬生转摘链接:https://www.zhihu.com/question/48356514/answer/123290631来源:知乎著作权归作者所有. 实现 AD 有两种方式,函数重载与代 ...

  5. MindSpore:自动微分

    MindSpore:自动微分 作为一款「全场景 AI 框架」,MindSpore 是人工智能解决方案的重要组成部分,与 TensorFlow.PyTorch.PaddlePaddle 等流行深度学习框 ...

  6. LibTorch 自动微分

    得益于反向传播算法,神经网络计算导数时非常方便,下面代码中演示如何使用LibTorch进行自动微分求导. 进行自动微分运算需要调用函数 torch::autograd::grad( outputs, ...

  7. 附录D——自动微分(Autodiff)

    本文介绍了五种微分方式,最后两种才是自动微分. 前两种方法求出了原函数对应的导函数,后三种方法只是求出了某一点的导数. 假设原函数是$f(x,y) = x^2y + y +2$,需要求其偏导数$\fr ...

  8. 自动微分(AD)学习笔记

    1.自动微分(AD) 作者:李济深链接:https://www.zhihu.com/question/48356514/answer/125175491来源:知乎著作权归作者所有.商业转载请联系作者获 ...

  9. Qt 编程指南 3_1 按钮弹窗手动和自动关联示例

    触发的两种模式 connect() 和 on_控件ID_控件函数(参数) 两者优缺点对比: 虽然 Qt 有比较好用的自动关联大法,但自动关联不是万能的,尤其是涉及到多个窗体的时候,比如 A 窗体私有按 ...

随机推荐

  1. 15- web安全测试与appscan Scrawlr的使用

    web应用安全性问题 认证与授权测试要点 认证与授权测试要点之授权 session与cookie之cookie测试点: session测试点: 上传文件漏洞 SQL注入 SQL注入原理 SQL注入检查 ...

  2. LA3602DNA序列

    题意:      给你一个一些DNA序列(只有ACGT)然后让你构造一个序列,使得所有的序列到他的Hamming距离最小,所有的序列包括构造的序列长度都是N,Hamming表示两个序列的不同字符位置个 ...

  3. JSONP跨域资源共享的安全问题

    目录 关于 JSONP 一.JSON 劫持 二.Callback 可定义导致的安全问题 三.其他文件格式( Content-Type )与 JSON 四.防御 摘自:http://blog.known ...

  4. Linux-鸟菜-1-Linux简介

    Linux-鸟菜-1-Linux简介 鸟哥这一章是介绍了Linux的由来以及建议怎么学Linux.很多也是建议性的东西,概念性的东西(当然我不是排斥概念).把最后鸟哥的汇总粘过来吧. 建议大家去看下这 ...

  5. 在kubernetes上运行WASM负载

    在kubernetes上运行WASM负载 WASM一般用在前端业务中,但目前有扩展到后端服务的趋势.本文使用Krustlet 将WASM服务部署到kubernetes. 简介 Krustlet 是一个 ...

  6. SpringBoot项目启动后自动打开浏览器

    编写一个类,注册为Spring的Bean,然后实现CommandLineRunner接口,重写run()方法即可 @Component public class OpenBrowser impleme ...

  7. IntelliJ IDEA中项目的包和目录结构显示设置

    在新建的目录下再创建一个新目录时,出现了目录没有分层显示,这样使用起来十分不方便. 解决方案:点击右上方的设置按钮,将"compact middle packages"取消勾选,实 ...

  8. java 运用Cipher加密再解密后会变乱码。解决方案!

    同样的方法类用main调用加解密都正常,就是当用到业务就是加密后再解密变乱码. 后来发现同样的内容加密后的内容竟不相同. 经调试发现 encryptData.getBytes() 转为字节是的使用 C ...

  9. Java初始化数据域的途径

    Java调用构造器的具体处理步骤: 1.所有数据域被初始化为默认值(0,false或null); 2.按照在类声明中出现的次序,依次执行所有域的初始化语句和初始化块: 3.如果构造器第一行调用了第二个 ...

  10. beta设计和计划

    项目 内容 课程:北航-2020-春-软件工程 博客园班级博客 要求 Beta设计和计划 我们在这个课程的目标是 提升团队管理及合作能力,开发一项满意的工程项目 这个作业在哪个具体方面帮助我们实现目标 ...