当前位置: 首页 > article >正文

深度学习--链式法则

可以链接一个多元函数所有变量偏导数方式计算梯度

偏导计算示例

函数z = f(x,y) = 3x^2y + 2xy^2

zxy偏导数

x偏导数

y常熟x导数

= 3x2xy + 2y^2

y偏导数

3x^2 + 2x x 3y^2

2.4.4 链式法则

用上吗方法可能很难找到梯度因为深度学习中多元函数通常是复合, 所以难以应用上述任何规则这些函数微分幸运链式法则可以用来复合函数微分

我们考虑变量函数假设函数y = f(u) u = g(x) 都是根据链式法则

dy/dx = dy/du

现在考虑一个更一般场景函数具有任意数量变量情况假设可微函数y变量u1, u2,.. un 其中每个可微函数u都有变量x1,x2,...xn 注意yx1,x2..xn函数对于任意i = 1,2,...n 链式法则给出

2.5 自动微分

正如2.4所述求导几乎所有深度学习优化算法关键步骤虽然求导计算简单只需要一些基本微积分知识但是对于复杂模型手动进行更新一件痛苦事情

深度学习框架通过自动计算导数自动微分加快求导实践中根据设计好的模型系统构建一个计算跟踪计算哪些数据通过哪些操作组合起来产生输出自动微分使系统能够随后传播梯度这里反向传播意味着跟踪整个计算图填充关于每个参数偏导数

2.5.1 一个简单例子

作为一个演示例子假设我们函数y = 2x^Tx关于向量x求导我们创建变量x分配一个初始值

import torch

x = torch.arange(4.0)

tensor([0,1,2,3])

在我们计算y关于x梯度之前需要一个区域存储梯度重要我们不会每次一个参数求导分配新的内存因为我们经常成千上万更新相同参数如果每次分配新的内存可能很快就回内存耗尽注意一个标量函数关于向量x梯度向量并且x具有相同形状

x.requires_grad_(True)

x.grad

现在计算y

y = 2 * torch.dot(x,y)

tensor(28,grad_fn)

x一个长度4向量计算xx得到了我们赋值y标量输出接下来通过调用反向传播函数自动计算y关于x每个分量梯度打印这些梯度

y.backward()

x.grad

函数y=2x^Tx 关于x梯度4x我们快速验证这个梯度是否计算正确

x.grad == 4 * x

现在计算x另一个函数

默认情况下PyTorch累积梯度我们需要清除之前

x.grad.zero()

y = x.sum()

y.backward()

x.grad

2.5.2 标量传播

y不是标量向量y关于向量x导数自然解释是一个矩阵对于高阶高纬yx求导结果可以一个高阶张量

然而虽然这些更奇特对象确实出现高级机器学习调用向量反向传播函数计算时我们通常试图计算第一批训练样本每个组成部分损失函数导数这里我们目的不是计算微分矩阵而是单独计算批量每个样本偏导数之和

非标量调用backward函数需要传入一个gradient参数参数指定微分函数关于self梯度本例只想偏导数所以传递一个1梯度合适

x.grad.zero()

y = x*x

等价于y.backward(torch.ones(len(x)))

y.sum().backward()

x.grad()

2.5.3 分离计算

有时我们希望某些计算移到记录计算之外例如假设y作为x函数计算z则是作为yx函数计算想象一下我们计算z关于x梯度但是由于某种原因希望y视为一个常数并且考虑xy计算后发挥作用

这里可以分离y来返回一个新变量u变量y具有相同但是丢弃计算图中如何计算y任何信息换句话说梯度不会向后ux因此下面方向传播函数计算z = u*x关于x偏导数同时u作为常数处理而不是计算z=x*x*x关于x偏导数

x.grad.zero()

y=x*x

u = y.detach()

z=u*x

由于记录y计算结果因此我们可以随后y调用反向传播函数得到y=x*x关于x导数2*x

x.grad.zero()

y.sum().backward()

x.grad = 2*x

2.5.4 Python控制流梯度计算

使用自动微分一个好处即使构造函数计算需要通过Python控制我们可以计算得到变量梯度下面代码While 循环迭代次数if语句结果都取决于输入a

def f(a)

b = a *2

while b.norm() < 1000;

b = b * 2;

if b.sum() > 0

c = b;

else

c = 100 * b;

return c

我们计算梯度

a = torch.randn(size=(), requires_grad=True)

d = f(a)

d.backward()

我们现在可以分析上面定义f函数注意它在输入a分段线性换言之对于任何a存在某个常量标量k使得f(a) = k*a, 其中k取决于输入a因此可以d/a验证梯度是否正确


http://www.kler.cn/a/597503.html

相关文章:

  • RK3588开发笔记-RTL8852wifi6模块驱动编译报错解决
  • Starrocks 命令 Alter table DISTRIBUTED 重分布数据的实现
  • Java常用类
  • 使用Aspera高速上传文件到ncbi
  • Mac | Excel | 列数改为和行数一样用数字表示
  • 操作系统为ubantu的服务器上部署nginx软件基础步骤总结
  • 5(五)Jmeter监控服务器性能
  • 【机器学习】机器学习工程实战-第2章 项目开始前
  • 网络安全应急入门到实战
  • pytorch3d学习(五)——批量输出图片+对渲染器的位姿解读+npy文件解读
  • 图像回归评价的常用指标
  • 3. 轴指令(omron 机器自动化控制器)——>MC_ImmediateStop
  • 基于STC89C52的8255并行口拓展实验
  • Transformers x SwanLab:可视化NLP模型训练(2025最新版)
  • vue3:十一、主页面布局(优化页面跳转方式)
  • Android:蓝牙设置配套设备配对
  • 机器学习--DBSCAN聚类算法详解
  • 【空地协同异构机器人系统之无人机点云引导无人车实时避障技术研究】
  • 考研复习之队列
  • 反反爬虫技术指南:原理、策略与合规实践