libsvm (C ++) gibt immer die gleiche Vorhersage aus

8

Ich habe einen OpenCV / C ++ - Wrapper für libsvm implementiert. Bei der Rastersuche nach SVM-Parametern (RBF-Kernel) gibt die Vorhersage immer das gleiche Label zurück. Ich habe künstliche Datensätze erstellt, die Daten sehr leicht trennen können (und versucht, Daten, die ich gerade trainiert habe, zu prognostizieren), aber immer noch das gleiche Etikett zurückgibt.

Ich habe die MATLAB-Implementierung von libsvm verwendet und eine hohe Genauigkeit für denselben Datensatz erreicht. Ich muss etwas falsch machen mit der Einrichtung des Problems, aber ich habe die README viele Male durchgelaufen und ich kann das Problem nicht ganz finden.

So stelle ich das libsvm Problem ein, wo Daten eine OpenCV Mat:

sind %Vor%

So stelle ich die Parameter ein, wobei svmParams meine eigene Struktur für C / Gamma und so ist:

%Vor%

Ich verwende die zur Verfügung gestellte param / problem checking Funktion und es werden keine Fehler zurückgegeben.

Ich trainiere dann als solche:

%Vor%

Und dann vorher sagen:

%Vor%

Wenn jemand darauf hinweisen könnte, wo ich falsch liege, würde ich es sehr schätzen. Danke!

BEARBEITEN:

Mit diesem Code habe ich den Inhalt des Problems gedruckt

%Vor%

Hier ist die Ausgabe:

%Vor%

Hier werden die Daten im Format [(index, value) ...] label gedruckt.

Der künstliche Datensatz, den ich erstellt habe, hat nur 3 Klassen, die alle leicht mit einer nichtlinearen Entscheidungsgrenze trennbar sind. Jede Zeile ist ein Merkmalsvektor (Beobachtung) mit 2 Merkmalen (xkoord, ykoord). Libsvm bittet darum, jeden Vektor mit einem -1-Label zu beenden, also tue ich das.

EDIT2:

Diese Änderung bezieht sich auf meine C- und Gamma-Werte, die für das Training verwendet werden, sowie auf die Datenskalierung. Ich habe normalerweise Daten zwischen 0 und 1 (wie hier vorgeschlagen: Ссылка ). Ich werde auch dieses gefälschte Dataset skalieren und es erneut versuchen, obwohl ich genau dieses Dataset mit der MATLAB-Implementierung von libsvm verwendet habe und diese unskalierten Daten mit 100% Genauigkeit trennen könnte.

Für C und Gamma verwende ich auch die in der Anleitung empfohlenen Werte. Ich erstelle zwei Vektoren und verwende eine doppelt verschachtelte Schleife, um alle Kombinationen auszuprobieren:

%Vor%

Und die Schleife sieht so aus:

%Vor%

EDIT3:

Da ich immer auf MATLAB referenziere, zeige ich die Genauigkeitsunterschiede. Hier ist eine Heatmap der Genauigkeit libsvm ergibt:

Und hier ist die Genauigkeitskarte, die MATLAB unter Verwendung der gleichen Parameter und des gleichen C / Gamma-Gitters liefert:

Hier ist der Code, der verwendet wird, um die C / Gamma-Listen zu erzeugen, und wie ich trainiere:

%Vor%

EDIT4

Als Plausibilitätsprüfung habe ich meinen gefälschten skalierten Datensatz so umformatiert, dass er dem von der libsvm Unix / Linux-Terminal-API verwendeten Datensatz entspricht. Ich trainierte und prognostizierte mit einem C / Gamma, das in der MATLAB-Genauigkeitskarte gefunden wurde. Die Vorhersagegenauigkeit betrug 100%. Damit mache ich in der C ++ Implementierung absolut etwas falsch.

EDIT5

Ich habe das vom Linux-Terminal trainierte Modell in meine C ++ Wrapper-Klasse geladen. Ich habe dann versucht, den gleichen genauen Datensatz für das Training vorherzusagen. Die Genauigkeit in C ++ war immer noch schrecklich! Ich bin jedoch sehr nahe daran, die Ursache des Problems einzugrenzen. Wenn sich MATLAB / Linux auf eine Genauigkeit von 100% einigen und das von ihm erzeugte Modell bereits eine 100% ige Genauigkeit auf dem gleichen Datensatz erzielt hat, an dem trainiert wurde, zeigt meine C ++ Wrapper-Klasse mit dem verifizierten Modell eine schlechte Leistung. .. Es gibt drei mögliche Situationen:

  1. Die Methode, mit der ich cv :: Mats in den svm_node * umwandeln kann, der für die Vorhersage benötigt wird, hat ein Problem.
  2. Die Methode zur Vorhersage von Labels enthält ein Problem.
  3. BEIDE 2 und 3!

Der Code, um jetzt wirklich zu inspizieren, ist, wie ich den svm_node erstelle. Hier ist es wieder:

%Vor%

Und Vorhersage:

%Vor%

EDIT6:

Für diejenigen von Ihnen, die sich zu Hause einschalten, trainierte ich ein Modell (mit optimalem C / Gamma in MATLAB) in C ++, speicherte es in Datei und versuchte dann, die Trainingsdaten über das Linux-Terminal vorherzusagen. Es erzielte 100%. Etwas stimmt nicht mit meiner Vorhersage. o_0

EDIT7:

Ich habe das Problem endlich gefunden. Ich hatte enorme Fehlerbehebungshilfe, um es zu finden. Ich habe den Inhalt des 2D-Arrays svm_node ** für die Vorhersage gedruckt. Es war eine Teilmenge der createProblem () -Methode. Es gab ein Stück davon, das ich nicht kopieren und in die neue Funktion einfügen konnte. Es war der Index eines bestimmten Merkmals; Es wurde nie geschrieben. Es hätte eine weitere Zeile geben sollen:

%Vor%

Und die Vorhersage funktioniert jetzt gut.

    
trianta2 15.09.2013, 19:37
quelle

1 Antwort

3

Es wäre nützlich, Ihren Gamma-Wert zu sehen, da Ihre Daten nicht normalisiert sind, was einen großen Unterschied machen würde.

Das Gamma in libsvm ist umgekehrt zum Hypersphärenradius. Wenn diese Sphären also zu klein in Bezug auf den Eingabebereich sind, wird immer alles aktiviert und dann würde das Modell immer den gleichen Wert ausgeben.

Die beiden Empfehlungen lauten also: 1) Skalieren Sie Ihre Eingabewerte auf den Bereich [-1,1]. 2) Spielen Sie mit den Gammawerten.

    
Pedrom 16.09.2013, 14:03
quelle

Tags und Links