1.介绍Variable
实际上,Variable是Torch里的一种数据类型,他与tensor没有什么很大的区别,但
是他们属于不同的数据类型,Variable对象有更多的属性。主要的区别如下:
①、Variable类型的变量具有自动求导的功能
②、Variable类型的变量会被放到一个计算图中,Variable类型的变量具有三个属性:data、grad、grad_fn:
data: 取出Variable里面的tensor数值
grad:是variable的反向传播梯度,也就是求导的结果
grad_fn: 是指得到这个Variable所要进行的操作,比如是通过加减乘除,下面有具体的例子。如果是
Variable是在torch.autograd中,注意引用Variable的时候要导入
import torch
from torch. autograd import Variable
先看看Tensor和Variable的区别:
a = torch. Tensor( [ 1 ] )
b = Variable( a)
print ( a)
print ( b)
tensor([1.])
tensor([1.])
再看看Variable()的三个属性以及他们的用法:其中requires_grad = True表示的是,是否对这个变量求导,默认的情况下是False
x = Variable( torch. Tensor( [ 1 ] ) , requires_grad = True )
w = Variable( torch. Tensor( [ 2 ] ) , requires_grad = True )
b = Variable( torch. Tensor( [ 3 ] ) , requires_grad = True )
print ( x)
print ( w)
print ( b)
tensor([1.], requires_grad=True)
tensor([2.], requires_grad=True)
tensor([3.], requires_grad=True)
y = w * x + b
我们都知道Variable具有自动求导的功能,用.backward()实现对y的所有变量进行求导,求导的结果
y. backward( )
属性1,输出其导数
print ( x. grad)
print ( w. grad)
print ( b. grad)
tensor([2.])
tensor([1.])
tensor([1.])
所求得导数还是Tensor类型的,这是对标量进行的求导,下面有对矩阵求的导,下
属性2,输出其data
print ( x. data)
print ( w. data)
print ( b. data)
tensor([1.])
tensor([2.])
tensor([3.])
属性3,输出所得到的这个Variable的操作,注意!!如果是直接通过Variable(Tensor),输出的是non
print ( x. grad_fn)
print ( w. grad_fn)
print ( b. grad_fn)
print ( y. grad_fn)
None
None
None
<AddBackward0 object at 0x000001F187AADEF0>
对 y.backward() # same as y.backward(torch.FloatTensor([1]))的解释:
所谓的自动求导,不需要你明确的说明那个函数对那个函数进行的求导,通过这行代码就可以对所
有的 ** 需要求梯度(导数)** 的变量进行求导,得到他们的梯度,
y.backward(torch.FloatTensor([1])),实际上y.backward()里面有参数,对标量求导没写
对矩阵的求导:
x = torch. randn( 3 )
x
tensor([ 2.7666, -1.5363, 0.4382])
x = Variable( x, requires_grad = True )
x
tensor([ 2.7666, -1.5363, 0.4382], requires_grad=True)
y = x * 2
print ( y)
tensor([ 5.5331, -3.0726, 0.8765], grad_fn=<MulBackward0>)
y. backward( torch. FloatTensor( [ 1 , 0.1 , 0.01 ] ) )
print ( x. grad)
tensor([2.0000, 0.2000, 0.0200])
y自动求导后,变量x的导数是[2,2,2],然后与1,0.1,0.01相乘,这相当于给出了一个三维向量去做运算,此时就不能直接写成y.backward(),y.backward(torch.FloatTensor([1,1,1]))是得到他们每个分量的梯度,y.backward(torch.FloatTensor([1,0.1,0.01]))他们每个分量的梯度分别乘上1,0.1,0.01