2015-06-17 26 views
16

Mam trudności z optymalizacją programu, który polega na funkcji ad s conjugateGradientDescent dla większości jego pracy.Jak zwiększyć wydajność automatycznego różnicowania?

Zasadniczo mój kod jest tłumaczeniem old papers code, który jest napisany w Matlab i C. Nie zmierzyłem go, ale ten kod działa w kilku powtórzeniach na sekundę. Kopalnia jest w porządku minut na iteracji ...

Kod jest dostępna w tym repozytoriów:

Kod w pytaniu może być uruchamiany przez następujące te polecenia:

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

Korzystanie z GHC y profilowania urządzeń I potwierdziły, że zejście jest w rzeczywistości część, która trwa przez większość czasu:

Flamegraph of one iteration

(wersja interaktywna tutaj: https://dl.dropboxusercontent.com/u/2359191/learngabors.svg)

-s mówi mi, że wydajność jest dość niska:

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

Z tego co ja zebrane są dwie rzeczy, które mogłyby prowadzić do wyższej wydajności:

  • Unboxing: Obecnie używam niestandardowej implementacji macierzy (w src/Data/SimpleMat.hs). Był to jedyny sposób, w jaki mogłem uzyskać ad do pracy z macierzami (patrz: How to do automatic differentiation on hmatrix?). Domyślam się, że użycie matrycy typu, takiej jak newtype Mat w h a = Mat (Unboxed.Vector a), zapewni lepszą wydajność dzięki rozpakowaniu i fuzji. Znalazłem some code, który ma ad wystąpienia dla nieskrytych wektorów, ale do tej pory nie mogłem ich użyć z conjugateGradientFunction.

  • pochodne Matrix: W wiadomości e-mail po prostu nie mogę znaleźć w tej chwili Edward mówi, że byłoby lepiej użyć Forward instancje typów macierzy zamiast matryc wypełnionych Forward przypadkach. Mam lekki pomysł, jak to osiągnąć, ale jeszcze nie wiem, jak go wdrożyć pod względem klas typu s.

Jest to prawdopodobnie zbyt szerokie pytanie, na które można odpowiedzieć, więc jeśli chcesz mi pomóc, skontaktuj się ze mną na Github.

+0

Pytanie dla publiczności: czy w kabale biegnie coś w rodzaju runhaskell pod maską, czyli jest częścią problemu, że ten kod jest interpretowany zamiast kompilacji? –

+1

@ JohnF.Miller 'cabal run' uruchamia skompilowany kod. Uruchomienie tej samej rzeczy z GHCi (tj. Użycie ': main') jest jeszcze wolniejsze. – fho

Odpowiedz

3

W tym przypadku można znaleźć najgorszy możliwy scenariusz dla obecnej biblioteki ad.

FWIW - Nie będzie można używać istniejących klas/typów ad z "Matrix/Vector Ad".Byłoby to dość duży wysiłek inżynieria, zobacz https://github.com/ekmett/ad/issues/2

Jak, dlaczego nie można unbox: conjugateGradient wymaga zdolności do korzystania z trybu Kahn lub dwa poziomy trybu przodu na swoich funkcji. Ten pierwszy wyklucza możliwość pracy z nieskrytymi wektorami, ponieważ typy danych zawierają drzewa składniowe i nie można ich rozpakować. Z różnych przyczyn technicznych nie wiem, jak sprawić, by działał z "taśmą" o ustalonym rozmiarze, jak standardowy tryb Reverse.

Myślę, że "właściwą" odpowiedzią jest dla nas usiąść i dowiedzieć się, jak uzyskać macierz/wektor AD prawo i zintegrowany z pakietem, ale przyznaję, jestem czasowaty nieco zbyt cienko teraz, aby dać to uwaga, na jaką zasługuje.

Jeśli masz szansę na huśtanie się przez # soczewki na IRC.freenode.net, chętnie pomówię o projektach w tej przestrzeni i dam radę. Alex Lang pracował również nad ad i często jest tam obecny i może mieć pomysły.