pytorch的梯度计算以及backward方法详解


Posted in Python onJanuary 10, 2020

基础知识

tensors:

tensor在pytorch里面是一个n维数组。我们可以通过指定参数reuqires_grad=True来建立一个反向传播图,从而能够计算梯度。在pytorch中一般叫做dynamic computation graph(DCG)——即动态计算图。

import torch
import numpy as np

# 方式一
x = torch.randn(2,2, requires_grad=True)

# 方式二
x = torch.autograd.Variable(torch.Tensor([2,3]), requires_grad=True)

#方式三
x = torch.tensor([2,3], requires_grad=True, dtype=torch.float64)

# 方式四
x = np.array([1,2,3] ,dtype=np.float64)
x = torch.from_numpy(x)
x.requires_grad = True
# 或者 x.requires_grad_(True)

note1:在pytorch中,只有浮点类型的数才有梯度,故在方法四中指定np数组的类型为float类型。为什么torch.Tensor中不需要呢,可以通过以下代码验证

import torch
import numpy as np

a = torch.Tensor([2,3])
print(a.dtype) # torch.floaat32

b = torch.tensor([2,3])
print(b.dtype) # torch.int64

 c = np.array(2,3)
 print(c.dtype) # int64

note2pytorch中tensor与Tensor的区别是什么?这两个看起来如此相似。

首先,torch.Tensor是一个类,所有的tensor都是Tensor的一个实例;而torch.tensor是一个函数。这也说明了为什么使用torch.Tensor()没有问题而torch.tensor()却有问题。

其次,torch.tensor主要是将一个data封装成tensor,并且可以指定requires_grad。

torch.tensor(data,dtype=None,device=None,requires_grad=False) - > Tensor

最后,我们更多地使用torch.tensor,我们可以通过使用torch.tensor(())来达到与torch.Tensor()同样的效果。

具体可参考torch.tensor与torch.Tensor的区别

Dynamic Computational graph

我们来看一个计算图

pytorch的梯度计算以及backward方法详解

我们 来看一个计算图 解释一下各个属性的含义,

data: 变量中存储的值,如x中存储着1,y中存储着2,z中存储着3

requires_grad:该变量有两个值,True 或者 False,如果为True,则加入到反向传播图中参与计算。

grad:该属性存储着相关的梯度值。当requires_grad为False时,该属性为None。即使requires_grad为True,也必须在调用其他节点的backward()之后,该变量的grad才会保存相关的梯度值。否则为None

grad_fn:表示用于计算梯度的函数。

is_leaf:为True或者False,表示该节点是否为叶子节点。

当调用backward函数时,只有requires_grad为true以及is_leaf为true的节点才会被计算梯度,即grad属性才会被赋予值。

梯度计算

examples

运算结果变量的requires_grad取决于输入变量。例如:当变量z的requires_grad属性为True时,为了求得z的梯度,那么变量b的requires_grad就必须为true了,而变量x,y,a的requires_grad属性都为False。

将事先创建的变量,如x、y、z称为创建变量;像a、b这样由其他变量运算得到的称为结果变量。

from torch.autograd import Variable

x = Variable(torch.randn(2,2))
y = Variable(torch.randn(2,2))
z = Variable(torch.randn(2,2), requires_grad=True)


a = x+y
b = a+z

print(x.requires_grad, y.requires_grad, z.requires_grad) # False, False, True
print(a.requires_grad, b.requires_grad) # False, True

print(x.requires_grad) # True
print(a.requires_grad) # True

调用backward()计算梯度

import torch as t
from torch.autograd import Variable as v

a = v(t.FloatTensor([2, 3]), requires_grad=True) 
b = a + 3
c = b * b * 3
out = c.mean()
out.backward(retain_graph=True) # 这里可以不带参数,默认值为‘1',由于下面我们还要求导,故加上retain_graph=True选项

print(a.grad) # tensor([15., 18.])

backward中的gradient参数使用

a. 最后的结果变量为标量(scalar)

如第二个例子,通过调用out.backward()实现对a的求导,这里默认调用了out.backward(gradient=None)或者指定为out.backward(gradient=torch.Tensor([1.0])

b. 最后的结果变量为向量(vector)

import torch
from torch.autograd import Variable as V

m = V(torch.FloatTensor([2, 3]), requires_grad=True) # 注意这里有两层括号,非标量
n = V(torch.zeros(2))
n[0] = m[0] ** 2
n[1] = m[1] ** 3
n.backward(gradient=torch.Tensor([1,1]), retain_graph=True)
print(m.grad)

结果为:

tensor([ 4., 27.])

如果使用n.backward()的话,那么就会报如下的错:RuntimeError: grad can be implicitly created only for scalar outputs

注意:这里的gradient的维度必须与n的维度相同。其中的原理如下:

在执行z.backward(gradient)的时候,如果z不是一个标量,那么先构造一个标量的值:L = torch.sum(z*gradient),再计算关于L对各个leaf Variable的梯度。

pytorch的梯度计算以及backward方法详解

以上这篇pytorch的梯度计算以及backward方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现字符串连接的三种方法及其效率、适用场景详解
Jan 13 Python
Python3 中把txt数据文件读入到矩阵中的方法
Apr 27 Python
python文件拆分与重组实例
Dec 10 Python
numpy.array 操作使用简单总结
Nov 08 Python
Python协程 yield与协程greenlet简单用法示例
Nov 22 Python
如何使用python3获取当前路径及os.path.dirname的使用
Dec 13 Python
tensorflow将图片保存为tfrecord和tfrecord的读取方式
Feb 17 Python
python3 sorted 如何实现自定义排序标准
Mar 12 Python
Python多线程Threading、子线程与守护线程实例详解
Mar 24 Python
python2和python3哪个使用率高
Jun 23 Python
Pytorch生成随机数Tensor的方法汇总
Sep 09 Python
python实现web邮箱扫描的示例(附源码)
Mar 30 Python
Python如何获取Win7,Win10系统缩放大小
Jan 10 #Python
python-OpenCV 实现将数组转换成灰度图和彩图
Jan 09 #Python
Python 实现将数组/矩阵转换成Image类
Jan 09 #Python
python 实现将Numpy数组保存为图像
Jan 09 #Python
Python+OpenCV实现将图像转换为二进制格式
Jan 09 #Python
如何使用Python破解ZIP或RAR压缩文件密码
Jan 09 #Python
python读取raw binary图片并提取统计信息的实例
Jan 09 #Python
You might like
二次元帅气男生排行榜,只想悄悄收藏系列
2020/03/04 日漫
php一句话cmdshell新型 (非一句话木马)
2009/04/18 PHP
PHP多线程抓取网页实现代码
2010/07/22 PHP
PHP 与 UTF-8 的最佳实践详细介绍
2017/01/04 PHP
使一个函数作为另外一个函数的参数来运行的javascript代码
2007/08/13 Javascript
高效的表格行背景隔行变色及选定高亮的JS代码
2010/12/04 Javascript
Extjs4 关于Store的一些操作(加载/回调/添加)
2013/04/18 Javascript
文本域中换行符的替换示例
2014/03/04 Javascript
Javascript实现禁止输入中文或英文的例子
2014/12/09 Javascript
深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP详解
2015/03/05 Javascript
原生JS实现的放大镜效果实例代码
2016/10/15 Javascript
Vue应用部署到服务器的正确方式
2017/07/15 Javascript
NodeJS服务器实现gzip压缩的示例代码
2018/10/12 NodeJs
微信二次分享报错invalid signature问题及解决方法
2019/04/01 Javascript
Python GAE、Django导出Excel的方法
2008/11/24 Python
Python实现的中国剩余定理算法示例
2017/08/05 Python
Python数据可视化编程通过Matplotlib创建散点图代码示例
2017/12/09 Python
Python django框架输入汉字,数字,字符生成二维码实现详解
2019/09/24 Python
python GUI库图形界面开发之PyQt5表单布局控件QFormLayout详细使用方法与实例
2020/03/06 Python
Python3标准库之dbm UNIX键-值数据库问题
2020/03/24 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
2020/06/02 Python
解析Python 偏函数用法全方位实现
2020/06/26 Python
CSS3中使用RGBa来调节透明度的教程
2016/05/09 HTML / CSS
简洁自适应404页面HTML好看的404源码
2020/12/16 HTML / CSS
英国皇家邮政海外旗舰店:Royal Mail
2018/02/21 全球购物
eBay瑞士购物网站:eBay.ch
2018/12/24 全球购物
实习生体会的自我评价范文
2013/11/28 职场文书
大门门卫岗位职责
2013/11/30 职场文书
大四自我鉴定
2014/02/08 职场文书
品牌宣传方案
2014/03/21 职场文书
市场总经理岗位职责
2014/04/11 职场文书
实习指导老师评语
2014/04/26 职场文书
2015团员个人年度总结
2015/11/24 职场文书
Python基础数据类型tuple元组的概念与用法
2021/08/02 Python
Node.js实现爬取网站图片的示例代码
2022/04/04 NodeJs
vue route新窗口跳转页面并且携带与接收参数
2022/04/10 Vue.js