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. JSON反序列化接口的问题

    今天在使用JSON序列化类时出现问题,原来类中有一个接口,在反序列化时不知道接口的实体是什么 public class Device : IComparer {         private str ...

  2. MySql 入门——日期计算

    MySQL自带的日期函数TIMESTAMPDIFF计算两个日期相差的秒数.分钟数.小时数.天数.周数.季度数.月数.年数,当前日期增加或者减少一天.一周等等 SELECT TIMESTAMPDIFF( ...

  3. springboot + mybatisplus出现was not registered for synchronization because synchronization is not active

    原因一:缺少事务注解,底层mybatisplus的接口方法有事务 原因二:该服务器被限制访问要连接的数据库 原因三:乐观锁失效 乐观锁由@version注解标注,有以下使用要求 支持的数据类型只有:i ...

  4. FCARM - Output Name not specified, please check 'Options for Target - Utilit问题

    FCARM - Output Name not specified, please check 'Options for Target - Utilit问题 按照书上说明按步操作,但是书上是按照kei ...

  5. egret 图片跨域

    //图片跨域 egret.ImageLoader.crossOrigin = "anonymous";

  6. 痞子衡嵌入式:2021 TencentOS Tiny AIoT应用创新大赛 - 初赛阶段的38个作品速览

    腾讯 TencentOS 团队于2021年12月8日联合恩智浦半导体.安谋科技发起的线上开发者活动 - TencentOS Tiny AIoT 应用创新大赛目前已经进入到了最后的决赛阶段. 参赛者的作 ...

  7. Python学习笔记--数据可视化的开头

    JSON数据格式的转换 示例: 若是有中文数据,可以在data后面加上ensure_ascii=False pyecharts模块 网站:https://gallery.pyecharts.org(有 ...

  8. vulnhub靶场之BLUESMOKE: DEVRANDOM2|bluesmoke

    准备: 攻击机:虚拟机kali.本机win10. 靶机:Bluesmoke: devrandom2,下载地址:https://download.vulnhub.com/bluesmoke/Bluesm ...

  9. 穷人版生产力工具,好用得飞起 「GitHub 热点速览」

    被 GPT 和 OpenAI 刷屏了一个多月,现在 GitHub Trending 已经没有什么和 gpt 无关的项目了,但是好在总有优秀的开源项目拯救我的项目疲惫.像是贴心好用的反向代理 pgrok ...

  10. 剑指 offer 第 3 天

    第 3 天 字符串(简单) 剑指 Offer 05. 替换空格 请实现一个函数,把字符串 s 中的每个空格替换成"%20". 示例 1: 输入:s = "We are h ...