pytorch两个基本对象:Tensor(张量)和Variable(变量)
其中,tensor不能反向传播,variable可以反向传播。
tensor的算术运算和选取操作与numpy一样,一次你numpy相似的运算操作都可以迁移过来。
Variable
variable是一种可以不断变化的变量,符合反向传播,参数更新的属性。pytorch的variable是一个存放会变化值的地理位置,里面的值会不停变化,像装糖果(糖果就是数据,即tensor)的盒子,糖果的数量不断变化。pytorch都是由tensor计算的,而tensor里面的参数是variable形式。
扩展
在PyTorch中计算图的特点总结如下:
autograd根据用户对Variable的操作来构建其计算图。
1、requires_grad
variable默认是不需要被求导的,即requires_grad属性默认为False,如果某一个节点的requires_grad为True,那么所有依赖它的节点requires_grad都为True。
2、volatile
variable的volatile属性默认为False,如果某一个variable的volatile属性被设为True,那么所有依赖它的节点volatile属性都为True。volatile属性为True的节点不会求导,volatile的优先级比requires_grad高。
3、retain_graph
多次反向传播(多层监督)时,梯度是累加的。一般来说,单次反向传播后,计算图会free掉,也就是反向传播的中间缓存会被清空【这就是动态度的特点】。为进行多次反向传播需指定retain_graph=True来保存这些缓存。
4、backward(grad_variables=None,retain_graph=None,create_graph=None)
反向传播,求解Variable的梯度。放在中间缓存中。
PyTorch 的 backward 为什么有一个 grad_variables 参数?
假设 x 经过一番计算得到 y,那么 y.backward(w) 求的不是 y 对 x 的导数,而是 l = torch.sum(y*w) 对 x 的导数。w 可以视为 y 的各分量的权重,也可以视为遥远的损失函数 l 对 y 的偏导数。也就是说,不一定需要从计算图最后的节点 y 往前反向传播,从中间某个节点 n 开始传也可以,只要你能把损失函数 l 关于这个节点的导数 dl/dn 记录下来,n.backward(dl/dn) 照样能往前回传,正确地计算出损失函数 l 对于节点 n 之前的节点的导数。特别地,若 y 为标量,w 取默认值 1.0,才是按照我们通常理解的那样,求 y 对 x 的导数。
5、grad_variable
grad_variables是y求导时的梯度参数,由于autograd仅用于标量,因此当y不是标量且在声明时使用了requires_grad=True,必须指定grad_variables参数,在完成原始的反向传播之后得到的梯度会对这个grad_variables进行修正,然后将结果保存在Variable的grad中。grad_variables形状必须与Variable一致。在深度学习中求导与梯度有关,因此grad_variables一般会定义类似为[1, 0.1, 0.01, 0.001],表示梯度的方向,取较小的之不会对求导效率有影响。
>>>import torch >>>from torch.autograd import Variable >>> x=torch.rand(4) >>> x tensor([0.4635, 0.4753, 0.1375, 0.3797]) >>> x=variable(x,requires_grad=True) >>> y=x*3 >>> y tensor([1.3905, 1.4260, 0.4125, 1.1391], grad_fn=<MulBackward0>) >>> grad_variables = torch.FloatTensor([1,2,3,4]) #梯度参数grad_variables形状必须与Variable一致 >>> grad_variables tensor([1., 2., 3., 4.]) >>> y.backward(grad_variables) >>> x.grad tensor([ 3., 6., 9., 12.])