查看非叶节点梯度的两种方法

在反向传播过程中非叶子节点的导数计算完之后即被清空。若想查看这些变量的梯度,有两种方法:

  • 使用autograd.grad函数
  • 使用hook

autograd.gradhook方法都是很强大的工具,更详细的用法参考官方api文档,这里举例说明基础的使用。推荐使用hook方法,但是在实际使用中应尽量避免修改grad的值。

求z对y的导数

x = V(t.ones(3))
w = V(t.rand(3),requires_grad=True)
y = w.mul(x)
z = y.sum() # hook
# hook没有返回值,参数是函数,函数的参数是梯度值
def variable_hook(grad):
print("hook梯度输出:\r\n",grad) hook_handle = y.register_hook(variable_hook) # 注册hook
z.backward(retain_graph=True) # 内置输出上面的hook
hook_handle.remove() # 释放 print("autograd.grad输出:\r\n",t.autograd.grad(z,y)) # t.autograd.grad方法
hook梯度输出:
Variable containing:
1
1
1
[torch.FloatTensor of size 3] autograd.grad输出:
(Variable containing:
1
1
1
[torch.FloatTensor of size 3]
,)

多次反向传播试验

实际就是使用retain_graph参数,

# 构件图
x = V(t.ones(3))
w = V(t.rand(3),requires_grad=True)
y = w.mul(x)
z = y.sum() z.backward(retain_graph=True)
print(w.grad)
z.backward()
print(w.grad)
Variable containing:
1
1
1
[torch.FloatTensor of size 3] Variable containing:
2
2
2
[torch.FloatTensor of size 3]

如果不使用retain_graph参数,

实际上效果是一样的,AccumulateGrad object仍然会积累梯度

# 构件图
x = V(t.ones(3))
w = V(t.rand(3),requires_grad=True)
y = w.mul(x)
z = y.sum() z.backward()
print(w.grad)
y = w.mul(x) # <-----
z = y.sum() # <-----
z.backward()
print(w.grad)
Variable containing:
1
1
1
[torch.FloatTensor of size 3] Variable containing:
2
2
2
[torch.FloatTensor of size 3]

分析:

这里的重新建立高级节点意义在这里:实际上高级节点在创建时,会缓存用于输入的低级节点的信息(值,用于梯度计算),但是这些buffer在backward之后会被清空(推测是节省内存),而这个buffer实际也体现了上面说的动态图的"动态"过程,之后的反向传播需要的数据被清空,则会报错,这样我们上面过程就分别从:保留数据不被删除&重建数据两个角度实现了多次backward过程。

实际上第二次的z.backward()已经不是第一次的z所在的图了,体现了动态图的技术,静态图初始化之后会留在内存中等待feed数据,但是动态图不会,动态图更类似我们自己实现的机器学习框架实践,相较于静态逻辑简单一点,只是PyTorch的静态图和我们的比会在反向传播后清空存下的数据:下次要么完全重建,要么反向传播之后指定不舍弃图z.backward(retain_graph=True)。

总之图上的节点是依赖buffer记录来完成反向传播,TensorFlow中会一直存留,PyTorch中就会backward后直接舍弃(默认时)。

『PyTorch』第五弹_深入理解autograd_中:Variable梯度探究的更多相关文章

  1. 『PyTorch』第五弹_深入理解autograd_上:Variable属性方法

    在PyTorch中计算图的特点可总结如下: autograd根据用户对variable的操作构建其计算图.对变量的操作抽象为Function. 对于那些不是任何函数(Function)的输出,由用户创 ...

  2. 『PyTorch』第五弹_深入理解autograd_下:函数扩展&高阶导数

    一.封装新的PyTorch函数 继承Function类 forward:输入Variable->中间计算Tensor->输出Variable backward:均使用Variable 线性 ...

  3. 『PyTorch』第五弹_深入理解Tensor对象_中下:数学计算以及numpy比较_&_广播原理简介

    一.简单数学操作 1.逐元素操作 t.clamp(a,min=2,max=4)近似于tf.clip_by_value(A, min, max),修剪值域. a = t.arange(0,6).view ...

  4. 『PyTorch』第五弹_深入理解Tensor对象_下:从内存看Tensor

    Tensor存储结构如下, 如图所示,实际上很可能多个信息区对应于同一个存储区,也就是上一节我们说到的,初始化或者普通索引时经常会有这种情况. 一.几种共享内存的情况 view a = t.arang ...

  5. 『PyTorch』第五弹_深入理解Tensor对象_中上:索引

    一.普通索引 示例 a = t.Tensor(4,5) print(a) print(a[0:1,:2]) print(a[0,:2]) # 注意和前一种索引出来的值相同,shape不同 print( ...

  6. 『PyTorch』第五弹_深入理解Tensor对象_上:初始化以及尺寸调整

    一.创建Tensor 特殊方法: t.arange(1,6,2)t.linspace(1,10,3)t.randn(2,3) # 标准分布,*size t.randperm(5) # 随机排序,从0到 ...

  7. 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下

    『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 # Author : Hellcat # Time : 2018/2/11 import torch as t import t ...

  8. 『PyTorch』第十弹_循环神经网络

    RNN基础: 『cs231n』作业3问题1选讲_通过代码理解RNN&图像标注训练 TensorFlow RNN: 『TensotFlow』基础RNN网络分类问题 『TensotFlow』基础R ...

  9. 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上

    总结一下相关概念: torch.Tensor - 一个近似多维数组的数据结构 autograd.Variable - 改变Tensor并且记录下来操作的历史记录.和Tensor拥有相同的API,以及b ...

随机推荐

  1. java接口对接——别人调用我们接口获取数据

    java接口对接——别人调用我们接口获取数据,我们需要在我们系统中开发几个接口,给对方接口规范文档,包括访问我们的接口地址,以及入参名称和格式,还有我们的返回的状态的情况, 接口代码: package ...

  2. python requests 请求的封装

    #encoding=utf-8import requestsimport jsonclass HttpClient(object):    def __init__(self):        pas ...

  3. web前端----JavaScript的DOM(二)

    前面在DOM一中我们知道了属性操作,下面我们来了解一下节点操作.很重要!! 一.节点操作 创建节点:var ele_a = document.createElement('a');添加节点:ele_p ...

  4. python之路----初识面向对象(二)

    类命名空间与对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两种属性:静态属性和动态属性 静态属性就是直接在类中定义的变量 动态属性就 ...

  5. bzoj1649 / P2854 [USACO06DEC]牛的过山车Cow Roller Coaster

    P2854 [USACO06DEC]牛的过山车Cow Roller Coaster dp 对铁轨按左端点排个序,蓝后就是普通的二维dp了. 设$d[i][j]$为当前位置$i$,成本为$j$的最小花费 ...

  6. git和github的简单配合使用

    1.安装git,TortoiseGit. 2.用帐号A登陆github,建立一个版本仓库test1.用默认值创建就可以了. 3.在本机用TortoiseGit克隆仓库test1.直接选https开头的 ...

  7. Node-webkit 安装使用npm安装模块方法

    原文链接:http://jingyan.baidu.com/article/5225f26b5aaa20e6fa0908a6.html package.json可以放在软件根目录下,也可以放在项目目录 ...

  8. Educational Codeforces Round 21 Problem D(Codeforces 808D)

    Vasya has an array a consisting of positive integer numbers. Vasya wants to divide this array into t ...

  9. C# 获取枚举的描述属性

    在使用枚举类型时,我们需要取名称和值,甚至有时候还需要取枚举类型的描述.通过反射,我们能获取到枚举类型的描述属性. 首先我们需要给枚举类型添加描述属性(属性都没有是不可能取到的),[Descripti ...

  10. P3466 [POI2008]KLO-Building blocks

    目录 题目 思路 错误 代码 题目 luogu csdn好像限制了展开博客次数,真的好xx 思路 显然一段区间内的值一定是他的中位数 少一点比多一点好 然后就可以枚举区间了 区间答案为 val[mid ...