[Pytorch系列-21]:Pytorch基础 - 反向链式求导的全过程拆解
Posted 文火冰糖的硅基工坊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Pytorch系列-21]:Pytorch基础 - 反向链式求导的全过程拆解相关的知识,希望对你有一定的参考价值。
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:
目录
第一章 自动求导的两种方法
Pytorch有两种方式进行自动求导。
1.1 半自动
这种方法,使用torch的全局函数,需要指定求导的函数以及相应的偏导数对象。
y = wx + b
dy = torch.autograd.grad(y, [w,b], retain_graph=True)
备注:这种方式获得的梯度,直接通过函数返回,并没有存放到w,b的tensor中。
1.2 全自动
这种方法,使用输出tensor的成员函数,不需要指定偏导数对象,它对函数中所有的表示了requires_grad=True的参数,自动全部求导。
y = wx + b
y.backward(retain_graph=True)
备注:这种方式获得的梯度,自动存放在w和b的tensro中。
第2章 自动求导的中间过程的拆解
2.1 链式求导的基本原理
2.2 定义支持自动求导的tensor
#环境准备
import numpy as np
import math
import matplotlib.pyplot as plt
%matplotlib inline
import torch
from torch.autograd import Variable
print("Hello World")
print(torch.__version__)
print(torch.cuda.is_available())
print("定义样本数据")
x = torch.Tensor([1])
print("\\n定义参数tensor")
w2 = torch.tensor([4.], requires_grad=True)
b2 = torch.tensor([5.], requires_grad=True)
w1 = torch.tensor([2.], requires_grad=True)
b1 = torch.tensor([3.], requires_grad=True)
print("w2=", w2)
print("b2=", b2)
print("w1=", w1)
print("b1=", b1)
定义样本数据 定义参数tensor w2= tensor([4.], requires_grad=True) b2= tensor([5.], requires_grad=True) w1= tensor([2.], requires_grad=True) b1= tensor([3.], requires_grad=True)
2.3 定义复合函数
print("\\n定义一级函数")
y1 = w1 * x + b1
print("y1=", y1)
print("\\n定义二级函数")
y2 = w2 * y1 + b2
print("y2=", y2)
定义一级函数 y1= tensor([5.], grad_fn=<AddBackward0>) 定义二级函数 y2= tensor([25.], grad_fn=<AddBackward0>)
2.4 全自动求导(求梯度)
print("\\n(1)全过程自动链式求导")
y2.backward(retain_graph=True)
print("w1.grad=", w1.grad)
print("b1.grad=", b1.grad)
print("w2.grad=", w2.grad)
print("b2.grad=", b2.grad)
(1)全过程自动链式求导 w1.grad= tensor([4.]) b1.grad= tensor([4.]) w2.grad= tensor([5.]) b2.grad= tensor([1.])
2.5 指定函数链自动求导
print("\\n(2)指定链自动链式求导")
dy2_dw1 = torch.autograd.grad(y2, [w1], retain_graph=True)[0]
dy2_db1 = torch.autograd.grad(y2, [b1], retain_graph=True)[0]
dy2_dw2 = torch.autograd.grad(y2, [w2], retain_graph=True)[0]
dy2_db2 = torch.autograd.grad(y2, [b2], retain_graph=True)[0]
print("dy2_dw1=", dy2_dw1)
print("dy2_db1=", dy2_db1)
print("dy2_dw2=", dy2_dw2)
print("dy2_db2=", dy2_db2)
(2)指定链自动链式求导 dy2_dw1= tensor([4.]) dy2_db1= tensor([4.]) dy2_dw2= tensor([5.]) dy2_db2= tensor([1.])
2.6 分解式链式求导
print("\\n(3)分步式自动链式求导")
dy2_dw2 = torch.autograd.grad(y2, [w2], retain_graph=True)[0]
dy2_db2 = torch.autograd.grad(y2, [b2], retain_graph=True)[0]
print("dy2_dw2=", dy2_dw2)
print("dy2_db2=", dy2_db2)
print("")
dy2_dy1 = torch.autograd.grad(y2, [y1], retain_graph=True)[0]
print("dy2_dy1=", dy2_dy1)
dy1_dw1 = torch.autograd.grad(y1, [w1], retain_graph=True)[0]
dy1_db1 = torch.autograd.grad(y1, [b1], retain_graph=True)[0]
print("dy1_dw1=", dy1_dw1)
print("dy1_db1=", dy1_db1)
print("")
print("dy2_dw1=", dy2_dy1 * dy1_dw1)
print("dy2_db1=", dy2_dy1 * dy1_db1)
(3)分步式自动链式求导 dy2_dw2= tensor([5.]) dy2_db2= tensor([1.]) dy2_dy1= tensor([4.]) dy1_dw1= tensor([1.]) dy1_db1= tensor([1.]) dy2_dw1= tensor([4.]) dy2_db1= tensor([4.])
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/120298291
以上是关于[Pytorch系列-21]:Pytorch基础 - 反向链式求导的全过程拆解的主要内容,如果未能解决你的问题,请参考以下文章
深度学习系列21:pytorch lightning和torchline
[Pytorch系列-18]:Pytorch基础 - 张量的范数
[Pytorch系列-20]:Pytorch基础 - Varialbe变量的手工求导和自动链式求导
[Pytorch系列-22]:Pytorch基础 - Autograd库 Autograd.Function与反向自动求导机制