2017-02-24 1 views
1

Mit Opencv 3.2.0 versuche ich den Trainings- und Testfehler für ein SVM-Modell zu berechnen, das mit einer Untermenge von erstellt wurde Features mit dem varIdx-Vektor in cv :: ml :: TrainData :: create(). Hier ist der relevante Abschnitt des C++ Codes.Opencv-Fehler bei Verwendung von cv :: ml :: StatModel :: calcError mit auf dem ausgewählten Feature-Subset trainierten Modellen

using namespace cv; 
using namespace cv::ml; 
using namespace std; 

// Code to read samples and responses from external data file not shown... 

// Copy vector to Mat 
Mat matSamples(samples.size(), samples.at(0).size(), CV_32F); 
for(int i = 0; i < matSamples.rows; i++) { 
    for(int j = 0; j < matSamples.cols; j++) { 
     matSamples.at<float>(i, j) = samples.at(i).at(j); 
    } 
} 

// Copy vector to Mat 
Mat matResponses(responses.size(), 1, CV_32SC1); 
for(int i = 0; i < matResponses.rows; i++) { 
     matResponses.at<int>(i) = responses.at(i); 
} 

// Create Mat to specify training variables (features) 
Mat matVarIdx(1, 7, CV_32SC1); 
matVarIdx = (Mat_<int>(1, 7) << 0, 15, 26, 27, 28, 29, 31); 
cout << "Using features specified by " << matVarIdx << endl; 

// Construct training data from samples read from file above 
Ptr<TrainData> td = TrainData::create(
        matSamples,     // Array of samples 
        ROW_SAMPLE,     // Data in rows 
        matResponses,    // Array of responses 
        matVarIdx,     // Use features specified 
        noArray(),     // Use all data points 
        noArray(),     // Do not use samples weights 
        noArray()     // Do not specify inp and out types 
        ); 

// Split training and test data 
double ratio = 0.90; // 90% of samples will be labled training data 
bool shuffle = true; // randomly shuffle test and training data 
td->setTrainTestSplitRatio(ratio, shuffle); 
int n_train_samples = td->getNTrainSamples(); 
int n_test_samples = td->getNTestSamples(); 

cout << "Found " << n_train_samples << " Train Samples, and " 
    << n_test_samples << " Test Samples." << endl; 

// Output number of features 
cout << "Total number of features " << td->getNAllVars() << " and " 
    << td->getNVars() << " features used." << endl; 

// Set up SVM's parameters 
Ptr<SVM> svm = SVM::create(); 
svm->setType(SVM::C_SVC); 
svm->setKernel(SVM::RBF); 
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 1000, FLT_EPSILON)); 

// Train the SVM with given parameters 
svm->train(td); 

// Calculate errors. 
Mat results; 
float train_performance = svm->StatModel::calcError(
             td, 
             false, // use train data 
             results); 

cout << "Incorrectly classified training samples: " << train_performance << "%" << endl; 

float test_performance = svm->StatModel::calcError(
             td, 
             true, // use test data 
             results); 

cout << "Incorrectly classified test samples: " << test_performance << "%" << endl; 

Hier ist die Ausgabe des Programms:

Using features specified by [0, 15, 26, 27, 28, 29, 31] 
Found 267 Train Samples, and 30 Test Samples. 
Total number of features 32 and 7 features used. 
OpenCV Error: Assertion failed (samples.cols == var_count && samples.type() == CV_32F) in predict, file /home/lindo/dev/opencv/opencv-3.2.0/modules/ml/src/svm.cpp, line 1930 
terminate called after throwing an instance of 'cv::Exception' 
what(): /home/lindo/dev/opencv/opencv-3.2.0/modules/ml/src/svm.cpp:1930: error: (-215) samples.cols == var_count && samples.type() == CV_32F in function predict 
Aborted 

Es ist wie die Vorhersagen sieht verwendet die Fehler zu berechnen ist fehlgeschlagen, da die Anzahl der Spalten Probe nicht gleich der Anzahl von Funktionen ist das, was Ich wollte mit varIdx die Trainingsdaten erstellen.

Dieser Code funktioniert, wenn ich die volle Anzahl von Features verwende, d. H. Setze varIdx = cv :: noArray() in cv: ml :: TrainData :: create().

Ich habe versucht, einen Vektor anstelle einer Matte für varIdx sowie eine CV_8UC1 Mat für varIdx zu verwenden, aber immer noch den gleichen Assertionsfehler zu bekommen.

Jede Hilfe sehr geschätzt!

Antwort

0

bei der Dokumentation der Suche here, wird erklärt, dass der varIdx Vektor zu identifizieren Merkmale von Interesse und arbeitet als eine Liste von-0 basierter Indizes verwendet wird, oder eine Maske der aktiven Variablen

Auf diese Weise können Sie prüfen, Erstellen Sie einen varIdx vector_of_features-sized und geben Sie entweder 0 oder 1 Werte für Variablen an, die berücksichtigt werden sollen oder nicht.

Ich denke, dass Ihr Fehler aufgetreten ist, weil varIdx nur 7 Werte statt 32 enthielt und dass zur Vorhersagezeit OpenCV nur 7 erwartete, aber 32 gegeben wurde. Dieser Fehler tritt nicht auf, wenn Sie keine Variablen von Interesse angeben weil der Algorithmus jede Variable mit gleichem Gewicht berücksichtigt.

Zögern Sie auch nicht, einen Code der Bibliothek zu sehen. Ihr Compiler gab Ihnen den Ort, an dem der Fehler aufgetreten ist, damit Sie verstehen können, warum Ihr Code fehlgeschlagen ist.

Verwandte Themen