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.