在深度学习与科学计算领域,自动微分(Automatic Differentiation)技术正逐渐取代传统的手动求导和数值微分方法。想象一下,当你需要计算一个包含数百个参数的复杂神经网络梯度时,手动推导几乎是不可能完成的任务。而数值微分虽然实现简单,却饱受精度问题和计算效率低下的困扰。这就是为什么现代框架如 TensorFlow 和 PyTorch 都将自动微分作为核心功能的原因。
本文将带你从零开始,用 C++ 实现一个基于前向模式自动微分的轻量级库。不同于简单的理论讲解,我们会深入代码层面,通过 Dual Number(对偶数)和运算符重载这两个关键技术,揭示自动微分如何优雅地解决导数计算问题。无论你是希望理解深度学习框架的底层原理,还是需要在嵌入式设备等场景中实现高效的微分计算,这篇文章都将为你提供清晰的实现路径。
1. 自动微分基础与 Dual Number 原理
1.1 为什么需要自动微分?
在机器学习中,我们经常需要计算损失函数对模型参数的导数。传统方法主要有三种:
- 符号微分:通过代数软件进行公式推导
- 优点:精确
- 缺点:表达式膨胀问题严重,无法处理控制流
- 自动微分:本文重点介绍的方法
- 优点:精确且高效,计算复杂度与原始函数相当
- 数值微分:使用有限差分近似
- 优点:实现简单
- 缺点:精度受步长影响,计算复杂度高
def numerical_diff(f, x, h=1e-5):
return (f(x+h) - f(x-h)) / (2*h)
1.2 Dual Number 的数学基础
Dual Number 是对复数概念的扩展,形式为 a + bε,其中ε²=0 但ε≠0。它的神奇之处在于:
- 函数计算:f(a + bε) = f(a) + bf'(a)ε
- 导数获取:ε项的系数即为导数
常见运算的 Dual Number 规则:
| 运算 | 普通结果 | 导数结果 |
|---|---|---|
| 加法 | (a+c) + (b+d)ε | f'+g' |
| 乘法 | ac + (ad+bc)ε | f'g + fg' |
| 除法 | a/c + (b/a - ad/c²)ε | (f'g - fg')/g² |
// Dual Number 结构体基础定义
struct Dual {
double real; // 函数值
double eps; // 导数值
Dual(double r, double e = 0) : (r), (e) {}
};

