haskell automatic-differentiation hmatrix

haskell - ¿Cómo obtener más rendimiento de la diferenciación automática?



automatic-differentiation hmatrix (1)

Me está costando mucho optimizar un programa que se basa en la función conjugateGradientDescent los ad para la mayor parte de su trabajo.

Básicamente, mi código es una traducción de un código de documentos antiguos que está escrito en Matlab y C. No lo he medido, pero ese código se ejecuta en varias iteraciones por segundo. El mío está en el orden de minutos por iteración ...

El código está disponible en este repositorios:

El código en cuestión se puede ejecutar siguiendo estos comandos:

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

Al utilizar las instalaciones de perfilado de GHC, he confirmado que el descenso es, de hecho, la parte que más tiempo toma:

(versión interactiva aquí: https://dl.dropboxusercontent.com/u/2359191/learngabors.svg )

-s me está diciendo que la productividad es bastante baja:

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

De lo que he reunido hay dos cosas que pueden conducir a un mayor rendimiento:

  • Unboxing: actualmente uso una implementación de matriz personalizada (en src/Data/SimpleMat.hs ). Esta era la única forma en que podía hacer que el ad funcionara con matrices (ver: ¿Cómo hacer la diferenciación automática en hmatrix? ). Mi conjetura es que al usar un tipo de matriz como newtype Mat wha = Mat (Unboxed.Vector a) lograría un mejor rendimiento debido a la unboxing y la fusión. Encontré un código que tiene instancias de ad para vectores sin caja, pero hasta ahora no he podido usarlos con el conjugateGradientFunction .

  • Derivadas de matriz: en un correo electrónico que no puedo encontrar en este momento, Edward menciona que sería mejor usar las instancias de Forward para los tipos de matriz en lugar de tener matrices llenas de instancias de Forward . Tengo una pequeña idea de cómo lograrlo, pero aún tengo que descubrir cómo lo implementaría en términos de clases de tipos de ad .

Esta es probablemente una pregunta que es demasiado amplia para ser contestada en SO, así que si está dispuesto a ayudarme aquí, no dude en contactarme en Github.


Se está ejecutando en el peor de los casos de la biblioteca de ad actual aquí.

FWIW: no podrá utilizar los tipos / clases de ad existentes con "matriz / vector de anuncios". Sería un esfuerzo de ingeniería bastante grande, consulte https://github.com/ekmett/ad/issues/2

En cuanto a por qué no puedes unboxear: conjugateGradient requiere la habilidad de usar el modo Kahn o dos niveles del modo de avance en tus funciones. Lo anterior le impide trabajar con vectores sin caja, ya que los tipos de datos llevan árboles de sintaxis y no pueden ser sin caja. Por diversas razones técnicas, no he descubierto cómo hacer que funcione con una "cinta" de tamaño fijo como el modo Reverse estándar.

Creo que la respuesta "correcta" aquí es que nos sentemos y averigüemos cómo hacer que la matriz / vector AD sea correcta e integrada en el paquete, pero confieso que en este momento estoy demasiado limitado para prestarle atención. merece

Si tienes la oportunidad de pasar por # haskell-lens en irc.freenode.net, me encantaría hablar sobre los diseños en este espacio y ofrecerte consejos. Alex Lang también ha estado trabajando mucho en ad y, a menudo, está presente allí y puede tener ideas.