Pytorch中backward函数

  • Post author:
  • Post category:其他





  1. backward


    函数是反向求导数,使用链式法则求导,如果对非标量


    y


    求导,函数需要额外指定


    grad_tensors





    grad_tensors





    shape


    必须和


    y


    的相同。





  2. import torch  
    from torch.autograd import Variable  
    x=Variable(torch.Tensor([16]),requires_grad=True) #需要求导数  
    y=x*x  
    y.backward()  
    print(x.grad)  




  3. 运行结果是:


    tensor([32.])











  4. y


    是标量所以


    backward


    函数不需要额外的参数,backward没有参数的时候,默认对标量求导,有参数的时候,相当是指定了后一层传过来的梯度,根据chain rule,乘即可





  5. import torch  
    from torch.autograd import Variable  
    x=Variable(torch.Tensor([1,16]),requires_grad=True) #需要求导数  
    y=x*x  
    y.backward()  
    print(x.grad)  





  6. raise



    RuntimeError(


    “grad can be implicitly created only for scalar outputs”


    )





  7. RuntimeError: grad can be implicitly created only



    for



    scalar outputs





  8. 这里的


    y=[1,256]


    ,不是标量就报错


    RuntimeError: grad can be implicitly created only



    for



    scalar outputs





  9. 需要增加相应的参数


    y.backward(tensor.Tensor[value,value])


    ,接着来看参数的含义具体是什么,这的参数就是上一层传过来的梯度,根据chain rule,需要相乘才可以





  10. import torch  
    from torch.autograd import Variable  
    x=Variable(torch.Tensor([1,5,6,10,16]),requires_grad=True) #需要求导数  
    y=x*x  
      
    weights1=torch.ones(5)  
    y.backward(weights1,retain_graph=True)  
    print(x.grad)  




  11. 运行结果是:


    tensor([ 2., 10., 12., 20., 32.])








  12. 这里对


    y


    求导数,


    y=2 * x


    ,是没有问题的,


    weights1





    5


    维的和


    y


    的维度相同,由于使用了


    weights1





  13. 这里的


    y=x * 2 * weights1=2 * [1. * 1, 5. * 1, 6. * 1, 10. * 1, 16. *1]=[2 * 1.,10. * 1,12. * 1,20. * 1,32. * 1]





  14. 可以清楚的看到


    weights1


    是对求导的变量指定一个权重,这个权重就是后一层传过来的梯度,根据chain rule求导准则的,这一层的梯度需要乘上后一层传过来的梯度,以便更清楚的认识,再举个实例





  15. import torch  
    from torch.autograd import Variable  
    x=Variable(torch.Tensor([1,5,6,10,16]),requires_grad=True) #需要求导数  
    y=x*x  
      
    weights1=torch.Tensor([1,0.1,0.1,0.5,0.1])  
    y.backward(weights1,retain_graph=True)  
    print(x.grad)  




  16. 运行结果是:


    tensor([ 2.0000,  1.0000,  1.2000, 10.0000,  3.2000])








  17. 这里对


    y


    求导数,


    y=2*x


    ,但多了


    weights1


    ,需要对


    x的不同变量置偏重,这个偏重就是后一层传过来的梯度,根据chain rule求导准则的,这一层的梯度需要乘上后一层传过来的梯度





  18. y=x*2*weights1=2 * [1. * 1, 5. * 0.1, 6. * 0.1, 10. * 0.5, 16. * 0.1]=[2.*1,10.*0.1,12.*0.1,20.*0.5,32.*0.1]





  19. =[ 2.0000,  1.0000,  1.2000, 10.0000,  3.2000]








  20. backward


    函数中还有


    retain_graph


    参数


    ,使用


    retain_graph


    参数的时候,再次求导的时候,会对之前的导数进行累加





  21. import torch  
    from torch.autograd import Variable  
    x=Variable(torch.Tensor([1,5,6,10,16]),requires_grad=True) #需要求导数  
    y=x*x  
      
    weights0=torch.ones(5)  
    y.backward(weights0,retain_graph=True)  
    print(x.grad)  
      
    weights1=torch.FloatTensor([0.1,0.1,0.1,0.1,0.1])  
    y.backward(weights1,retain_graph=True)  
    print(x.grad)  
    
    weights2=torch.FloatTensor([0.5,0.1,0.1,0.1,0.2])  
    y.backward(weights2,retain_graph=True)  
    print(x.grad)  




  22. 运行结果是:





  23. tensor([ 2., 10., 12., 20., 32.])





  24. tensor([ 2.2000, 11.0000, 13.2000, 22.0000, 35.2000])





  25. tensor([ 3.2000, 12.0000, 14.4000, 24.0000, 41.6000])








  26. weights0


    处求导,


    y0=2*x*weights0=[ 2., 10., 12., 20., 32.]





  27. 由于使用


    retain_graph


    保留计算图和求导结果





  28. weights1


    处求导,


    y1=y0+2*x*weights1=[ 2., 10., 12., 20., 32.]+[ 0.2, 1., 1.2, 2, 3.2]=[2.2





    11.





    13.2





    22.





    35.2]





  29. 仍然使用


    retain_graph


    保留计算图和求导结果





  30. weights2


    处求导,


    y2=y1+2*x*weights2=[2.2





    11.





    13.2





    22.





    35.2]+[ 1., 1., 1.2, 2, 6.4]=[ 3.2, 12. 14.4, 24., 41.6]





  31. 可以看到使用


    retain_graph


    ,接着的求导会进行累加,相当是训练了多个batch,然后梯度进行了累加,然后再一次update参数,而不是每个batch都进行update。





  32. 参考的内容:


    https://pytorch.org/docs/stable/autograd.html?highlight=backward


    #torch.autograd.backward




版权声明:本文为m0_50617544原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。