自动微分有多快?

计算科学 自动分化
2021-12-22 15:40:40

我之前在 StackOverflow 上问过这个问题,但它显然更适合 SciComp:

虽然网上似乎有很多参考资料将自动微分方法和框架相互比较,但我似乎找不到任何关于我应该如何期望自动微分与手写导数评估进行比较的信息。

我的特殊情况:我正在做一个标量成本函数的梯度下降,有几千个变量和显着(> 99%)的稀疏性。我有一个 C++ 函数来计算这个成本。我还手动派生并实现了计算梯度和 Hessian 的函数。(成本函数及其导数没有以任何方式调整,它们只是一个简单的实现。)典型的下降到最小值大约需要 10 秒。

我想更轻松地使用不同的成本函数,而使用 AD 似乎是一个很好的方法。我使用CppAD自动评估梯度和 Hessian;这些值与我手动衍生函数中的值完全相同。但是使用 AD,典型的梯度下降大约需要 5 分钟。

我对 AD 的速度有多慢感到惊讶,但后来意识到我真的不知道它应该有多快。我不是在寻找“如何加快计算速度?”,而是“我应该期待什么?”

与手写导数相比,自动微分应该慢多少?一阶和二阶导数怎么样?

1个回答

所以你说你有几千个变量。AD 通常比手动编码的导数要慢,如果您使用正向 AD,那么您基本上需要为每个设计变量评估一次成本函数,并且您有数千个。通常在这些情况下,人们使用 AD 的反向模式,它的缩放与设计变量的数量无关,而是随着目标或成本函数的数量而缩放。AD的反向模式对应于解决伴随问题。AD 的好处是比较容易实现,因为在大多数情况下,您的手动编码导数应该比 AD 运行得更快。如果您想要二阶导数,那么向前缩放的 AD 将随着设计变量数量的平方而缩放,这真的很棘手。