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. day48-Mysql安装文件结构及SQL常用语句

    1.安装文件结构 bin--mysql.exe 客户端运行程序: mysqld.exe 服务端运行程序:  data--数据库.数据表等文件 注:修改配置文件后需要重启服务端 2.常用SQL语句 1) ...

  2. centos docker 部署.net6项目

    1 .生成dockerfile文件 FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 5000 # 一般情况下必 ...

  3. mysql5.7_win64位安装

    1.下载MySQL压缩包解压缩 2.更改my.ini配置文件 [mysqld] #设置3306端口号 port=3306 #设置MySQL的安装目录 basedir=F:\\JavaSoftware\ ...

  4. PyQt5高级窗口组件

    https://blog.csdn.net/A642960662/article/details/123093350?utm_medium=distribute.pc_aggpage_search_r ...

  5. .net core 使用 Nlog 配置文件

    nlog.config文件 安装nuget包: NLog.Web.AspNetCore 配置开始 <?xml version="1.0" encoding="utf ...

  6. Linux值得收藏的40个命令总结,常用的正则表达式

    1 删除0字节文件 find -type f -size 0 -exec rm -rf {} \; 2 查看进程 按内存从大到小排列 PS -e -o "%C : %p : %z : %a& ...

  7. MySQL学习(九)frm与ibd了解

    参考:https://cloud.tencent.com/developer/article/1533746 InnoDB: frm,ibd MyISAM: frm,myd,myi ibd是InnoD ...

  8. MySQL学习(二)事务的隔离级别

    :规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的.较低级别的隔离通常可以执行更高的并发,系统的开销也更低 read uncommitted(未提交读):事务中的修改,即使没有 ...

  9. 高性能 Kafka队列的原理

    一.原理简述 [1]Producer将消息进行分组分别发送到对应 Leader节点:[2]Leader将消息写入本地 log:[3]Followers从 Leader pull最新消息,写入 log后 ...

  10. odoo 开发入门教程系列-安全-简介

    安全-简介 前一章中我们已经创建了第一个打算用于存储业务数据的表.在odoo这样的一个商业应用中,第一个考虑的问题就是谁(Odoo 用户(或者组用户))可以访问数据.odoo为指定用户组用户提供了一个 ...