目前,我正试图训练不同的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