Variable
在旧版本中variable和tensor的区别在于,variable可以进行误差的反向传播,而tensor不可以。但是现在在新版本的torch中可以直接使用tensor而不需要使用variable。
从0.4起, Variable 正式合并入Tensor, Variable 本来实现的自动微分功能,Tensor就能支持。读者还是可以使用Variable(tensor), 但是这个操作其实什么都没做。建议读者以后直接使
用tensor.
volatile=True
volatile=True是Variable的另一个重要的标识,它能够将所有依赖它的节点全部设为volatile=True,其优先级比requires_grad=True高。因而volatile=True的节点不会求导,即使requires_grad=True,也不会进行反向传播,对于不需要反向传播的情景(inference,测试推断),该参数可以实现一定速度的提升,并节省一半的显存,因为其不需要保存梯度。
autograd
单独求导数 torch.autograd.grad()
torch.autograd计算单变量标量函数 y=x^3+sin(x) 在x分别为1,pi和5时的一阶导数和二阶导数
import torch import numpy as np #%% 方法1:采用torch.autograd.grad x = torch.tensor([1, np.pi, 5],requires_grad=True) y = x**3 + torch.sin(x) dy = 3*x**2 + torch.cos(x) d2y = 6*x - torch.sin(x) dydx = torch.autograd.grad(y, x, grad_outputs=torch.ones(x.shape), #注意这里需要人为指定 create_graph=True, retain_graph=True) # 为计算二阶导保持计算图 print(dydx) # 注意输出是一个tuple,取第一个元素 # (tensor([ 3.5403, 28.6088, 75.2837], grad_fn=<AddBackward0>),) print(dy) # tensor([ 3.5403, 28.6088, 75.2837], grad_fn=<AddBackward0>) d2ydx2 = torch.autograd.grad(dydx[0],x, grad_outputs=torch.ones(x.shape), create_graph=False) # 默认会自动销毁计算图 print(d2ydx2) # (tensor([ 5.1585, 18.8496, 30.9589]),) print(d2y) # tensor([ 5.1585, 18.8496, 30.9589], grad_fn=<SubBackward0>) #%% 方法2:采用torch.autograd.backword x = torch.tensor([1, np.pi, 5],requires_grad=True) y = x**3 + torch.sin(x) dy = 3*x**2 + torch.cos(x) d2y = 6*x - torch.sin(x) torch.autograd.backward(y, grad_tensors=torch.ones(x.shape), create_graph=True, retain_graph=False) print(x.grad) #一阶导 # tensor([ 3.5403, 28.6088, 75.2837], grad_fn=<CopyBackwards>) torch.autograd.backward(x.grad, grad_tensors=torch.ones(x.shape), create_graph=False, retain_graph=False) #采用backword的方法并且在求一阶导的时候设置了create_graph时,该结果是两次梯度的累加结果 print(x.grad) # tensor([ 8.6988, 47.4584, 106.2426], grad_fn=<CopyBackwards>)
Python对函数求导 sympy
from sympy import * x, y = symbols('x, y') z = x ** 3 + y ** 3 + x * y + 3 print(z) result = z.subs({x: 2, y: 2}) # 用数值分别对x、y进行替换 print(result) dx = diff(z, x) # 对x求偏导 print(dx) result = dx.subs({x: 2, y: 2}) print(result) dy = diff(z, y) # 对y求偏导 print(dy) result = dy.subs({x: 2, y: 2}) print(result)
Pytorch(三) —— Variable(volatile=True) & torch.autograd.grad & python对函数求导(sympy)
于 2020-05-24 22:07:02 首次发布