So extrahieren Sie Informationen aus dem scikits.learn-Klassifizierer, um sie dann in C-Code zu verwenden

8

Ich habe eine Reihe von RBF SVMs mit scikits.learn in Python trainiert und dann die Ergebnisse gebeizt. Diese sind für Bildverarbeitungsaufgaben und eine Sache, die ich zum Testen machen möchte, ist jeder Klassifizierer auf jedem Pixel einiger Testbilder auszuführen. Das heißt, extrahiere den Merkmalsvektor aus einem Fenster, das auf dem Pixel (i, j) zentriert ist, führe jeden Klassifizierer auf diesem Merkmalsvektor aus und gehe dann zum nächsten Pixel und wiederhole ihn. Das ist viel zu langsam mit Python zu tun.

Klarstellung: Wenn ich sage "das ist viel zu langsam ...", dann meine ich, dass selbst der Code unter der Haube von Libsvm, den scikits.learn verwendet, zu langsam ist. Ich schreibe eigentlich eine manuelle Entscheidungsfunktion für die GPU, so dass die Klassifizierung bei jedem Pixel parallel erfolgt.

Ist es für mich möglich, die Klassifizierer mit Pickle zu laden und dann eine Art Attribut zu verwenden, das beschreibt, wie die Entscheidung aus dem Merkmalsvektor berechnet wird, und diese Information dann an meinen eigenen C-Code weiterzugeben? Im Fall von linearen SVMs könnte ich einfach den Gewichtsvektor und den Vorspannungsvektor extrahieren und diese als Eingaben zu einer C-Funktion hinzufügen. Aber was ist das Äquivalent für RBF-Klassifikatoren und wie bekomme ich diese Informationen vom scikits.learn-Objekt?

Hinzugefügt: Erste Versuche einer Lösung.

Es sieht so aus, als ob das Classifier-Objekt das Attribut support_vectors_ hat, das die Support-Vektoren als jede Zeile eines Arrays enthält. Es gibt auch das Attribut dual_coef_ , das ein 1 mal len(support_vectors_) Array von Koeffizienten ist. Aus den Standard-Tutorials zu nichtlinearen SVMs ergibt sich dann folgendes:

  • Berechnen Sie den Feature-Vektor v von Ihrem zu testenden Datenpunkt. Dies ist ein Vektor, der dieselbe Länge wie die Zeilen von support_vectors_ hat.
  • Berechne für jede Zeile i in support_vectors_ die quadrierte euklidische Distanz d[i] zwischen diesem Support-Vektor und v .
  • Berechne t[i] als gamma * exp{-d[i]} wobei gamma der RBF-Parameter ist.
  • Summiere dual_coef_[i] * t[i] über allen i . Fügen Sie dieser Summe den Wert des Attributs intercept_ des Klassifizierers scikits.learn hinzu.
  • Wenn die Summe positiv ist, klassifizieren Sie als 1. Andernfalls klassifizieren Sie als 0.

Hinzugefügt: Auf der nummerierten Seite 9 unter Dokumentationslink erwähnt, dass tatsächlich das Attribut intercept_ des Klassifikators den Verzerrungsterm enthält. Ich habe die obigen Schritte aktualisiert, um dies zu berücksichtigen.

    
ely 02.12.2011, 17:31
quelle

1 Antwort

9

Ja, Ihre Lösung sieht gut aus. Um den rohen Speicher eines numplien Arrays direkt an ein C-Programm zu übergeben, können Sie das verwenden ctypes Helfer aus numpy oder wickeln Sie Ihr C-Programm mit Cython und rufen Sie es direkt auf, indem Sie das numpy-Array übergeben (weitere Informationen finden Sie im Dokument unter Ссылка ) Details).

Ich bin jedoch nicht sicher, ob der Versuch, die Vorhersage auf einer GPU zu beschleunigen, der einfachste Ansatz ist: Kernel-Support-Vektormaschinen sind zur Vorhersagezeit langsam, da ihre Komplexität direkt von der Anzahl der Supportvektoren abhängt, die hoch sein können für stark nichtlineare (multimodale) Probleme.

Alternative Ansätze, die zur Vorhersagezeit schneller sind, umfassen neuronale Netze (wahrscheinlich komplizierter oder langsamer zu trainieren als SVMs, die nur zwei Hyperparameter C und Gamma haben) oder Transformieren Ihrer Daten mit einer nichtlinearen Transformation basierend auf Entfernungen zu Prototypen + Schwellenwertbildung + max. Pooling über Bildbereiche (nur zur Bildklassifizierung).

Schließlich können Sie auch versuchen, NuSVC-Modelle zu verwenden, deren Regularisierungsparameter nu sich direkt auf die Anzahl der Unterstützungsvektoren im angepassten Modell auswirkt: Weniger Unterstützungsvektoren bedeuten schnellere Vorhersagezeiten (überprüfen Sie die Genauigkeit, aber a Kompromiss zwischen Vorhersagegeschwindigkeit und Genauigkeit am Ende).

    
ogrisel 03.12.2011, 10:53
quelle