import torch #=======================backward:深度学习中最为重要的反向传播计算================== ''' backward(tensors,grad_tensors=None,retain_graph=None,create_graph=False,grad_varibles=None):有三个比较重要的参数grad_tensors,retain_graph,create_graph关于retain_graph,create_graph:pytoch构建的计算图是动态图,为了节约内存,所以每次一轮迭代完也即是进行了一次backward函数计算之后计算图就被在内存释放,因此如果你需要多次backward只需要在第一次反向传播时候添加一个retain_graph=True标识,让计算图不被立即释放。实际上文档中retain_graph和create_graph两个参数作用相同,因为前者是保持计算图不释放,而后者是创建计算图,因此如果我们不想要计算图释放掉,将任意一个参数设置为True都行。 ''' #===============================关于grad_tensors参数================================= '''1. 创建一个张量x,并设置其 requires_grad参数为True,程序将会追踪所有对于该张量的操作,当完成计算后通过调用 .backward(),自动计算所有的梯度,这个张量的所有梯度将会自动积累到 .grad 属性。2. 创建一个关于x的函数z,由于x的requires_grad参数为True,所以y对应的用于求导的参数grad_fn为<...Backward0>.-----原因:自动梯度的计算中有一个Function类,Tensor和Function互相连接生成非循环图,存储完整计算历史,每个张量都有一个.grad_fn属性,这个属性引用了一个创建了Tensor的Function3. z.backward()时,如果y是标量(scalar),则不需要为backward()传入任何参数; 如果y是张量(tensor),需要传入一个与y同形的Tensor(张量)------原因是:如果是标量对向量求导(scalar对tensor求导),那么就可以保证计算图的根节点只有一个,此时不用引入grad_tensors参数,直接调用backward函数即可。如果是(向量)矩阵对(向量)矩阵求导(tensor对tensor求导),实际上是先求出Jacobian(雅克比)矩阵中每一个元素的梯度值(每一个元素的梯度值的求解过程对应上面的计算图的求解方法),然后将这个Jacobian矩阵与grad_tensors参数对应的矩阵进行对应的点乘,得到最终的结果。''' #=====Z是标量=== x=torch.tensor([1.0,2.0],dtype=torch.float32,requires_grad=True) y=(x+2).pow(2) print(y) z=torch.mean(y) print(z) z.backward() print(x.grad) #======y是Tensor张量,直接像标量一样会报错==== # x=torch.tensor([1.0,2.0],requires_grad=True) # y=(x+2).pow(2) # print(y) # z = 4*y # z.backward() # print(x.grad)#====z是Tensor张量的正确做法=========== x=torch.tensor([1.0,2.0,3.0],requires_grad=True) y=(x+2).pow(2) z=4*y z.backward(torch.tensor([1,1,1]))#其实添加的这个tensor是待求得x的梯度的系数;即grad_tensors参数对应的矩阵 print(x.grad) #==========例子============ x=torch.tensor([[1,2,3,]],dtype=torch.float32,requires_grad=True) Jacobian=torch.zeros(3,3) y=torch.zeros(1,3) y[0,0] = x[0,0]**2 + 2*x[0,1] y[0,1] = x[0,1]**2 + 4*x[0,0] y[0,2] = x[0,2]**2 + 2*x[0,0] +x[0,1] #====每次求导前需要清0,不然会在前面求导结果上迭代 y.backward(torch.tensor([[1,0,0]]),retain_graph=True) print(x.grad) y.backward(torch.tensor([[0,1,0]]),retain_graph=True) print(x.grad) y.backward(torch.tensor([[0,0,1]]),retain_graph=True) print(x.grad) y.backward(torch.tensor([[1,1,1]]),retain_graph=True) print(x.grad)
参考链接:(88条消息) pytorch中backward()函数详解_Camlin_Z的博客-CSDN博客_backward()
Pytorch中的backward函数 - 知乎 (zhihu.com)
本文链接:https://my.lmcjl.com/post/11363.html
展开阅读全文
4 评论