16

我很难优化一个依赖adsconjugateGradientDescent函数完成大部分工作的程序。

基本上我的代码是用 Matlab 和 C 编写的旧论文代码的翻译。我没有测量它,但该代码每秒运行几次迭代。我的每次迭代大约需要几分钟...

该代码在此存储库中可用:

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

$ 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

从我收集的信息来看,有两件事可能会导致更高的性能:

  • 拆箱:目前我使用自定义矩阵实现(在 中src/Data/SimpleMat.hs)。这是我可以ad使用矩阵的唯一方法(请参阅:如何在 hmatrix 上进行自动微分?)。newtype Mat w h a = Mat (Unboxed.Vector a)我的猜测是,由于拆箱和融合,使用类似矩阵类型会获得更好的性能。我发现了一些包含未装箱向量实例的代码ad但到目前为止,我还无法将这些与conjugateGradientFunction.

  • 矩阵导数:在一封电子邮件中,我现在找不到 Edward 提到使用Forward矩阵类型的实例而不是用Forward实例填充矩阵会更好。我对如何实现这一点有一个模糊的想法,但还没有弄清楚我将如何根据ads 类型类来实现它。

这可能是一个在 SO 上无法回答的问题,所以如果您愿意在这里帮助我,请随时在 Github 上与我联系。

4

1 回答 1

3

ad您在这里遇到了当前库的最坏情况。

FWIW-您将无法将现有的ad类/类型与“矩阵/矢量广告”一起使用。这将是一项相当大的工程工作,请参阅https://github.com/ekmett/ad/issues/2

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

我认为这里的“正确”答案是让我们坐下来弄清楚如何正确获取矩阵/向量 AD 并将其集成到包中,但我承认我现在的时间片太薄了,无法引起人们的注意应得的。

如果您有机会在 irc.freenode.net 上浏览#haskell-lens,我很乐意谈论这个领域的设计并提供建议。亚历克斯朗也做ad了很多工作,经常在那里,可能有想法。

于 2015-09-16T18:37:04.020 回答