【one way的pytorch学习笔记】(四)autograd的流程机制原理

本文为对YouTube博主 Elliot Waite所讲视频的记录与思考,视频地址 PyTorch Autograd Explained - In-depth Tutorial


autograd 流程图
例 1.
a = torch.tensor(2.0)
b = torch.tensor(3.0)
c = a*b 

前项的计算图如下:
每个方框代表一个tensor,其中列出一些属性(还有其他很多属性):

  • .data 存了tensor的data
  • .grad 当计算gradient的时候将会存入此函数对应情况下的gradient
  • .grad_fn 指向用于backward的函数的节点
  • .is_leaf 判断是否是叶节点 (关于叶节点的信息请移步: one way的pytorch学习笔记(三)leaf 叶子(张量))
  • .requires_grad 如果是设为True,那么在做backward时候将作为图的一部分参与backwards运算,如果为False则不参加backwards运算

在图中可见, c= a*b的运算也算作计算图的一部分, 用Mul表示.由于a 和b 是require_grad,所以自动的被算为 is_leaf 为True, 至于为什么请见one way的pytorch学习笔记(三)leaf 叶子(张量) ,此时由于requires_grad都为False,因此没有backwards的graph.

例 2.
a = torch.tensor(2.0,requires_grad = True)
b = torch.tensor(3.0)
c = a*b 
c.backward()

重新进行计算,设tensor arequires_gradTrue,输出结果c因为输入自变量的属性为True而自动改变成 requires_gradTrue.这说明只要自变量中有一个requires_gradTrue, 进一步通过运算生成的变量也为True. 此时的c 为非叶节点, grad_fn 指向做backwards时与当前变量相关的backwards的函数(函数为pytorch自动生成的).

这是算数式的前馈流程图, 使我们可以通过函数代码观察到的.在此流程图的背后,其实pytorch还自动生成了对应的backwards的流程图:
  1. 当我们调用tensor的乘法函数时,同时调用了隐性变量 ctx (context)变量的save_for_backward(),这样就把此函数做backward时所需要的从forward函数中获取的相关的一些值存到了ctx中.ctx起到了缓存相关参数的作用,变成连接forward与backward之间的缓存站. ctx中的值将会在c 做backwards时传递给对应的Mulbackward 操作.
  2. 与此同时 由于c是通过 c=a*b运算得来的, c的grad_fn中存了做backwards时候对应的函数.且把这个对应的backward 叫做 “MulBackward
  3. 当进行c的backwards的时候,其实也就相当于执行了 c = a*b这个函数分别对 ab 做的偏导. 那么理应对应两组backwards的函数,这两组backwards的函数打包存在 MulBackward的 next_functions 中. nex_function为一个 tuple list, AccumulateGrad 将会把相应得到的结果送到 a.grad中.
  4. 于是在进行 c.backward() 后, c进行关于a以及关于b的求导,由于brequires_gradFalse,因此b项不参与backwards运算(自然的,next_function中list的第二个tuple即为None),c关于a的梯度为3,因此3将传递给AccumulaGrad进一步传给a.grad 因此 a.grad 的结果为3

从这个backward graph中,可以看出,其实pytorch在定义这些变量的运算函数时,其实也定义了函数对应的backwards的函数.如果想使用自定义的函数,那么自己也必须要定义backwards函数.

例 3.
a = torch.tensor(2.0,requires_grad = True)
b = torch.tensor(3.0,requires_grad = True)
c = a*b 
d = torch.tensor(4.0,requires_grad = True)
e = c*d
e.backward()
  1. egrad_fn 指向节点 MulBackward, cgrad_fn指向另一个节点 MulBackward
  2. c 为中间值is_leafFalse,因此并不包含 grad值,在backward计算中,并不需要再重新获取c.grad的值, backward的运算直接走相应的backward node 即可
  3. MulBackward 从 ctx.saved_tensor中调用有用信息, e= c+de关于c的梯度通过MulBackward 获取得4. 根据链式规则, 4再和上一阶段的 c关于 ac关于b的两个梯度值3和2相乘,最终得到了相应的值12 和8
  4. a.grad 中存入12, b.grad中存入 8
  • 13
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值