如何从自动微分中获得更多性能?

How to get more performance out of automatic differentiation?

我很难优化一个大部分工作都依赖 ads conjugateGradientDescent 函数的程序。

基本上我的代码是对用 Matlab 和 C 编写的 old papers code 的翻译。我没有对其进行测量,但该代码是 运行ning 每秒迭代几次。我的是每次迭代的分钟数......

此存储库中提供了代码:

有问题的代码可以通过以下命令 运行:

$ cd aer-utils
$ cabal sandbox init
$ cabal sandbox add-source ../aer
$ cabal run learngabors

使用 GHC 分析工具,我已经确认下降实际上是花费大部分时间的部分:

(互动版在这里:https://dl.dropboxusercontent.com/u/2359191/learngabors.svg

-s告诉我生产力很低:

Productivity  33.6% of total user, 33.6% of total elapsed

根据我收集到的信息,有两件事可能会带来更高的性能:

这个问题可能太宽泛,无法在 SO 上回答,所以如果您愿意帮助我,请随时通过 Github.

与我联系

你 运行 进入了当前 ad 库的最坏情况。

FWIW- 您将无法将现有的 ad classes/types 与 "matrix/vector ad" 一起使用。这将是一项相当大的工程工作,请参阅 https://github.com/ekmett/ad/issues/2

至于为什么不能拆箱:conjugateGradient 需要能够在您的函数上使用 Kahn 模式或两级转发模式。前者阻止它使用未装箱的向量,因为数据类型带有语法树,并且不能被拆箱。由于各种技术原因,我还没有弄清楚如何使它像标准 Reverse 模式一样使用固定大小的 'tape'。

我认为这里的 "right" 答案是让我们坐下来弄清楚如何正确获得 matrix/vector AD 并将其集成到包中,但我承认我也有点时间片现在就细细地给予它应有的关注。

如果你有机会在 irc.freenode.net 上通过#haskell-lens 摆动,我很乐意谈论这个 space 中的设计并提供建议。 Alex Lang 也一直致力于 ad,并且经常出现在那里并且可能有想法。