『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。我们通过这一公式来计算:

    ,因此,,最后有

  • 如果它有更多的元素(矢量),你需要指定一个和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]
时间: 2024-08-29 10:10:41

『PyTorch』第三弹_自动求导的相关文章

『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下

『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 # Author : Hellcat # Time : 2018/2/11 import torch as t import torch.nn as nn import torch.nn.functional as F class LeNet(nn.Module): def __init__(self): super(LeNet,self).__init__() self.conv1 = nn.Conv2d(3, 6, 5)

『PyTorch』第十弹_循环神经网络

『cs231n』作业3问题1选讲_通过代码理解RNN&图像标注训练 对于torch中的RNN相关类,有原始和原始Cell之分,其中RNN和RNNCell层的区别在于前者一次能够处理整个序列,而后者一次只处理序列中一个时间点的数据,前者封装更完备更易于使用,后者更具灵活性.实际上RNN层的一种后端实现方式就是调用RNNCell来实现的. 一.nn.RNN import torch as t from torch import nn from torch.autograd import Variab

『PyTorch』第五弹_深入理解autograd_下:函数扩展&amp;高阶导数

一.封装新的PyTorch函数 继承Function类 forward:输入Variable->中间计算Tensor->输出Variable backward:均使用Variable 线性映射 from torch.autograd import Function class MultiplyAdd(Function): # <----- 类需要继承Function类 @staticmethod # <-----forward和backward都是静态方法 def forward(

『PyTorch』第五弹_深入理解autograd_上:Variable

一.Variable类源码简介 class Variable(_C._VariableBase): """ Attributes: data: 任意类型的封装好的张量. grad: 保存与data类型和位置相匹配的梯度,此属性难以分配并且不能重新分配. requires_grad: 标记变量是否已经由一个需要调用到此变量的子图创建的bool值.只能在叶子变量上进行修改. volatile: 标记变量是否能在推理模式下应用(如不保存历史记录)的bool值.只能在叶变量上更改.

『PyTorch』第五弹_深入理解autograd_下:Variable梯度探究

查看非叶节点梯度的两种方法 在反向传播过程中非叶子节点的导数计算完之后即被清空.若想查看这些变量的梯度,有两种方法: 使用autograd.grad函数 使用hook autograd.grad和hook方法都是很强大的工具,更详细的用法参考官方api文档,这里举例说明基础的使用.推荐使用hook方法,但是在实际使用中应尽量避免修改grad的值. 求z对y的导数 x = V(t.ones(3)) w = V(t.rand(3),requires_grad=True) y = w.mul(x) z

『PyTorch』第六弹_最小二乘法的不同实现手段(待续)

PyTorch的Variable import torch as t from torch.autograd import Variable as V import matplotlib.pyplot as plt from IPython import display # 指定随机数种子 t.manual_seed(1000) def get_fake_data(batch_size=8): x = t.rand(batch_size,1)*20 y = x * 2 + 3 + 3*t.ran

『PyTorch』第五弹_深入理解Tensor对象_中上:索引

一.普通索引 示例 a = t.Tensor(4,5) print(a) print(a[0:1,:2]) print(a[0,:2]) # 注意和前一种索引出来的值相同,shape不同 print(a[[1,2]]) # 容器索引 3.3845e+15 0.0000e+00 3.3846e+15 0.0000e+00 3.3845e+15 0.0000e+00 3.3845e+15 0.0000e+00 3.3418e+15 0.0000e+00 3.3845e+15 0.0000e+00 3

『PyTorch』第五弹_深入理解Tensor对象_中下:数学计算以及numpy比较

一.简单数学操作 1.逐元素操作 t.clamp(a,min=2,max=4)近似于tf.clip_by_value(A, min, max),修剪值域. a = t.arange(0,6).view(2,3) print("a:",a) print("t.cos(a):",t.cos(a)) print("a % 3:",a % 3) # t.fmod(a, 3) print("a ** 2:",a ** 2) # t.po

『PyTorch』第五弹_深入理解Tensor对象_下:从内存看Tensor

Tensor存储结构如下, 如图所示,实际上很可能多个信息区对应于同一个存储区,也就是上一节我们说到的,初始化或者普通索引时经常会有这种情况. 一.几种共享内存的情况 view a = t.arange(0,6) print(a.storage()) b = a.view(2,3) print(b.storage()) print(id(a.storage())==id(b.storage())) a[1] = 10 print(b) 上面代码,我们通过.storage()可以查询到Tensor