pytorch中 backward 机制理解

backward只能被应用在一个标量上,也就是一个一维tensor,或者传入跟变量相关的梯度。特别注意Variable里面默认的参数requires_grad=False,所以这里我们要重新传入requires_grad=True让它成为一个叶子节点
这里写图片描述

对其求偏导:
这里写图片描述

import torch 
from torch.autograd import Variable
a = Variable(torch.Tensor([2,3]),requires_grad = True)
b = a + 3
c = b * b * 3 
out = c.mean()
out.backward()
print(‘*’ * 10)
print(‘====simple gradient=====’)
print(‘input’)
print(a.data)
print('compute result is:')
print(out.data[0])
print('input gradients are:')
print(a.grad.data)

注:torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现
Varibale包含三个属性:
• data:存储了Tensor,是本体的数据
• grad:保存了data的梯度,grad本身也是个Variable而非Tensor,与data形状一致
•grad_fn:指向Function对象,用于反向传播的梯度计算之用

这里写图片描述

下面研究一下如何能够对非标量的情况下使用backward。backward里传入的参数是每次求导的一个系数。
首先定义好输入 m=(x1,x2)=(2,3) m = ( x 1 , x 2 ) = ( 2 , 3 ) ,然后我们做的操作就是n= (x21,x32) ( x 1 2 , x 2 3 ) ,这样我们就定义好了一个向量输出,结果第一项只和x1有关,结果第二项只和 x2 x 2 有关,那么求解这个梯度

m = Variable(torch.Tensor([[2,3]]),requires_grad = True)
n = Variable(torch.zeros(1,2))
n[0,0] = m[0,0] ** 2
n[0,1] = m[0,1] ** 3
n.backward(torch.Tensor([[1,1]]))
print('*' * 10)
print('==== non scalar output ======')
print('input')
print(m.data)
print('input gradient are')
print(m.grad.data)

这里写图片描述
这里写图片描述

jacobian矩阵
这里写图片描述
对其求导:

这里写图片描述

k.backward(parameters)接受的参数parameters必须要和k的大小一模一样,然后作为k的系数传回去,backward里传入的参数是每次求导的一个系数。

j = t.zeros(2 ,2)
k = v(t.zeros(1, 2))
k[0, 0] = m[0, 0] ** 2 + 3 * m[0 ,1]
k[0, 1] = m[0, 1] ** 2 + 2 * m[0, 0]
# [1, 0] dk0/dm0, dk1/dm0
k.backward(t.FloatTensor([[1, 0]]), retain_variables=True) # 需要两次反向求导
j[:, 0] = m.grad.data
m.grad.data.zero_()
# [0, 1] dk0/dm1, dk1/dm1
k.backward(t.FloatTensor([[0, 1]]))
j[:, 1] = m.grad.data
print('jacobian matrix is') print(j)

我们要注意backward()里面另外的一个参数retain_variables=True,这个参数默认是False,也就是反向传播之后这个计算图的内存会被释放,这样就没办法进行第二次反向传播了,所以我们需要设置为True,因为这里我们需要进行两次反向传播求得jacobian矩阵。
这里写图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值