如何通过自动差异化获得更多性能?

时间:2015-06-17 10:14:30

标签: haskell automatic-differentiation hmatrix

我很难在大多数工作中优化依赖ad conjugateGradientDescent功能的程序。

基本上我的代码是用Matlab和C编写的old papers code的翻译。我没有测量它,但是代码每秒运行几次。我的每次迭代大约为几分钟......

此代码库中提供了代码:

可以通过以下命令运行相关代码:

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

使用GHC分析设施我已经确认下降实际上是大部分时间内的部分:

Flamegraph of one iteration

(此处为互动版: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使用矩阵的唯一方法(参见:How to do automatic differentiation on hmatrix?)。我的猜测是,通过使用像newtype Mat w h a = Mat (Unboxed.Vector a)这样的矩阵类型,由于拆箱和融合,可以获得更好的性能。我发现some code对于未装箱的向量有ad个实例,但到目前为止,我还没有能够将这些用于conjugateGradientFunction

  • 矩阵衍生产品:在目前我无法发现的电子邮件中,爱德华提到最好将Forward个实例用于矩阵类型而不是矩阵填充Forward个实例。我对如何实现这一点有一个微弱的想法,但还没有弄清楚我是如何用ad类型类来实现的。

这可能是一个太宽泛而无法回答的问题,所以如果你愿意帮助我,请随时与我联系Github。

1 个答案:

答案 0 :(得分:3)

您现在遇到的是当前ad库的最坏情况。

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

至于为什么你不能取消装箱:conjugateGradient要求能够在你的功能上使用Kahn模式或两级前进模式。前者阻止它使用未装箱的向量,因为数据类型带有语法树,并且无法取消装箱。由于各种技术原因,我还没有想出如何使用固定尺寸的胶带来解决问题。与标准Reverse模式一样。

我认为"对"回答这里是让我们坐下来弄清楚如何将矩阵/向量AD正确并集成到包中,但我承认我现在有点太过分了,以给予它应有的关注。

如果你有机会在irc.freenode.net上通过#haskell-lens摇摆,我很高兴谈论这个领域的设计并提供建议。 Alex Lang也经常在ad工作,经常出现在那里,可能有想法。