Autograd: 自动求导机制

PyTorch 中所有神经网络的核心是 autograd 包。
我们先简单介绍一下这个包,然后训练第一个简单的神经网络。

autograd包为张量上的所有操作提供了自动求导。
它是一个在运行时定义的框架,这意味着反向传播是根据你的代码来确定如何运行,并且每次迭代可以是不同的。

示例

张量(Tensor)

torch.Tensor是这个包的核心类。如果设置
.requires_gradTrue,那么将会追踪所有对于该张量的操作。
当完成计算后通过调用 .backward(),自动计算所有的梯度,
这个张量的所有梯度将会自动积累到 .grad 属性。

要阻止张量跟踪历史记录,可以调用.detach()方法将其与计算历史记录分离,并禁止跟踪它将来的计算记录。

为了防止跟踪历史记录(和使用内存),可以将代码块包装在with torch.no_grad():中。
在评估模型时特别有用,因为模型可能具有requires_grad = True的可训练参数,但是我们不需要梯度计算。

在自动梯度计算中还有另外一个重要的类Function.

Tensor and Function are interconnected and build up an acyclic
graph, that encodes a complete history of computation. Each tensor has
a .grad_fn attribute that references a Function that has created
the Tensor (except for Tensors created by the user - their
grad_fn is None).

TensorFunction互相连接并生成一个非循环图,它表示和存储了完整的计算历史。
每个张量都有一个.grad_fn属性,这个属性引用了一个创建了TensorFunction(除非这个张量是用户手动创建的,即,这个张量的
grad_fnNone)。

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

译者注:在其他的文章中你可能会看到说将Tensor包裹到Variable中提供自动梯度计算,Variable 这个在0.41版中已经被标注为过期了,现在可以直接使用Tensor,官方文档在这里:
https://pytorch.org/docs/stable/autograd.html#variable-deprecated

具体的后面会有详细说明

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 0x000002004F7CC248>

对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属性。
如果没有指定的话,默认输入的flag是 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 0x000002004F7D5608>

梯度

反向传播
因为 out是一个纯量(scalar),out.backward() 等于out.backward(torch.tensor(1))

out.backward()

print gradients d(out)/dx

print(x.grad)
tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])

得到矩阵 4.5.将 out叫做
Tensor

o

o

o”.

得到

o

=

1

4

i

z

i

o = \frac{1}{4}\sum_i z_i

o=41​∑i​zi​,

z

i

=

3

(

x

i

+

2

)

2

z_i = 3(x_i+2)^2

zi​=3(xi​+2)2 和

z

i

x

i

=

1

=

27

z_i\bigr\rvert_{x_i=1} = 27

zi​∣∣​xi​=1​=27.

因此,

o

x

i

=

3

2

(

x

i

+

2

)

\frac{\partial o}{\partial x_i} = \frac{3}{2}(x_i+2)

∂xi​∂o​=23​(xi​+2), 则

o

x

i

x

i

=

1

=

9

2

=

4.5

\frac{\partial o}{\partial x_i}\bigr\rvert_{x_i=1} = \frac{9}{2} = 4.5

∂xi​∂o​∣∣​xi​=1​=29​=4.5.

在数学上,如果我们有向量值函数

y

=

f

(

x

)

)

\vec{y} = f(\vec{x}))

y

​=f(x

)) ,且

y

\vec{y}

y

​ 关于

x

\vec{x}

x

的梯度是一个雅可比矩阵(Jacobian matrix):

J

=

(

y

1

x

1

y

1

x

n

y

m

x

1

y

m

x

n

)

J = \begin{pmatrix} \frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{1}}{\partial x_{n}} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_{m}}{\partial x_{1}} & \cdots & \frac{\partial y_{m}}{\partial x_{n}} \end{pmatrix}

J=⎝⎜⎛​∂x1​∂y1​​⋮∂x1​∂ym​​​⋯⋱⋯​∂xn​∂y1​​⋮∂xn​∂ym​​​⎠⎟⎞​

一般来说,torch.autograd就是用来计算vector-Jacobian product的工具。也就是说,给定任一向量

v

=

(

v

1

  

v

2

  


  

v

m

)

T

v=(v_{1}\;v_{2}\;\cdots\;v_{m})^{T}

v=(v1​v2​⋯vm​)T ,计算

v

T

J

v^{T}\cdot J

vT⋅J ,如果

v

v

v 恰好是标量函数

l

=

g

(

y

)

l=g(\vec{y})

l=g(y

​) 的梯度,也就是说

v

=

(

l

y

1

  


  

l

y

m

)

T

v=(\frac{\partial l}{\partial y_{1}}\;\cdots\;\frac{\partial l}{\partial y_{m}})^{T}

v=(∂y1​∂l​⋯∂ym​∂l​)T,那么根据链式法则,vector-Jacobian product 是

x

\vec{x}

x

l

l

l 的梯度:

J

T

v

=

(

y

1

x

1

y

m

x

1

y

1

x

n

y

m

x

n

)

(

l

y

1

l

y

m

)

=

(

l

x

1

l

x

n

)

J^{T}\cdot v = \begin{pmatrix} \frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{m}}{\partial x_{1}} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_{1}}{\partial x_{n}} & \cdots & \frac{\partial y_{m}}{\partial x_{n}} \end{pmatrix} \begin{pmatrix} \frac{\partial l}{\partial y_{1}}\\ \vdots \\ \frac{\partial l}{\partial y_{m}} \end{pmatrix} = \begin{pmatrix} \frac{\partial l}{\partial x_{1}}\\ \vdots \\ \frac{\partial l}{\partial x_{n}} \end{pmatrix}

JT⋅v=⎝⎜⎛​∂x1​∂y1​​⋮∂xn​∂y1​​​⋯⋱⋯​∂x1​∂ym​​⋮∂xn​∂ym​​​⎠⎟⎞​⎝⎜⎛​∂y1​∂l​⋮∂ym​∂l​​⎠⎟⎞​=⎝⎜⎛​∂x1​∂l​⋮∂xn​∂l​​⎠⎟⎞​

(注意,

v

T

J

v^{T}\cdot J

vT⋅J 给出了一个行向量,可以通过

J

T

v

J^{T}\cdot v

JT⋅v 将其视为列向量)

vector-Jacobian product 这种特性使得将外部梯度返回到具有非标量输出的模型变得非常方便。

现在让我们来看一个vector-Jacobian product的例子

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

y = x * 2
while y.data.norm() < 1000:
y = y * 2 print(y)
tensor([ 293.4463,   50.6356, 1031.2501], grad_fn=<MulBackward0>)

在这个情形中,y不再是个标量。torch.autograd无法直接计算出完整的雅可比行列,但是如果我们只想要vector-Jacobian product,只需将向量作为参数传入backward

gradients = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(gradients) print(x.grad)
tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])

如果.requires_grad=True但是你又不希望进行autograd的计算,
那么可以将变量包裹在 with torch.no_grad()中:

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

稍后阅读:

autogradFunction 的官方文档 https://pytorch.org/docs/autograd

[Pytorch框架] 1.4 Autograd:自动求导的更多相关文章

  1. Pytorch Autograd (自动求导机制)

    Pytorch Autograd (自动求导机制) Introduce Pytorch Autograd库 (自动求导机制) 是训练神经网络时,反向误差传播(BP)算法的核心. 本文通过logisti ...

  2. Pytorch学习(一)—— 自动求导机制

    现在对 CNN 有了一定的了解,同时在 GitHub 上找了几个 examples 来学习,对网络的搭建有了笼统地认识,但是发现有好多基础 pytorch 的知识需要补习,所以慢慢从官网 API进行学 ...

  3. 什么是pytorch(2Autograd:自动求导)(翻译)

    Autograd: 自动求导 pyTorch里神经网络能够训练就是靠autograd包.我们来看下这个包,然后我们使用它来训练我们的第一个神经网络. autograd 包提供了对张量的所有运算自动求导 ...

  4. PytorchZerotoAll学习笔记(三)--自动求导

    Pytorch给我们提供了自动求导的函数,不用再自己再推导计算梯度的公式了 虽然有了自动求导的函数,但是这里我想给大家浅析一下:深度学习中的一个很重要的反向传播 references:https:// ...

  5. pytorch的自动求导机制 - 计算图的建立

    一.计算图简介 在pytorch的官网上,可以看到一个简单的计算图示意图, 如下. import torchfrom torch.autograd import Variable x = Variab ...

  6. 『PyTorch x TensorFlow』第六弹_从最小二乘法看自动求导

    TensoFlow自动求导机制 『TensorFlow』第二弹_线性拟合&神经网络拟合_恰是故人归 下面做了三个简单尝试, 利用包含gradients.assign等tf函数直接构建图进行自动 ...

  7. Pytorch Tensor, Variable, 自动求导

    2018.4.25,Facebook 推出了 PyTorch 0.4.0 版本,在该版本及之后的版本中,torch.autograd.Variable 和 torch.Tensor 同属一类.更确切地 ...

  8. [深度学习] pytorch学习笔记(1)(数据类型、基础使用、自动求导、矩阵操作、维度变换、广播、拼接拆分、基本运算、范数、argmax、矩阵比较、where、gather)

    一.Pytorch安装 安装cuda和cudnn,例如cuda10,cudnn7.5 官网下载torch:https://pytorch.org/ 选择下载相应版本的torch 和torchvisio ...

  9. PyTorch官方中文文档:自动求导机制

    自动求导机制 本说明将概述Autograd如何工作并记录操作.了解这些并不是绝对必要的,但我们建议您熟悉它,因为它将帮助您编写更高效,更简洁的程序,并可帮助您进行调试. 从后向中排除子图 每个变量都有 ...

  10. 『PyTorch』第三弹_自动求导

    torch.autograd 包提供Tensor所有操作的自动求导方法. 数据结构介绍 autograd.Variable 这是这个包中最核心的类. 它包装了一个Tensor,并且几乎支持所有的定义在 ...

随机推荐

  1. 会长哥哥帮助安装ubuntu

    今晚突然想到要安装虚拟机,因为我原来上的python预科班里面讲解安装虚拟机,但是我当时没有安装上,导致预科班后面的课我没听懂,今天听课讲到字符和编码 所以想到了我的虚拟机,于是今晚很谨慎的求助会长大 ...

  2. Oracle-展示的时候出现????乱码

    Oracle-展示的时候出现????乱码 配置环境变量: NLS_LANG SIMPLIFIED CHINESE_CHINA.ZHS16GBK

  3. beta冲刺:汇总博客

    这个作业属于哪个课程 <班级的链接> 这个作业要求在哪里 <作业要求的链接> 这个作业的目标 汇总博客 作业正文 .... 其他参考文献 ... 博客 beta冲刺(1/5) ...

  4. 非常有用的python单行代码

    1 推导式应用 1.1 列表推导式(一行for循环) #For循环在一行 mylist = [200, 300, 400, 500] #正常方式 result = [] for x in mylist ...

  5. VUE配置proxy代理、开发环境、测试环境、生产环境

    VUE配置proxy代理.开发环境.测试环境.生产环境 前端开发过程中,我们经常会碰到跨域的问题,下面我们来配置下,不同的环境下,统一的跨域问题解决. 1.根目录下新建三个环境的配置文件,.env.d ...

  6. java的maven项目打包成.exe可执行文件

    打包exe可执行脚本: 1.源代码maven项目写完后打包成可执行jar包,此处我使用的是assembly插件. <plugin> <groupId>org.apache.ma ...

  7. Python类的继承,你了解多少?

    "三人行必有我师焉!"."不耻下问",中国的圣人先师孔子留下的文化瑰宝传承在生活中的每个角落. 孔子是中国古代最伟大的思想家.教育家.如果说中国有一种根本的立国 ...

  8. IDEA2022中部署Tomcat Web项目

    使用工具: IDEA2022 Tomcat9.0.4 1.下载Tomcat: 官网:https://tomcat.apache.org/ 找到需要的版本下载即可,下载完成解压即可用: Tomcat目录 ...

  9. 图与网络分析—R实现(四)

    三 最短路问题 最短路问题(short-path problem)是图论理论的一个经典问题.寻找最短路径就是在指定网络中两结点间找一条距离最小的路.最短路不仅仅指一般地理意义上的距离最短,还可以引申到 ...

  10. 使用easyexcal导出excal

    需要的依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</ ...