aotograd

任务描述

本关任务:

本关提供了一个张量变量tensor ,根据所给的张量创建 Variable 变量v,同时要求同学们掌握 Variable 的相关属性,例如如何获得 Variable 的 data 属性。

相关知识

之前我们学习” Pytorch 之 Tensor “中提过, Pytorch和 Numpy 有很多相似之处,而 Pytorch 与其最不同的地方在于 Pytorch 提供了自动求导功能,也就是可以自动计算出用户所需的参数的梯度,这个操作由另外一个基本元素提供——Variable。

本质上Variable和Tensor没有区别,多数情况下,将Tensor替换为Variable,代码一样会正常的工作。不过Variabel会放入一个计算图(computational graph),这个图将所有的计算步骤 (节点) 都连接起来,进行前向传播,反向传播以及自动求导。在最后进行误差反向传递时,一次性将所有 Variable 里面的梯度都计算出来,而Tensor 就没有这个能力啦。

autograd.Variable 是这个包中最核心的类。 它包装了一个 Tensor,并且几乎支持所有定义在其上的操作。一旦完成了运算,用户可以调用 .backward()来自动计算出所有的梯度,可以通过属性 .data 来访问原始的Tensor,而关于Variable的梯度则集中于 .grad 属性中。

创建 Variable

在创建之前,首先要引入相应的包,如下列代码所示:

import torch
from torch.autograd import Variable

基本形式:

Variable(data, requires_grad=True)

参数说明:

data: 任意的 tensor 类
requires_grad:是否参与误差反向传播, 是否计算计算梯度

应用示例:

tensor = torch.FloatTensor([[1,2],[3,4]])
variable = Variable(tensor, requires_grad=True)

输出结果:

Variable containing:
1  2
3  4
[torch.FloatTensor of size 2x2]

Variable 数据
利用variable.data可获取 Variable 中的张量。

应用示例:

print(variable.data)

输出结果:

1  2
 3  4
[torch.FloatTensor of size 2x2]

任务描述

本关要求掌握Variable 的基本属性及其意义,如requires_grad属性标记着该Variable 是否需要求导。

本关任务:

本关提供了一个32位浮点型的张量 x,要求同学们根据 x创建一个Variable类型的变量 y, y是由 x 的平方计算得到,并输出y的Requires Gradiet属性和Gradient属性。

相关知识

Variable 形式的数据, 在很多时候是用不了的( 比如想要用 plt 画图 ), 所以我们要转换一下, 将它变成 tensor 形式。

Variable 数据

之前我们学习了利用.data访问 Variable 的 Tensor,可以在此基础上利用 numpy() 转换为 numpy 类型。

应用示例:

print(variable.data.numpy())   

输出结果:

[[ 1.  2.]
 [ 3.  4.]]

grad_fn属性

PyTorch采用动态图设计,可以很方便地查看中间层的输出,动态的设计计算图结构。autograd根据用户对Variable的操作构建其计算图。其中,对变量的操作抽象为Function。

在 autograd 包中,还有一个对其实现非常重要的类——Function。Variable 和Function是相互关联的,并建立一个非循环图,从而完成完整的计算过程。

variable和function它们是彼此不分开的,先上图:

在这里插入图片描述

如图,假设我们有一个输入变量input,input是用户输入的,所以其创造者creator为null值,input经过第一个数据操作operation1(比如加减乘除运算)得到output1变量,这个过程中会自动生成一个function1的变量,而output1的创造者就是这个function1。随后,output1再经过一个数据操作生成output2,这个过程也会生成另外一个Function实例function2,output2的创造者creator为function2。

在这个向前传播的过程中,function1和function2记录了数据input的所有操作历史,当output2运行其backward函数时,会使得function2和function1自动反向计算input的导数值并存储在grad属性中。

若把整个操作流看成是一张图(Graph),那么像input这种creator为null的被称之为图的叶子(graph leaf),它不是任何函数(Function)的输出,而是由用户创建的节点,只有叶子节点才能被autograd,返回导数。而creator 非null的变量比如output1和output2,是不能被返回导数的,它们的grad均为None。

应用示例:

x = Variable(torch.ones(2, 2), requires_grad=True)
#在 x 基础上进行运算
y = x + 2 
print(x.grad_fn)
print(y.grad_fn)

y是作为运算的结果产生的,所以y有grad_fn,而x是直接创建的,所以x没有grad_fn。

输出结果:

None
<AddBackward0 object at 0x111413898>

相关属性
Variable 的主要属性如下所示:

.data
任意类型的封装好的张量。

.grad
保存与 data类型和位置相匹配的梯度,此属性难以分配并且不能重新分配。

.requires_grad
标记变量是否已经由一个需要调用到此变量的子图创建的 bool值。只能在叶子变量上进行修改。默认为 False,叶子节点指定 True后,依赖节点都被置为 True。

is_leaf
标记变量是否是子图叶子节点(如由用户创建的变量)bool值。

.volatile
标记变量是否能在推理模式下应用的 bool值。只能在叶子变量上更改。

应用示例:

print('Requires Gradient : %s ' % (variable.requires_grad))
print('Volatile : %s ' % (variable.volatile))
print('Gradient : %s ' % (variable.grad))
输出结果:

Requires Gradient : True 
Volatile : False 
Gradient : None

特别地,变量的requires_grad和volatile标记的运算就相当于or。 如下列所示:

x = Variable(torch.randn(5, 5))
y = Variable(torch.randn(5, 5))
z = Variable(torch.randn(5, 5), requires_grad=True)
a = x + y # x, y的 requires_grad的标记都为false, 所以输出的变量requires_grad也为false
print(a.requires_grad)
 #False
b = a + z
#a ,z 中,有一个 requires_grad 的标记为True,那么输出的变量的 requires_grad为True
print(b.requires_grad)
#True

注意: volatile =True相当于 requires _grad=False。但是在纯推断模式的时候,只要是输入 volatile =True,那么输出 Variable的 volatile必为 True。这就比使用 requires _grad=False方便多了。

NOTE:在使用 volatile =True的时候,变量是不存储 creator属性的,这样也减少了内存的使用。
background()
基本形式:

torch.autograd.backward(variables, grad_variables=None, retain_graph=None, create_graph=None, retain_variables=None)

用途:用以计算当前变量的梯度

参数说明:

variables (sequence of Variable):将要计算导数的变量

grad_variables (sequence of (Tensor, Variable or None))
相应变量的每个元素的梯度

Tensor:将自动转换为变量,当 create_graph为True时计算梯度

Variable:计算变量的梯度

None:被指定为标量梯度或不需要计算梯度的值

retain_graph (bool, optional)

False:用于计算梯度的图形将被释放
create_graph (bool, optional) 

True:图形的梯度将被计算,允许计算更高阶的导数
默认为False。
retain_variable

False:  反向传播之后这个计算图的内存会被释放

True : 反向传播之后这个计算图的内存不会被释放,可进行第二次进行第二次反向传播

该计算图使用链式规则进行求导。如果任何变量是非标量的(即它们的数据具有多于一个元素)并且需要梯度,则该函数另外需要指定grad_variables。

应用示例:

# Create tensors.
x = Variable(torch.Tensor([3]), requires_grad=True)
w = Variable(torch.Tensor([2]), requires_grad=True)
# Build a computational graph.
y = w * x + 4   # y =w * x + 4
# Compute gradients.
y.backward(retain_graph=True)
# Print out the gradients.
print(x.grad)    
print(w.grad)    

其中,对 y 的反向传播求解过程如下所示:

输出结果:

# x.grad = 2 对 y 式中的 x 求导
Variable containing:
 2
[torch.FloatTensor of size 1]

# w.grad = 3  对 y 式中的 w 求导
Variable containing:
 3
[torch.FloatTensor of size 1]

background()进阶

使用Variable.backward()求Variable的梯度的时候,Variable.grad是累加的。

应用示例:

y.backward()
# Print out the gradients.
print(x.grad)  
print(w.grad)   

输出结果:

Variable containing:
 4
[torch.FloatTensor of size 1]

Variable containing:
 6
[torch.FloatTensor of size 1]

既然累加的话,那我们如何置零呢?在上式的末尾添加以下语句,输出结果如下所示:

应用示例:

x.grad.data.zero_()
print(x.grad)

输出结果:

Variable containing:
 0
[torch.FloatTensor of size 1]

通过上面的方法,就可以将grad置零。

当要对矩阵求导时,backward需要传入一个参数,这个参数的维度必须是跟叶子结点的那个变量维度一致且元素值为1。比如叶子结点是2x2的矩阵,对backward传一个tensor.ones(2,2)即可。比如上式的y.backward()等价于y.backward(torch.Tensor([1.0]))。

在这里插入图片描述
在这里插入图片描述

torch.autograd.grad

基本语法:

torch.autograd.grad(outputs, inputs, grad_outputs=None, retain_graph=None, create_graph=None, only_inputs=True, allow_unused=False)

用途:计算并返回输入的输出梯度的总和。

参数说明:

outputs(可变序列)
差分函数的输出。

inputs(可变序列)
输入将返回梯度的积分(并不积累.grad)。

grad_outputs(Tensor 或Variable的序列) 
每个输出的梯度。任何张量将被自动转换为volatile,除非create_graph为True。

retain_graph(bool,可选)

如果为 False,则用于计算 grad的图形将被释放。

请注意,在几乎所有情况下,将此选项设置为 True不是必需的,通常可以以更有效的方式解决。

默认值为create_graph。

create_graph(bool,可选)

如果为True,则构造导数的图形,允许计算高阶衍生产品。

默认为False,除非grad_variables包含至少一个非易失性变量。

only_inputs(bool,可选) 

为True,则渐变 wrt离开是图形的一部分,但不显示inputs不会被计算和累积。

默认为True

allow_unused(bool, 可选) 

默认为False.

属性相关说明:

grad_outputs是匹配包含每个输出的预先计算的梯度的长度序列。如果输出不需要 grad,则梯度可以是None。

如果only_inputs为True,该函数将仅返回指定输入的梯度列表。如果它是False,则仍然计算所有剩余叶子的梯度,并累积到输入的.grad 属性中。

应用示例:

x=torch.FloatTensor([1,2,3])
x = Variable(x, requires_grad=True)
y = x * x
print(y)
dy_dx = torch.autograd.grad(y, x, grad_outputs=torch.ones(1,3)) 
print(dy_dx)

输出结果:

Variable containing:
 1
 4
 9
[torch.FloatTensor of size 3]

(Variable containing:
 2  4  6
[torch.FloatTensor of size 1x3]
,)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值