欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

pytorch autograd计算标量函数二阶导数

程序员文章站 2022-07-12 23:09:40
...

计算标量函数: y = x 3 + s i n ( x ) y=x^3+sin(x) y=x3+sin(x)
x = 1 , π , 5 x=1,\pi,5 x=1,π,5时的一阶导 d y d x \frac{dy}{dx} dxdy和二阶导 d 2 y d x 2 \frac{d^2y}{dx^2} dx2d2y,程序代码如下:

# -*- coding: utf-8 -*-
"""
Created on Mon Sep 28 08:59:50 2020

@author: 周文青

利用torch.autograd计算单变量标量函数y=x^3+sin(x)在x分别为1,pi和5时的一阶导数和二
阶导数

"""
import torch as tc
import numpy as np

#%% 方法1:采用torch.autograd.grad
x  = tc.tensor([1, np.pi, 5],requires_grad=True)
y = x**3 +  tc.sin(x)
dy = 3*x**2 + tc.cos(x)
d2y = 6*x - tc.sin(x)

dydx = tc.autograd.grad(y, x, 
                        grad_outputs=tc.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 = tc.autograd.grad(dydx[0],x, 
                          grad_outputs=tc.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  = tc.tensor([1, np.pi, 5],requires_grad=True)
y = x**3 +  tc.sin(x)
dy = 3*x**2 + tc.cos(x)
d2y = 6*x - tc.sin(x)

tc.autograd.backward(y, grad_tensors=tc.ones(x.shape),
           create_graph=True, retain_graph=False)
print(x.grad) #一阶导
# tensor([ 3.5403, 28.6088, 75.2837], grad_fn=<CopyBackwards>)
tc.autograd.backward(x.grad, grad_tensors=tc.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>)

pytorch实现了自动微分功能,可以自动计算梯度,因此后续可以研究使用pytorch实现一些利用梯度信息的优化算法,包括单变量情况和多变量情况的,例如one line search中的牛顿法梯度下降法共轭梯度算法等。