2016-05-09 12 views
1

Im Moment versuche ich verschiedene SVMs für die Erkennung verschiedener Emotionen zu trainieren. Um zum Beispiel die Emotion glücklich zu erkennen, trainiere ich eine SVM mit Bildern glücklicher Menschen als Positive und Bilder, in denen Menschen andere Emotionen wie Wut, Angst, Ekel, ... als Negative ausdrücken. Die Bilder werden in einer Datenbank gespeichert, die ich in einen Trainingsabschnitt und einen Testabschnitt unterteilt habe.OpenCV 3.1.0: Gespeicherte SVMs speichern und laden

Wenn ich die SVMs trainiert habe, benutze ich sie sofort, um die Genauigkeit der Testbilder der Datenbank zu testen, und das funktioniert gut. Aber ich spare auch die trainierten SVMs, weil ich sie gerne in einem anderen Programm verwenden würde und sie nicht jedes Mal neu trainieren möchte, wenn ich das andere Programm starte.

Also habe ich die SVMs in das andere Programm geladen, aber die Ergebnisse waren sehr schlecht. Die Genauigkeit lag nahe null Prozent. Also habe ich versucht, die SVMs im Trainingsprogramm zu speichern und sofort zu laden, aber auch hier lag die Genauigkeit bei null Prozent.

Nach einer Weile habe ich herausgefunden, dass, wenn ich die SVMs geladen habe und ich den SVM-Typ, Kernel-Typ und Supportvektoren drucke, dass sie die gleichen wie in der SVM .xml-Datei sind. Ich denke also, dass das Problem darin besteht, dass die Vorhersage nicht richtig ausgeführt wird. Ich weiß auch nicht, ob ich meine SVMs speichere und sie in der richtigen Weise lade.

Ich habe im Moment versucht, nach einer Lösung zu suchen, aber ohne Erfolg. Einige der Links, die ich habe versucht, sind:

Train SVM and save it with OpenCV 3.0

How to load previously stored svm classifier?

Load Trained SVM – Emgu CV

opencv 3 (C++) auto trained SVM loading issue

Der Code, den ich die SVM zu trainieren und sie testen sofort ohne Belastung sie sind wieder:

trainData = ml::TrainData::create(training_mat, ROW_SAMPLE, label_mat); 
svm = SVM::create(); 
svm->setType(SVM::C_SVC); 
svm->setKernel(SVM::RBF); 
svm->trainAuto(trainData); 
svm->save(svmSaveNames[i]); 

// Test SVMs 
data_file.open(filenameLabelsTestingImages[i]); 
data_file << "Number\n"; 
startTest = stopTest; 
stopTest = startTest + emotionCountersTesting[i]; 
int numberRightClassified = 0; 
int numberClassified = 0; 

for (int j = 0; j < numberOfTestImg; j++) 
{ 
    cv::Mat testing_one_image_mat(1, numberOfFeatures, CV_32F); 
    for (int k = 0; k < numberOfFeatures; k++) 
    { 
     testing_one_image_mat.at<float>(0, k) = testing_mat.at<float>(j, k); 
    } 

    int value_svm = svmNew->predict(testing_one_image_mat); 

    if (value_svm == 1) 
    { 
     if (j >= startTest && j < stopTest) 
     { 
      numberRightClassified++; 
     } 
     numberClassified++; 
    } 
    data_file << value_svm << endl; 
} 
data_file.close(); 
012 svmSaveNames enthält Strings mit Namen zum Speichern der verschiedenen SVMs wie svm_anger.xml

So funktioniert dies gut, bis ich den Code ändern für die Vorhersage zunächst die SVM zu speichern und sie dann wieder laden, wie

trainData = ml::TrainData::create(training_mat, ROW_SAMPLE, label_mat); 
svm = SVM::create(); 
svm->setType(SVM::C_SVC); 
svm->setKernel(SVM::RBF); 
svm->trainAuto(trainData); 
svm->save(svmSaveNames[i]); 

Ptr<SVM> svmNew = SVM::create(); 
svmNew = SVM::load<SVM>(svmSaveNames[i]); 
//cout << "The type is " << svmNew->getType() << endl; 
//cout << "The kernel type is " << svmNew->getKernelType() << endl; 
//cout << "The support vectors are " << svmNew->getSupportVectors() << endl; 

// Test SVMs 
data_file.open(filenameLabelsTestingImages[i]); 
data_file << "Number\n"; 
startTest = stopTest; 
stopTest = startTest + emotionCountersTesting[i]; 
int numberRightClassified = 0; 
int numberClassified = 0; 

for (int j = 0; j < numberOfTestImg; j++) 
{ 
    cv::Mat testing_one_image_mat(1, numberOfFeatures, CV_32F); 
    for (int k = 0; k < numberOfFeatures; k++) 
    { 
     testing_one_image_mat.at<float>(0, k) = testing_mat.at<float>(j, k); 
    } 

    //int value_svm = svm -> predict(testing_one_image_mat); 
    int value_svm = svmNew->predict(testing_one_image_mat); 

    if (value_svm == 1) 
    { 
     if (j >= startTest && j < stopTest) 
     { 
      numberRightClassified++; 
     } 
     numberClassified++; 
    } 
    data_file << value_svm << endl; 
} 
data_file.close(); 

Die Anordnung folgen, svm_contempt.xml, ...

Ich benutze die Variable data_file, um eine TXT-Datei für jede SVM zu erstellen, die getestet wird. Also trainiere und teste ich zuerst die SVM, um zum Beispiel den emotionalen Ärger zu erkennen und beim Testen dieser SVM benutze ich alle Testbilder. Daher wird die Vorhersage all dieser Bilder (1 = positiv/-1 = negativ) in eine Textdatei geschrieben.

Die Parameter startTest und stopTest werden verwendet, um zu überprüfen, ob die positiven Bilder, die Vorhersage den Wert 1 gibt, im Bereich der Bilder liegen, die als positiv erkannt werden müssen. In der Testkarte der Datenbank bestellte ich alle Bilder von dort Emotion so zuerst Wut dann Verachtung, ...

Die 2D-Matrix testing_mat enthält die Daten von allen Testbildern, die der SVM zur Vorhersage der Emotion gegeben wird .

Also mein Problem ist, dass, nachdem ich die SVMs geladen habe sie mir nicht die richtige Vorhersage geben.

Antwort

0

Nachdem ich eine Weile gesucht habe, habe ich herausgefunden, dass es kein Problem gibt, wenn ich einen linearen Kernel verwende.So kann ich die SVM speichern und laden und die Vorhersage ist korrekt. Also habe ich nach einem Grund gesucht, warum es für den linearen Kernel funktioniert und nicht für die anderen Kernel.

Die Antwort ist, dass es einen Fehler in OpenCV 3.1 nach Ausgabe #5054 auf Github gibt. Ich habe versucht, die vorgeschlagene Lösung, aber es hat immer noch nicht funktioniert. Schließlich habe ich OpenCV 2.4 heruntergeladen und jetzt funktioniert alles gut.

+0

können Sie mir erklären, wie Sie den SVM-Klassifikator xml generieren. –

+0

Für eine gute Erklärung können Sie [mit OpenCV und SVM mit Bildern] (http://stackoverflow.com/questions/14694810/using-opencv-and-svm-with-images) überprüfen. – Plzzz

Verwandte Themen