Ich muss eine Oberfläche optimieren, die durch ein 2D-Gitter von Punkten dargestellt wird, um normale Vektoren der Oberfläche zu erzeugen, die mit den vorgesehenen Zielnormalenvektoren ausgerichtet sind. Die Rastergröße liegt wahrscheinlich zwischen 201x201 und 1001x1001. Das bedeutet, dass die Anzahl der Variablen 40.000 bis 1.000.000 beträgt, da ich nur die Z-Koordinaten der Gitterpunkte modifiziere.
Ich benutze das Ceres-Framework, da es sich bei großflächigen nichtlinearen Optimierungsproblemen auszeichnen soll. Ich habe MATLABs fmincon bereits ausprobiert, aber es verbraucht unglaublich viel Speicher. Ich habe eine Zielfunktion geschrieben, die für kleine Netze funktioniert (erfolgreich bei 3x3 und 31x31). Wenn ich jedoch versuche, den Code mit einer großen Mesh-Größe (157 x 200) zu kompilieren, sehe ich den Fehler unten. Ich habe gelesen, dass dies eine Einschränkung von Eigen ist. Wenn ich Ceres jedoch sage, LAPACK anstelle von Eigen zu verwenden, bekomme ich den gleichen Fehler für große Matrizen. Ich habe diese Zeilen ausprobiert:
%Vor%Diese sagen dem Löser, LAPACK und DENSE_QR zu verwenden, da die Ausgabe mit einem 3x3-Mesh zeigt:
%Vor%Wenn ich jedoch große Parameter verwende, bekomme ich immer noch die Fehler für Eigen.
Wie auch immer, ich könnte wirklich etwas Hilfe dabei gebrauchen. Wie kann ich Ceres dazu bringen, eine große Anzahl von Variablen (& gt; 30.000) zu optimieren? Vielen Dank im Voraus
Link zu Ceres: Ссылка
Link zu Eigen: Ссылка
Fehler:
%Vor%Mein Code sieht so aus (abgekürzt, um irrelevantes Material herauszunehmen):
%Vor%Zwei Dinge
Wenn Sie Version 1.9 oder älter verwenden, benötigen Sie SuiteSpare / CXSparse. Wenn Sie den neuesten Release Candidate oder die git Version verwenden, sollten Sie in der Lage sein, mit Eigen die spärliche lineare Algebra auszuführen.
Sehen Sie sich den Beispielcode an, der mit ceres ausgeliefert wird, zum Beispiel denoising.cc, der ein ganzes Bild demoziert und eine ähnliche gitterähnliche Struktur hat.
Erstellen Sie im Allgemeinen einen einzelnen Restblock für jeden Knoten in Ihrem Problem.
Peter, Ja, technisch kann man die dynamische Autodiff-Kostenfunktion verwenden, aber es wird unglaublich langsam und es wird das ganze Problem als ein einziges Residuum für den Solver darstellen, also keine Sparsity und schlecht Rang mangelnde Jacobi.
Sie sollten darüber nachdenken, einen Rest pro Rasterpunkt hinzuzufügen, der nur von Nachbarknoten abhängig ist.
Wenn Sie weiterhin einen Kosten-Restblock verwenden, wird es immer noch Probleme geben.
Diese Antwort basiert vollständig auf meinen Erfahrungen mit C ++ und Eigen (ich kenne Ceres nicht):
Die Option. * Zeilen scheinen das Laufzeitverhalten zu steuern, aber die Fehlermeldung ist ein Kompilierzeitfehler.
Der relevanteste Teil des Fehlers, der für mich herausragt, ist:
/usr/include/eigen3/Eigen/src/Core/DenseStorage.h:79:5: Fehler: 'OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG' ist kein Mitglied von 'Eigen :: internal :: static_assertion' EIGEN_STATIC_ASSERT (Größe * Größe von (T) & lt; = 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
Eigen wird oft feste Matrizen auf dem Stack zuweisen und ich denke, das ist was hier passiert. Bei Matrizen, mit denen Sie arbeiten, müssen sie auf dem Heap zugewiesen werden. Um dies zu erzwingen, wählen Sie dynamisch große Matrizen aus. Nach dem Kompilieren sollten Sie es mit oder ohne Eigen ausführen können, indem Sie die gefundenen Optionen verwenden.
Die spezifische Lösung scheint DynamicAutoDiffCostFunction
anstelle von AutoDiffCostFunction
zu verwenden. Ein relevanter Ausschnitt der Dokumentation:
AutoDiffCostFunction
erfordert, dass die Anzahl der Parameterblöcke und ihre Größen zur Kompilierungszeit bekannt sind. Es hat auch eine Obergrenze von 10 Parameterblöcken.
Tags und Links optimization c++ eigen lapack large-scale