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:
v
von Ihrem zu testenden Datenpunkt. Dies ist ein Vektor, der dieselbe Länge wie die Zeilen von support_vectors_
hat. i
in support_vectors_
die quadrierte euklidische Distanz d[i]
zwischen diesem Support-Vektor und v
. t[i]
als gamma * exp{-d[i]}
wobei gamma
der RBF-Parameter ist. dual_coef_[i] * t[i]
über allen i
. Fügen Sie dieser Summe den Wert des Attributs intercept_
des Klassifizierers scikits.learn hinzu. 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.
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).
Für die erste Methode finden Sie eine gute Dokumentation zum Deep Learning-Lernprogramm
Lesen Sie die letzten Artikel von Adam Coates und lesen Sie diese Seite auf kmeans feature extraction
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).
Tags und Links python scikit-learn libsvm scikits svm