目前,我正試圖訓練不同的SVM以識別不同的情緒。因此,例如,要認識到情緒快樂,我訓練帶有快樂人的圖像的支持向量機作爲積極和圖像,人們表達其他情緒,例如憤怒,恐懼,厭惡......作爲否定。這些圖像存儲在我已經在培訓部分和測試部分分區的數據庫中。OpenCV 3.1.0:保存並加載訓練過的SVM
當我訓練完SVM後,我馬上用它們來測試數據庫測試圖像的準確性,這很好。但我也保存訓練有素的SVM,因爲我想在另一個程序中使用它們,並且不希望每次啓動其他程序時都要重新訓練它們。
因此,我將SVM加載到其他程序中,但結果非常糟糕。準確度接近0%。所以我試圖在訓練計劃中加載SVM,並且在這裏準確度接近零。
搜索了一會兒後,我發現,如果我已經加載了支持向量機和我打印SVM類型,核型和supportvectors,他們是一樣的,在SVM .xml文件。所以我認爲問題在於預測不能以正確的方式執行。我也不知道我是否保存了我的SVM並以適當的方式加載它們。
目前我已嘗試尋找解決方案,但沒有任何成功。有的,我已經試過的鏈接是:
Train SVM and save it with OpenCV 3.0
How to load previously stored svm classifier?
opencv 3 (C++) auto trained SVM loading issue
,我用它來訓練支持向量機,並立即對其進行測試,而無需加載代碼他們再次是:
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();
所以直到我更改代碼先保存支持向量機,然後再加載它們的預測如下
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();
數組svmSaveNames包含名稱的字符串保存不同的支持向量機像svm_anger.xml這工作得很好, svm_contempt.xml,...
我使用變量data_file爲每個測試的SVM創建一個.txt文件。因此,我首先訓練和測試SVM,以識別情緒憤怒,並在測試此SVM時使用所有測試圖像。因此,所有這些圖像的預測(1 =正/ -1 =負)被寫入文本文件。
參數startTest和stopTest用於驗證預測值爲1的正圖像是否在需要識別爲正的圖像範圍內。在數據庫的測試地圖中,我通過情緒排序所有圖像,所以首先憤怒然後蔑視,...
2D矩陣testing_mat包含來自所有測試圖像的數據,該數據被提供給SVM以預測情緒。
所以我的問題是,我已經加載SVM後,他們不給我正確的預測。
你能解釋我如何生成svm分類器xml。 –
爲了一個很好的解釋,你可以檢查[使用OpenCV和SVM與圖像](http://stackoverflow.com/questions/14694810/using-opencv-and-svm-with-images)。 – Plzzz