2015-06-17 6 views
16

У меня есть трудная оптимизация программы, которая опирается на функцию ad s conjugateGradientDescent для большинства ее работ.Как получить больше производительности от автоматической дифференциации?

В основном мой код является переводом old papers code, который написан в Matlab и C. Я не измерял его, но этот код работает с несколькими итерациями в секунду. Шахта в порядке минут на каждую итерацию ...

код доступен в этом репозитории:

Код в вопросе может быть запущен следующий эти команды:

$ 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 

Из того, что я собрал, есть две вещи, которые могут привести к повышению производительности:

  • Unboxing: В настоящее время я использую реализацию пользовательской матрицы (в 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.

Это, вероятно, вопрос, который слишком велик, чтобы ответить на SO, так что если вы готовы помочь мне здесь, не стесняйтесь связаться со мной по Github.

+0

Вопрос для аудитории: работает ли cabal что-то вроде runhaskell под капотом, то есть является частью проблемы, которую этот код интерпретируется вместо компиляции? –

+1

@ JohnF.Miller 'cabal run' запускает скомпилированный код. Запуск того же самого из GHCi (т.е. использование ': main') еще медленнее. – fho

ответ

3

Вы используете в основном сценарий наихудшего сценария для текущей библиотеки ad.

FWIW- Вы не сможете использовать существующие классы/типы ad с «матричным/векторным объявлением».Было бы довольно большой инженерные усилия, см https://github.com/ekmett/ad/issues/2

А почему вы не можете распаковывать: conjugateGradient требует умения использовать Kahn режим или два уровня режима вперед на ваших функций. Первое исключает его из работы с нерасположенными векторами, поскольку типы данных несут деревья синтаксиса и не могут быть распакованы. По различным техническим причинам я не понял, как заставить его работать с лентой фиксированного размера, например, стандартным режимом Reverse.

Я думаю, что «правильный» ответ здесь для нас, чтобы сесть и выяснить, как получить матрицу/вектор AD справа и интегрироваться в пакет, но, признаюсь, я слишком тонко сейчас слишком тонко, чтобы дать это внимание, которого оно заслуживает.

Если у вас есть шанс перевернуть # haskell-lens на irc.freenode.net, я с удовольствием расскажу о проектах в этом пространстве и предлагаю совет. Алекс Ланг также много работал на ad и часто присутствует там и может иметь идеи.