Pytorch(三) —— Variable(volatile=True) & torch.autograd.grad & python对函数求导(sympy)

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值