Loading [MathJax]/jax/output/HTML-CSS/jax.js

【AI系统】微分计算模式

简介: 本文深入探讨了自动微分技术,这是AI框架中的核心功能。自动微分分为前向微分和后向微分两种模式,主要通过雅克比矩阵实现。前向模式适用于输出维度大于输入的情况,而后向模式则更适合多参数场景,广泛应用于现代AI框架中。文章还详细解释了这两种模式的工作原理、优缺点及应用场景。

上一篇文章简单了解计算机中常用几种微分方式。本文将深入介绍 AI 框架离不开的核心功能:自动微分。

而自动微分则是分为前向微分和后向微分两种实现模式,不同的实现模式有不同的机制和计算逻辑,而无论哪种模式都离不开雅克比矩阵,所以我们也会深入了解一下雅克比矩阵的原理。

雅克比矩阵

在向量微积分中,Jacobian 矩阵是一阶偏导数以一定方式排列成的矩阵,其行列式称为 Jacobian 行列式。Jacobian 矩阵的重要性在于它体现了一个可微方程与给出点的最优线性逼近。

Jacobian 矩阵表示两个向量所有可能的偏导数。它是一个向量相对于另一个向量的梯度,其实现的是 n 维向量到 m 维向量的映射。

在矢量运算中,Jacobian 矩阵是基于函数对所有变量一阶偏导数的数值矩阵,当输入个数等于输出个数时又称为 Jacobian 行列式。

假设输入向量 𝑥𝑅n,而输出向量 𝑦𝑅m,则 Jacobian 矩阵定义为:

Jf=[δy1δx1δy1δxnδymδx1δymδxn]

微分计算模式

根据对分解后的基本操作求导和链式规则组合顺序的不同,自动微分可以分为两种模式:

  • 前向模式(Forward Automatic Differentiation,也叫做 tangent mode AD)或者前向累积梯度(前向模式);

  • 反向模式(Reverse Automatic Differentiation,也叫做 adjoint mode AD)或者说反向累计梯度(反向模式)。

计算模式区别

两种自动微分模式都通过递归方式来求 dy/dx,只不过根据链式法则展开的形式不太一样。

前向梯度累积会指定从内到外的链式法则遍历路径,即先计算 dw1/dx,再计算 dw2/dw1,最后计算 dy/dw2。即,前向模式是在计算图前向传播的同时计算微分。因此前向模式的一次正向传播就可以计算出输出值和导数值。

dwidx=dwidwi1dwi1dx

反向梯度累积正好相反,它会先计算 dy/dw2,然后计算 dw2/dw1,最后计算 dw1/dx。这是最为熟悉的反向传播模式,它非常符合沿模型误差反向传播这一直观思路。

即,反向模式需要对计算图进行一次正向计算,得出输出值,再进行反向传播。反向模式需要保存正向传播的中间变量值(比如 wi),这些中间变量数值在反向传播时候被用来计算导数,所以反向模式的内存开销要大。

dydwi=dydwi+1dwi+1dwi

即如图所示,前向自动微分(tangent mode AD)和后向自动微分(adjoint mode AD)分别计算了 Jacobian 矩阵的一列和一行。

image

前向自动微分(tangent mode AD)可以在一次程序计算中通过链式法则,得到:

δxkδx0j=δxkδxk1δk1δx0j

递推得到 Jacobian 矩阵中与单个输入有关的参数,即 Jacobian 矩阵的一列。

后向自动微分(adjoint mode AD)利用链式法则,得到:

δxLiδxk=δxLiδxk+1δk+1δxk

可以仅通过一次对计算过程的遍历得到 Jacobian 矩阵的一行。但它的导数链式法则传递方向和程序执行方向相反,所以需要在程序计算过程中记录一些额外的信息来辅助求导,这些辅助信息包括计算图和计算过程的中间变量。

样例

我们以公式为例,首先把它转换成一个计算图:

f(x1,x2)=ln(x1)+x1x2sin(x2)

  • 输入变量:自变量维度为 n,这里 n=2,输入变量就是 x1, x2

  • 中间变量:中间变量这里是 v1v5,在计算过程中,只需要针对这些中间变量做处理即可将符号微分法应用于最基本的算子,然后代入数值,保留中间结果,最后再应用于整个函数;

  • 输出变量:假设输出变量维度为 m,这里 m=1,输出变量就是 y1,也就是 f(x1,x2)

image

转化成如上 DAG(有向无环图)结构之后,我们可以很容易分步计算函数的值,并求取它每一步的导数值,然后,我们把 df/dx1 求导过程利用链式法则表示成如下的形式:

dfdx1=dv1dx1(dv1dv1dv4dv1+dv2dv1dv4dx2)dv5dv4dfdv5

整个求导可以被拆成一系列微分算子的组合。

前向模式 Foward Mode

前向模式从计算图的起点开始,沿着计算图边的方向依次向前计算,最终到达计算图的终点。它根据自变量的值计算出计算图中每个节点的值以及其导数值,并保留中间结果。一直得到整个函数的值和其导数值。整个过程对应于一元复合函数求导时从最内层逐步向外层求导。

同样,以公式为例子:

f(x1,x2)=ln(x1)+x1x2sin(x2)

面是前向模式的计算过程,下表中,左半部分是从左往右每个图节点的求值结果和计算过程,右半部分是每个节点对 x1 的求导结果和计算过程。这里 ˙vi 表示 vi𝑥1 的偏导数。即:

˙vi=δviδx1

在该示例中,我们希望计算函数在 x1=2,x2=5 处的导数 dy/dx1,即:

˙yj=δyjδxi

可以看出,左侧是源程序分解后得到的基本操作集合,而右侧则是每一个基本操作根据已知的求导规则和链式法则由上至下计算的求导结果。

image

计算过程

根据上图左边的 Forward Primal Trace 直接计算公式,对于节点数值的计算如下:

  1. 我们给输入节点赋值,v1=x1=2v0=x2=5
  2. 计算 v1 节点,v1=lnv1=lnx1=ln2
  3. 计算 v2 节点,节点 v2 依赖于 v1v0v2=10
  4. 计算 v3 节点,v3=sinv0=sin5
  5. 计算 v4 节点,v4=v1+v2=0.693+10
  6. 计算 v5 节点,v5=v1+v2=10.693+0.959
  7. 最终 y=v5=11.652

此时,已经得到了图中所有节点的数值。自动微分正向模式中(上图右边 Forward Tangent Trace),在计算节点数值的同时,也一起计算导数,假设求 δy/δx1,则是从输入开始计算。

  1. 计算 v1 节点对于 x1 的梯度:v1=x1,所以 δv1/δx1=1
  2. 计算 v0 节点对于 x1 的梯度:v0=x2,所以 δv0/δx1=0
  3. 计算 v1 节点对于 x1 的梯度:δv1/δx1=0.5
  4. 计算 v2 节点对于 x1 的梯度:δv2/δx1=(δv1/δx1)v0+(δv0/δx1)v1=5
  5. 计算 v3 节点对于 x1 的梯度:δv3/δx1=(δv0/δx1)cosv0=0
  6. 计算 v4 节点对于 x1 的梯度:δv4/δx1=δv1/δx1+δv2/δx1=0.5+5
  7. 计算 v5 节点对于 x1 的梯度:δv5/δx1=5.5=0
  8. 因此,得到 δy/δx1=δv5/δx1=5.5

从计算过程来看啦,自动微分的前向模式实际上与我们在微积分里所学的求导过程一致。

雅克比-向量矩阵

把上述过程当做雅克比矩阵求解问题,假设一个函数有 n 个输入变量 xi,m 个输入变量 yj,即输入向量 xRn,yRm,则这个的映射是:

f:RnRm

在这种情况下,每个自动微分的前向传播计算时候,初始输入被设置为 ˙xi=1,其余被设置为 0。对应 Jacobian 矩阵定义为:

Jf=[δy1δx1δy1δxnδymδx1δymδxn]

一次前向计算,可以求出 Jacobian 矩阵的一列数据,如 ˙x3=1 对应就可以求出来第 3 列。tangent mode AD 可以在一次程序计算中,通过链式法则递推得到 Jacobian 矩阵中与单个输入有关的部分,即 Jacobian 矩阵的一列。

如图所示,如果想用正向模式求对所有输入的导数,需要计算 n 次才能求出所有列。

进一步,设置 ˙x=r,可以在一次前向传播中直接计算 Jacobian–vector 乘积:

Jfr=[δy1δx1δy1δxnδymδx1δymδxn][r1rn]

最终我们可以递归的得到本次迭代的计算目标:雅克比矩阵中的第 i 行。

优缺点

前向模式的优点:

  • 实现起来很简单;

  • 也不需要很多额外的内存空间。

向前模式的缺点:

  • 每次前向计算只能计算对一个自变量的偏导数,对于一元函数求导是高效的,但是机器学习模型的自参数(入参)数量级大。

  • 如果有一个函数,其输入有 n 个,输出有 m 个,对于每个输入来说,前向模式都需要遍历计算过程以得到当前输入的导数,求解整个函数梯度需要 n 遍如上计算过程。

反向模式 Reverse Mode

反向自动微分同样是基于链式法则。仅需要一个前向过程和反向过程,就可以计算所有参数的导数或者梯度。

因为需要结合前向和后向两个过程,因此反向自动微分会使用一个特殊的数据结构,来存储计算过程。

而这个特殊的数据结构例如 TensorFlow 或者 MindSpore,则是把所有的操作以一张图的方式存储下来,这张图可以是一个有向无环(DAG)的计算图;而 PyTroch 则是使用 Tape 来记录每一个操作,他们都表达了函数和变量的关系。

反向模式根据从后向前计算,依次得到对每个中间变量节点的偏导数,直到到达自变量节点处,这样就得到了每个输入的偏导数。在每个节点处,根据该节点的后续节点(前向传播中的后续节点)计算其导数值。

整个过程对应于多元复合函数求导时从最外层逐步向内侧求导。这样可以有效地把各个节点的梯度计算解耦开,每次只需要关注计算图中当前节点的梯度计算。

从下图可以看出来,reverse mode 和 forward mode 是一对相反过程,reverse mode 从最终结果开始求导,利用最终输出对每一个节点进行求导。下图虚线就是反向模式。

image

计算过程

前向和后向两种模式的过程表达如下,表的左列浅色为前向计算函数值的过程,与前向计算时相同,右面列深色为反向计算导数值的过程。

反向模式的计算过程如图所示,其中:

¯vi=δyδvi

根据链式求导法则展开有:

fx=Nk=1fvkvkx

可以看出,左侧是源程序分解后得到的基本操作集合,而右侧则是每一个基本操作根据已知的求导规则和链式法则由下至上计算的求导结果。

image

  1. 计算 yv5 的导数值,即 ¯v5=¯y=1
  2. 计算 y 对 v4 的导数值,¯v4=¯v5δv5δv4=1
  3. 计算 y 对 v3 的导数值,¯v3=¯v5δv5δv3=1
  4. 计算 y 对 v1 的导数值,¯v1=¯v4δv4δv1=1
  5. 计算 y 对 v2 的导数值,¯v2=¯v4δv4δv1=1
  6. 接下来要计算 y 对 v0 的导数值和 y 对 v1 的导数值,因为 v0v1 都是后续有两个节点,因此需要分开计算;
  7. 计算 δv3δv0=cosv0=0.284
  8. 计算 δv2δv0=v1=2
  9. 计算 δv2δv1=v0=5
  10. 计算 δv1δv1=1x1=0.5

到目前为止,我们已经计算出来了所有步骤的偏导数的数值。现在需要计算 ¯v1¯v2 。计算 ¯v1 从最后的位置往前到自变量 x1,有多条路径,需要将这个路径上的数值连乘起来得到一个乘积数值,然后将这多条路径的乘积数值相加起来得到最后的结果。

yx1 的路径有两条,分别是:

  1. v5v4v1v1,其数值乘积是 1∗1∗0.5=0.5;
  2. v5v4v2v1,其数值乘积是 1∗1∗ 5= 5。

因此,¯v1=0.5+5=5.5,同理有 ¯v2=2.00.284=1.716

向量-雅克比矩阵

对于函数 ¯y=f(¯x),其中 f:RnRm,那么 ¯y 中关于 ¯x 的梯度可以表示为 Jacobian 矩阵:

Jf=[yx1yx1]=[y1x1y1xnymx1ymxn]

设置 ¯v 是关于函数 l=g(¯y) 的梯度:

¯v=[ly1lym]T

Jacobian-vector 积就是函数 l 中关于 x_1 的梯度:

JT¯v=[y1x1y1xnymx1ymxn][ly1lym]=[y1x1ymx1]

即通过雅克比矩阵转置与后续节点梯度值的乘积,可以得到当前节点的梯度值。

优缺点

前向模式在计算之中,计算图各个节点的数值和该节点的导数可同步求出,但是代价就是对于多个输入需要多次计算才行。

反向模式的优点:

  • 通过一次反向传输,就计算出所有偏导数,中间的偏导数计算只需计算一次;

  • 减少了重复计算的工作量,在多参数的时候后向自动微分的时间复杂度更低。

反向模式的缺点:

  • 需要额外的数据结构记录正向过程的计算操作,用于反向使用;

  • 带来了大量内存占用,为了减少内存操作,需要 AI 框架进行各种优化,也带来了额外限制和副作用。

正反向模式的比较

前向自动微分(tangent mode AD 和后向自动微分(adjoint mode AD)分别计算了 Jacobian 矩阵的一列和一行。

前向模式和反向模式的不同之处在于矩阵相乘的起始之处不同。

当输出维度小于输入维度,反向模式的乘法次数要小于前向模式。因此,当输出的维度大于输入的时候,适宜使用前向模式微分;当输出维度远远小于输入的时候,适宜使用反向模式微分。

即,后向自动微分更加适合多参数的情况,多参数的时候后向自动微分的时间复杂度更低,只需要一遍 reverse mode 的计算过程,便可以求出输出对于各个输入的导数,从而轻松求取梯度用于后续优化更新。

因此,目前大部分 AI 框架都会优先采用反向模式,但是也有例如 MindSpore 等 AI 框架同事支持正反向的实现模式。

如果您想了解更多AI知识,与AI专业人士交流,请立即访问昇腾社区官方网站https://www.hiascend.com/或者深入研读《AI系统:原理与架构》一书,这里汇聚了海量的AI学习资源和实践课程,为您的AI技术成长提供强劲动力。不仅如此,您还有机会投身于全国昇腾AI创新大赛和昇腾AI开发者创享日等盛事,发现AI世界的无限奥秘~

相关文章
使用AI进行系统调优:给系统装上“智能大脑”
使用AI进行系统调优:给系统装上“智能大脑”
59 10
“AI医生”入驻运维现场:聊聊系统健康检查的新姿势
“AI医生”入驻运维现场:聊聊系统健康检查的新姿势
137 78
Dify-Plus:企业级AI管理核弹!开源方案吊打SaaS,额度+密钥+鉴权系统全面集成
Dify-Plus 是基于 Dify 二次开发的企业级增强版项目,新增用户额度、密钥管理、Web 登录鉴权等功能,优化权限管理,适合企业场景使用。
161 3
Dify-Plus:企业级AI管理核弹!开源方案吊打SaaS,额度+密钥+鉴权系统全面集成
Agent TARS:一键让AI托管电脑!字节开源PC端多模态AI助手,无缝集成浏览器与系统操作
Agent TARS 是一款开源的多模态AI助手,能够通过视觉解析网页并无缝集成命令行和文件系统,帮助用户高效完成复杂任务。
2195 3
Agent TARS:一键让AI托管电脑!字节开源PC端多模态AI助手,无缝集成浏览器与系统操作
对话即服务:Spring Boot整合MCP让你的CRUD系统秒变AI助手
本文介绍了如何通过Model Context Protocol (MCP) 协议将传统Spring Boot服务改造为支持AI交互的智能系统。MCP作为“万能适配器”,让AI以统一方式与多种服务和数据源交互,降低开发复杂度。文章以图书管理服务为例,详细说明了引入依赖、配置MCP服务器、改造服务方法(注解方式或函数Bean方式)及接口测试的全流程。最终实现用户通过自然语言查询数据库的功能,展示了MCP在简化AI集成、提升系统易用性方面的价值。未来,“对话即服务”有望成为主流开发范式。
570 3
AI技术如何重塑客服系统?解析合力亿捷AI智能客服系统实践案例
本文探讨了人工智能技术在客服系统中的应用,涵盖技术架构、关键技术和优化策略。通过感知层、认知层、决策层和执行层的协同工作,结合自然语言处理、知识库构建和多模态交互技术,合力亿捷客服系统实现了智能化服务。文章还提出了用户体验优化、服务质量提升和系统性能改进的方法,并展望了未来发展方向,强调其在客户服务领域的核心价值与潜力。
51 6
AI对话网站一键生成系统源码
可以添加进自己的工具箱,也可以嵌入自己博客的页面中,引流效果杠杠的,新拟态设计风格,有能力的大佬可以进行二开,仅提供学习,用户可输入网站名称、AI默认的开场白、AI头像昵称、AI网站中引流的你的网站等等内容,所有生成的网页全部保存到你的服务器上
71 27
AI对话网站一键生成系统源码
凌晨急诊室诞生的疫苗系统:一个宝妈的AI破局之路
本文分享了一位妈妈在急诊室经历后,将技术与母爱结合的心路历程。从凌晨抱着高烧儿子就医,同时处理工作告警的崩溃时刻,到意识到妈妈和程序员都是“运维工程师”,作者逐步构建了宝宝疫苗管理系统。文章介绍了系统从静态命令行工具升级为动态智能预警系统的全过程,包括环境搭建、核心代码解析及家庭协同功能实现,并总结了碎片时间开发法与防坑指南。最终,作者通过技术赋予母爱温度,为其他妈妈提供了实用资源包,展现了代码背后的人文关怀。
64 5
【最佳实践系列】AI程序员让我变成全栈:基于阿里云百炼DeepSeek的跨语言公告系统实战
本文介绍了如何在Java开发中通过跨语言编程,利用阿里云百炼服务平台的DeepSeek大模型生成公告内容,并将其嵌入前端页面。
算法系统协同优化,vivo与港中文推出BlueLM-V-3B,手机秒变多模态AI专家
BlueLM-V-3B是由vivo与香港中文大学共同研发的多模态大型语言模型,专为移动设备优化。它通过算法和系统协同优化,实现了高效部署和快速生成速度(24.4 token/s),并在OpenCompass基准测试中取得优异成绩(66.1分)。模型小巧,语言部分含27亿参数,视觉编码器含4000万参数,适合移动设备使用。尽管如此,低端设备可能仍面临资源压力,实际应用效果需进一步验证。论文链接:https://arxiv.org/abs/2411.10640。
43 9

热门文章

最新文章