backward用法

backward用法

pytorch中backward自动求导原理解释

标量对矢量求导

  • 默认的时候是不采用梯度跟踪的,需要在创建的时候加入requires_grad=True
  • 若创建的时候无梯度跟踪,需要加入a.requires_grad_(True)
  • 标量对矢量求导的时候backward不需要加入参数

in

a = torch.randn(2,2)
a = ((a * 3) / (a - 1))
a

out

tensor([[  8.4251,  -1.6011],
        [-22.3855,  -0.5603]])

in

print(a.requires_grad)

out

False

in

a.requires_grad_(True)

out

tensor([[  8.4251,  -1.6011],
        [-22.3855,  -0.5603]], requires_grad=True)

in

b = (a * a).sum()
print(b.grad_fn)

out

<SumBackward0 object at 0x00000200A4D84BE0>

in

b.backward()
print(a.grad)

求完导数后,2a为其导数,所以结果为:

tensor([[ 16.8502,  -3.2023],
        [-44.7710,  -1.1205]])

矢量对矢量求导

  • 矢量对矢量求导需要在backward后面加入一个和result维度相同的矩阵
  • 我们传入的参数,被看作是行向量,进行矩阵的乘法

in

import torch
from torch.autograd import Variable

a = Variable(torch.FloatTensor([[2., 4.]]), requires_grad=True)
b = torch.zeros(1,2)
b[0,0] = a[0,0] ** 2 + a[0,1]
b[0,1] = a[0,1] ** 3 + a[0,0]
out = 2 * b

# 参数需要传入和out相同维度的
out.backward(torch.FloatTensor([[1., 2.]]))

print('input:')
print(a.data)
print('output:')
print(out.data)
print('input gradients:')
print(a.grad)

out

input:
tensor([[2., 4.]])
output:
tensor([[ 16., 132.]])
input gradients:
tensor([[ 12., 194.]])

求完导后

行列式为

4 a 1 = 8 4a_1=8 4a1=82
2 6 a 2 2 = 96 6a^2_2=96 6a22=96

传入的参数是行向量 [ 1 , 2 ] [1,2] [1,2]

动手验证一下是正确的

因此结果为 ( a r g × J a c o b i ) T (arg \times Jacobi)^T (arg×Jacobi)T

可以自己输出雅可比行列式

import torch
from torch.autograd import Variable
import copy

a = Variable(torch.FloatTensor([[2., 4.]]), requires_grad=True)
b = torch.zeros(1,2)
b[0,0] = a[0,0] ** 2 + a[0,1]
b[0,1] = a[0,1] ** 3 + a[0,0]
out = 2 * b

out.backward(torch.FloatTensor([[1,0]]), retain_graph = True)
A_temp = copy.deepcopy(a.grad)
a.grad.zero_()
out.backward(torch.FloatTensor([[0,1]]))
B_temp = a.grad
print('Jacobi Matrix:')
print(torch.cat((A_temp, B_temp), 0))

out

Jacobi Matrix:
tensor([[ 8.,  2.],
        [ 2., 96.]])

因为经过了复杂的神经网络之后,out中每个数值都是由很多输入样本的属性(也就是输入数据)线性或者非线性组合而成的,那么out中的每个数值和输入数据的每个数值都有关联,也就是说【out】中的每个数都可以对【a】中每个数求导,那么我们backward()的参数[k1,k2,k3…kn]的含义就是:每个out分量对an求导时的权重。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值