自动微分(AutoDiff)的原理

简介: 求偏微分,可以选择的方法有:手工微分(manual differentiation)、符号微分(symbolic differentiation)、数值微分(numerical differentiation)、前向自动微分(forward-mode autodiff)和反向自动微分(reverse-mode autodiff)。

自动微分(AutoDiff)的原理

1/ 各种自动微分的优缺点1

机器学习的一个重要的任务,就是对参数求导得到损失函数对于每个参数的偏导数,然后进行梯度下降。

而求偏微分,可以选择的方法有:手工微分(manual differentiation)、符号微分(symbolic differentiation)、数值微分(numerical differentiation)、前向自动微分(forward-mode autodiff)和反向自动微分(reverse-mode autodiff)。

而在 Julia 的 Flux 包里和 Tensorflow 一样,就是使用的反向自动微分。

手工微分:手工微分对于复杂的函数,会变得非常繁琐,容易出错

符号微分:利用计算图来处理。但是对于复杂的函数,会出现计算图十分巨大的,降低性能,而一个最大的缺点就是,符号微分无法处理任意编码的函数。

数值微分:数值微分根据公式:

$$ \begin{aligned} h^{\prime}(x)&=\lim_{x\rightarrow x_0}\frac{h(x)-h(x_0)}{x-x_0}\\ &=\lim_{\epsilon\rightarrow 0}\frac{h(x_0+\epsilon)-h(x_0)}{\epsilon} \end{aligned} $$

要计算函数 $f(x_1,x_2,\cdots,x_n)$ 在某个点关于 $x_i$ 的偏导数,只需要计算当 $\epsilon$ 很小的时候 $f(x_1,x_2,\cdots,x_i-\epsilon,\cdots,x_n)$ 处以 $\epsilon$ 的商。

不过数值微分的缺点就是,结果并不准确,是一种近似,并且会重复调用函数 $f(x)$ 很多次,在机器学习参数很多的情况下,会变得很低效。但是由于数值微分很容易执行,它可以作为一个检查其他算法是否正确的有用工具。

前向自动微分:虽然既不是符号微分也不是数值微分,但是在某些方面,前向自动微分是符号微分和数值微分的结合。

前向自动微分依赖于 dual number,形式为 $a+b\epsilon$,其中 $a,b$ 是两个是两个实数,$\epsilon$ 是一个无穷小的数字。dual number 在存储的时候,用一对浮点数表示,例如 $42+24\epsilon$ 用 $(42,0,24.0)$ 表示。

对于 dual number 的基本运算如下:(注意 $\epsilon^2=0$)

$$ \begin{aligned} \lambda(a+b\epsilon)&=\lambda a+\lambda b\epsilon\\ (a+b\epsilon)+(c+d\epsilon)&=(a+c)+(b+d)\epsilon\\ (a+b\epsilon)\times(c+d\epsilon)&=ac+(ad+bd)\epsilon+(bd)\epsilon^2\\ &=ac+(ad+bc)\epsilon \end{aligned} $$

更为重要的是 $h(a+b\epsilon)=h(a)+b\times h^{\prime}(a)\epsilon$,所以当我们计算 $h(a+\epsilon)$ 的时候,可以一次给出 $h(a)$ 和 $h^{\prime}(a)$.

假如函数 $f(x,y)=x^2y+y+2$,我们要计算关于 $x$ 的偏导数,需要做的就是计算 $f(3+\epsilon,4)$,结果为一个 dual number $42+24\epsilon$,那么就可以得到 $f(3,4)=42$ 并且偏导数 $\partial_xf(3,4)=24$

前向自动微分的缺点就是,穿过一次图,只能计算一个参数的偏导数,虽然结果精确,但是对于多个参数的时候,要穿过很多次图。

反向自动微分:正向穿过图来计算每个节点的值,然后第二次反向穿过图,计算所有的偏导数。

反向自动微分(Reverse-mode autodiff)依赖于链式法则:$\frac{\partial f}{\partial x}=\frac{\partial f}{\partial n_i}\times \frac{\partial n_i}{\partial x}$.

自动微分认为,任何数值计算的本质其实是一系列可微分算子的组合。那么,我们就可以假设我们求不出这个函数的导数,但是将该函数拆解成为其他子部分后,子部分可以通过常规的求导方式得到,最终将每个子部分进行组合,就得到了最终的结果。2

目录
相关文章
|
编解码 算法 数据处理
基于八叉树的空间划分及搜索操作
基于八叉树的空间划分及搜索操作
基于八叉树的空间划分及搜索操作
|
域名解析 Linux Shell
CentOS 7 执行 yum 命令失败问题的排查方法
本文主要为大家讲解CentOS 7系统中执行yum命令失败等常见问题的排查方法。
5546 0
CentOS 7 执行 yum 命令失败问题的排查方法
|
3月前
|
移动开发 NoSQL 前端开发
从零到一:游戏陪玩系统的技术架构与业务设计| 多端实战
本文分享基于ThinkPHP6+Uniapp重构的游戏陪玩系统实战经验,涵盖五角色权限设计、订单状态机、Redis抢锁、邀请裂变等核心实现,强调业务梳理重于技术选型,代码开源可二次开发。(239字)
457 2
|
11月前
|
机器学习/深度学习 存储 缓存
阿里云服务器企业级实例选购攻略:八代/九代/倚天实例性能、场景、选型参考
2025年阿里云活动中适合企业用户的云服务器实例规格主要为通用算力型u1、计算型c8i、计算型c9i、计算型c8y、通用型g8i、通用型g9i、通用型g8y、内存型r9i、内存型r8y等实例。本文为大家介绍这些实例规格的性能、场景以及选型参考。
|
8月前
|
Web App开发 资源调度 算法
Fresnel变换的详解
菲涅耳变换是描述光波近场衍射的核心工具,由法国物理学家菲涅耳提出,用于精确刻画光通过孔径后的传播行为。它在傍轴近似下将衍射积分转化为含二次相位因子的傅里叶形式,广泛应用于激光传输、全息成像与光学系统设计。该变换介于精确的瑞利-索末菲积分与远场的夫琅禾费衍射之间,体现了波动光学的基本特征。
1203 5
|
SQL 开发框架 前端开发
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
|
资源调度 数据可视化 JavaScript
一个高效的低代码表单,可视化设计,一键生成源码,享受更多摸鱼时间!
Variant Form 是一款基于 Vue 2 的低代码表单生成器,采用可视化拖拽设计界面,支持一键生成完整源码,大幅降低开发复杂度。它具备高度自定义配置能力,能够满足不同场景需求,并且完全开源免费。通过简单的拖拽操作,用户可以轻松创建表单,同时还能自定义 CSS 样式、校验逻辑及多语言支持等功能。安装便捷,兼容多种环境,极大提升开发效率。赶紧试试 Variant Form,享受高效开发的乐趣吧!
483 0
|
数据安全/隐私保护
ensp中基本acl 原理及配置命令(详解)
ensp中基本acl 原理及配置命令(详解)
1638 1
|
存储 缓存 Java
JVM的即时编译(JIT)优化原理:加速程序的执行
JVM的即时编译(JIT)优化原理:加速程序的执行