Ho difficoltà a ottimizzare un programma che si basa sulla funzione conjugateGradientDescent
s conjugateGradientDescent
per la maggior parte del suo lavoro.Come ottenere più prestazioni dal differenziamento automatico?
Fondamentalmente il mio codice è una traduzione di un old papers code scritto in Matlab e C. Non l'ho misurato, ma quel codice è in esecuzione a più iterazioni al secondo. Il mio è nell'ordine dei minuti per l'iterazione ...
Il codice è disponibile in questo repository:
Il codice in questione può essere eseguito seguendo questi comandi:
$ cd aer-utils
$ cabal sandbox init
$ cabal sandbox add-source ../aer
$ cabal run learngabors
Utilizzo di GHC s profiling servizi mi hanno confermato che la discesa è infatti la parte che sta prendendo la maggior parte del tempo:
(versione interattiva qui: https://dl.dropboxusercontent.com/u/2359191/learngabors.svg)
-s
mi sta dicendo che la produttività è abbastanza basso:
Productivity 33.6% of total user, 33.6% of total elapsed
da quello che ho raccolto ci sono due cose che possono portare a prestazioni più elevate:
Unboxing: attualmente utilizzo un'implementazione matrice personalizzata (in
src/Data/SimpleMat.hs
). Questo era l'unico modo per far funzionaread
con le matrici (vedi: How to do automatic differentiation on hmatrix?). La mia ipotesi è che usando un tipo di matrice comenewtype Mat w h a = Mat (Unboxed.Vector a)
si otterrebbero prestazioni migliori a causa di unboxing e fusione. Ho trovato some code che ha istanzead
per vettori unboxed, ma fino ad ora non sono stato in grado di utilizzare questi con ilconjugateGradientFunction
.derivati Matrix: In un'email non riesco proprio a trovare al momento Edward afferma che sarebbe meglio usare
Forward
casi per i tipi di matrice invece di avere matrici pieni diForward
casi. Ho una vaga idea di come ottenerlo, ma devo ancora capire come implementarlo in termini di classi di tipoad
s.
Questa è probabilmente una domanda che è troppo ampia per essere risolta su SO, quindi se si è disposti a darmi una mano qui, non esitate a contattarmi su Github.
Domanda per il pubblico: la corsa di cabala usa qualcosa come runhaskell sotto il cofano, cioè fa parte del problema che questo codice viene interpretato invece di compilato? –
@ JohnF.Miller 'cabal run' esegue codice compilato. Eseguire la stessa cosa da GHCi (cioè usare ': main') è ancora più lento. – fho