[Pytorch系列-21]:Pytorch基础 - 反向链式求导的全过程拆解

Posted 文火冰糖的硅基工坊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Pytorch系列-21]:Pytorch基础 - 反向链式求导的全过程拆解相关的知识,希望对你有一定的参考价值。

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:


目录

第一章 自动求导的两种方法

1.1 半自动

1.2 全自动

第2章 自动求导的中间过程的拆解

2.1 链式求导的基本原理

2.2 定义支持自动求导的tensor

2.3 定义复合函数

2.4 全自动求导(求梯度)

2.5 指定函数链自动求导

2.6 分解式链式求导



第一章 自动求导的两种方法

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与反向自动求导机制

[Pytorch系列-19]:Pytorch基础 - Variable变量的使用方法与 Tensor变量的比较

[PyTroch系列-16]:PyTorch基础 - 张量的操作 - 变形