Lösen von nichtlinearen Optimierungsproblemen auf der GPU


18

Ich versuche, einige nichtlineare Optimierungsprobleme mit der GPU (CUDA) zu lösen.

Die Zielfunktion ist eine glatte nichtlineare Funktion, und ihr Gradient ist relativ billig zu berechnen, so dass ich mich nicht mit der numerischen Approximation befassen muss.

Ich möchte dieses Problem hauptsächlich mit fp32 maths ops lösen (aus verschiedenen Gründen). Welche nichtlineare Optimierungsmethode ist also robuster gegen Aufrundungsfehler bei guter Leistung? (zB konjugierter Gradient / Quasi-Newton / Vertrauensbereich), hat jemand BFGS auf der GPU mit guten Ergebnissen ausprobiert?

Übrigens ist der Hessische bei Bedarf in meinem Fall relativ klein (normalerweise <64 x 64), aber ich muss Tausende dieser kleinen Optimierungsprobleme gleichzeitig lösen.


4
Angesichts der geringen Größe Ihrer Probleme denke ich nicht, dass die spezifische Wahl des Algorithmus (z. B. BFGS) Ihre größte Herausforderung sein wird. Stattdessen wird der Kommunikationsaufwand für GPU <-> CPU minimiert. Der wahrscheinlich beste Weg, dies zu tun, besteht darin, viele Instanzen Ihrer Probleme parallel auf der GPU zu lösen. Laden Sie sie alle auf einmal, lösen Sie sie alle auf einmal, laden Sie die Ergebnisse auf einmal herunter. Ich habe keine spezifischen Ratschläge zum Algorithmus, aber ich werde sagen, dass GPUs mit Schleifen besser sind als mit Zweigen.
Michael Grant

1
@Michael C. Grant: Nun, der Kommunikationsaufwand kann in meinem Fall einfach durch Berechnungen ausgeblendet werden, daher ist dies kein Engpass. Ich bin sehr geneigt, BFGS mit begrenztem Speicher oder Standard-BFGS hier zu verwenden, bin mir jedoch nicht sicher, ob dies der Fall ist Besserer Ansatz.
user0002128

Einige Leute haben LBFGS mit CUDA implementiert .
BenC

Antworten:


8

Ich habe eine ganze Reihe nichtlinearer Löser auf der GPU implementiert, einschließlich LBFGS, Barzilai Borwein-Gradientenabstieg und nichtlinearer konjugierter Gradient.

Dafür war der nichtlineare konjugierte Gradient von Dai & Yuan der effizienteste. Im Allgemeinen kann eine andere Version des nichtlinearen konjugierten Gradienten effizienter sein (wie z. B. CG-DESCENT), aber auch schwieriger zu implementieren sein.

LBFGS ist im Allgemeinen eine sehr solide Wahl, und es sei denn, Sie sind wirklich in Erinnerung geblieben, ist es wahrscheinlich der beste Ort, um anzufangen.

Sowohl der konjugierte Gradient als auch BFGS erfordern jedoch eine Zeilensuche, bei der fp32 zum Problem wird. Anstatt die Standard-Wolfe-Bedingungen für die Liniensuche zu verwenden, würde ich vorschlagen, die hier vorgeschlagene ungefähre Wolfe-Bedingung zu verwenden . Das Papier ist ein wenig umständlich, aber das Wichtigste ist Gleichung 4.1. Im Wesentlichen führen sie explizit die Genauigkeit ein, mit der Sie Ihre Funktion berechnen können.

Überlegungen zur GPU:

Sie haben viele kleine Probleme, was sich geringfügig von meinem Anwendungsfall eines großen Problems unterscheidet. Ziehen Sie in Betracht, 1 Problem pro GPU-Block (oder eher Warp) auszuführen, wenn Sie Funktions- und Verlaufsbewertungen parallelisieren können, um alle Threads in einem Block zu verwenden. Auf diese Weise ist es kein Problem, wenn unterschiedliche Probleme eine unterschiedliche Anzahl von Iterationen erfordern.

Wenn dies keine Option ist, würde ich mit dem LBFGS-Solver gehen. Wenn sich Ihre Funktion gut verhält, müssen Sie möglicherweise nicht nur eine Schrittgröße von 1 verwenden (um die Zeilensuche zu vermeiden) und alle Probleme nur für eine feste Anzahl von Iterationen ausführen.


0

Ich empfehle Ihnen, Levenberg Marquardt (eine Trust-Region-Variante) zu verwenden, da es in vielen praktischen Anwendungen verwendet wird und eine sehr gute Geschwindigkeit-gegen-Genauigkeit-Leistung aufweist. Außerdem gibt es für GPU einige Bibliotheken (zB cuLM https://github.com/zitmen/cuLM ), die Sie ausprobieren können. Wenn sie den Job nicht erledigen, stehen Ihnen unzählige Ressourcen zur Verfügung. Die Implementierung von LM ist überhaupt nicht schwierig. Sie sollten nur darauf achten, die GPU-Kommunikation zu minimieren. Um eine kurze Vorstellung zu bekommen:

http://on-demand.gputechconf.com/gtc/2012/presentations/S0231-Levenberg-Marquardt-Using-Block-Sparse-Matrices-on-CUDA.pdf


2
Levenberg-Marquart ist für nichtlineare kleinste Quadrate. Ich glaube nicht, dass er / sie etwas über die kleinsten Quadrate erwähnt hat.
Kurt

0

Möglicherweise kann ein simulierter Glühvorgang Abrundungsfehler besser behandeln (und ist leicht parallelisierbar).

Sie beginnen mit einem groben Raster des Suchbereichs und einem anfänglichen "Temperatur" -Parameter

Bei jedem Schritt berechnen Sie mögliche Lösungspunkte (man kann auch Nichtlösungspunkte akzeptieren, mit einiger Wahrscheinlichkeit umgekehrt analog zur Temperatur).

Behalten Sie dann nur die Lösungen in diesem Schritt bei und erhöhen Sie die Temperatur, um ein feinkörnigeres Gitter für die nächste Iteration zu erhalten

Tun Sie dies, bis die Temperatur <einer bestimmten Grenze / Genauigkeitsschwelle ist

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.