目前我正在尝试训练不同的支持向量机来识别不同的情绪。因此,例如,为了识别快乐的情绪,我训练了一个支持向量机,其中快乐的人的图像是积极的,人们表达其他情绪(如愤怒、恐惧、厌恶等)的图像是消极的。这些图像存储在一个数据库中,我已将其划分为训练部分和测试部分。
当我训练了 SVM 后,我立即使用它们来测试数据库测试图像的准确性,并且效果很好。但我也保存了训练过的 SVM,因为我想在另一个程序中使用它们,并且不想每次启动另一个程序时都重新训练它们。
因此,我在另一个程序中加载了 SVM,但结果非常糟糕。准确度接近于百分之零。因此,我尝试在训练程序中保存并立即加载 SVM,但这里的准确率现在接近于 0%。
搜索了一段时间后,我发现如果我加载了 SVM 并打印了 SVM 类型、内核类型和支持向量,它们与 SVM .xml 文件中的相同。所以我认为问题在于预测没有以正确的方式执行。我也不知道我是否保存了我的 SVM 并以适当的方式加载它们。
目前我已经尝试寻找解决方案,但没有任何成功。我尝试过的一些链接是:
我用来训练 SVM 并立即测试它们而不再次加载它们的代码是:
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();
所以这工作正常,直到我更改代码以首先保存 SVM,然后再次加载它们以进行预测,如下所示
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,例如 svm_anger.xml、svm_contempt.xml、...
我使用变量 data_file 为每个测试的 SVM 创建一个 .txt 文件。因此,首先我训练和测试 SVM 以识别例如情绪愤怒,并在测试这个 SVM 时使用所有测试图像。因此,所有这些图像的预测(1 = 正/-1 = 负)都被写入文本文件。
参数 startTest 和 stopTest 用于验证正图像(预测值为 1)是否在需要被识别为正图像的范围内。在数据库的测试图中,我按情感排序了所有图像,所以先是愤怒然后是鄙视,...
2D 矩阵 testing_mat 包含来自所有测试图像的数据,这些数据被提供给 SVM 以预测情绪。
所以我的问题是,在我加载了 SVM 之后,它们并没有给我正确的预测。