对Pytorch中backward()函数的理解

backward()

写在第一句:
这个博客解释的也很好,参考了很多:Pytorch中的自动求导函数backward()所需参数含义

所以切入正题:
backward()函数中的参数应该怎么理解?

官方:如果需要计算导数,可以在Tensor上调用.backward()。		1. 如果Tensor是一个标量(即它包含一个元素的数据),则不需要为backward()指定任何参数2. 但是如果它有更多的元素,则需要指定一个gradient参数,它是形状匹配的张量。

先看看官方怎么解释的

backward(gradient=None, retain_variables=False)[source]

当前Variable(理解成函数Y)对leaf variable(理解成变量X=[x1,x2,x3])求偏导。

计算图可以通过链式法则求导。如果Variable是 非标量(non-scalar)的(即是说Y中有不止一个y,即Y=[y1,y2,…]),且requires_grad=True。那么此函数需要指定gradient,它的形状应该和Variable的长度匹配(这个就很好理解了,gradient的长度体与Y的长度一直才能保存每一个yi的梯度值啊),里面保存了Variable的梯度。

此函数累积leaf variable的梯度。你可能需要在调用此函数之前将Variable的梯度置零。(梯度不置零的话为出现累加

参数:

  1. gradient (Tensor) – 其他函数对于此Variable的导数。仅当Variable不是标量的时候使用,类型和位形状应该和self.data一致。
    (补充:这里说的时其他函数对Variable的导数!)
  2. retain_variables (bool) – True, 计算梯度所必要的buffer在经历过一次backward过程后不会被释放。如果你想多次计算某个子图的梯度的时候,设置为True。在某些情况下,使用autograd.backward()效率更高。

情况1:out是一个标量(就是说一个输出值)

    '''情况1:out是一个标量(就是说一个输出值)'''
b=a+3
c=b*3
out=c.mean()
out.backward()
print('input:',a.data)
print('input gradients are:',a.grad)
print(a.numel()) #返回元素个数,所以c关于a的导数应该是[(a+3)*3]/6 就是0.5
输出结果:
input: tensor([[1., 1., 1.],[1., 1., 1.]])
input gradients are: tensor([[0.5000, 0.5000, 0.5000],[0.5000, 0.5000, 0.5000]])
6

这就是最简单的情况

情况2:out是一个向量(就是说输出一列值)

a=t.ones(2,1,requires_grad=True)
b=t.zeros(2,1)
b[0,0]=a[0,0]**2+a[1,0]*5
b[1,0]=a[0,0]**3+a[1,0]*4

接下来开始尝百草:

'''try 1'''
b.backward() #什么参数也不说
print(a.grad)
不出意外,得到错误:
RuntimeError: grad can be implicitly created only for scalar outputs

错误提示:只能对标量进行求梯度操作,这个错误和官方的文档标注一样:当输出为向量时,需要输入一个gradient

'''try 2'''

未完待续…

本文链接:https://my.lmcjl.com/post/11297.html

展开阅读全文

4 评论

留下您的评论.