『PyTorch』第三弹_自动求导

torch.autograd 包提供Tensor所有操作的自动求导方法。

数据结构介绍

autograd.Variable 这是这个包中最核心的类。 它包装了一个Tensor,并且几乎支持所有的定义在其上的操作。一旦完成了你的运算,你可以调用 .backward()来自动计算出所有的梯度,Variable有三个属性:

访问原始的tensor使用属性.data;

关于这一Variable的梯度则集中于 .grad;

.creator反映了创建者,标识了是否由用户使用.Variable直接创建(None)。

 1 import torch
 2 from torch.autograd import Variable
 3 
 4 
 5 '''求导数'''
 6 
 7 x = Variable(torch.ones(2,2),requires_grad=True)
 8 y = x + 2
 9 print(x.creator)      # None,用户直接创建没有creater属性
10 print(y.creator)      # <torch.autograd._functions.basic_ops.AddConstant object at 0x7fb9b4d4b208>

返回:

None
<torch.autograd._functions.basic_ops.AddConstant object at 0x7fb9b4d4b208>

求导运算

如果你想要进行求导计算,你可以在Variable上调用.backward()。

  • 如果Variable是一个标量(例如它包含一个单元素数据),你无需对backward()指定任何参数

    1 z = y*y*3
    2 out = z.mean()
    3 
    4 out.backward()
    5 
    6 print(x,y,z)
    7 print(x.grad)          # 输出对out对x求倒结果
    8 print(y.grad)          # y不是自动求导变量
    Variable containing:
     1  1
     1  1
    [torch.FloatTensor of size 2x2]
     Variable containing:
     3  3
     3  3
    [torch.FloatTensor of size 2x2]
     Variable containing:
     27  27
     27  27
    [torch.FloatTensor of size 2x2]
    
    Variable containing:
     4.5000  4.5000
     4.5000  4.5000
    [torch.FloatTensor of size 2x2]
    
    None

    最终得出的结果应该是一个全是4.5的矩阵。设置输出的变量为o。我们通过这一公式来计算:

    o = frac{1}{4}sum_i z_iz_i = 3(x_i+2)^2z_iigr
vert_{x_i=1} = 27,因此,frac{partial o}{partial x_i} = frac{3}{2}(x_i+2),最后有frac{partial o}{partial x_i}igr
vert_{x_i=1} = frac{9}{2} = 4.5

  • 如果它有更多的元素(矢量),你需要指定一个和tensor的形状匹配的grad_output参数(y在指定方向投影对x的导数)

    1 x = torch.randn(3)
    2 x = Variable(x, requires_grad = True)
    3 y = x * 2
    4 while y.data.norm() < 1000:
    5     y = y * 2
    6 gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
    7 y.backward(gradients)
    8 x.grad
    Variable containing:
    -0.8143
    -1.5852
    -0.8598
    [torch.FloatTensor of size 3]
    
    Variable containing:
    -1.6286
    -3.1704
    -1.7195
    [torch.FloatTensor of size 3]
    
    3.9573325720437613
    Variable containing:
      51.2000
     512.0000
       0.0512
    [torch.FloatTensor of size 3]

    测试传入向量的意义:

 1 x = torch.randn(3)
 2 x = Variable(x,requires_grad=True)
 3 y = x*2
 4 
 5 gradients = torch.FloatTensor([0.5,0.5,1])
 6 y.backward(gradients)  # 沿着某方向的梯度
 7 print(x.grad)
 8 
 9 # Variable containing:
10 #  1
11 #  1
12 #  2
13 # [torch.FloatTensor of size 3]
 1 x = torch.randn(3)
 2 x = Variable(x,requires_grad=True)
 3 y = x*2
 4 
 5 gradients = torch.FloatTensor([1,1,1])
 6 y.backward(gradients)  # 沿着某方向的梯度
 7 print(x.grad)
 8 
 9 # Variable containing:
10 #  2
11 #  2
12 #  2
13 # [torch.FloatTensor of size 3]
原文地址:https://www.cnblogs.com/hellcat/p/6851761.html