对OpenCV SVM的推荐参数有什么想法吗?我在OpenCV样本目录中玩letter_recog.cpp,然而,SVM的准确性很差!在一次测试中,我只得到了62%的准确率:
$ ./letter_recog_modified -data /home/cobalt/opencv/samples/data/letter-recognition.data -save svm_letter_recog.xml -svm
The database /home/cobalt/opencv/samples/data/letter-recognition.data is loaded.
Training the classifier ...
data.size() = [16 x 20000]
responses.size() = [1 x 20000]
Recognition rate: train = 64.3%, test = 62.2%
默认参数为:
model = SVM::create();
model->setType(SVM::C_SVC);
model->setKernel(SVM::LINEAR);
model->setC(1);
model->train(tdata);
将其设置为trainAuto()没有帮助;它给了我一个奇怪的0%的测试准确率:
model = SVM::create();
model->setType(SVM::C_SVC);
model->setKernel(SVM::LINEAR);
model->trainAuto(tdata);
结果:
Recognition rate: train = 0.0%, test = 0.0%
使用杨杰的答案更新:
$ ./letter_recog_modified -data /home/cobalt/opencv/samples/data/letter-recognition.data -save svm_letter_recog.xml -svm
The database /home/cobalt/opencv/samples/data/letter-recognition.data is loaded.
Training the classifier ...
data.size() = [16 x 20000]
responses.size() = [1 x 20000]
Recognition rate: train = 58.8%, test = 57.5%
结果不再是0%,但准确度比之前的62%更差。
将RBF内核与trainAuto()一起使用是最糟糕的吗?
$ ./letter_recog_modified_rbf -data /home/cobalt/opencv/samples/data/letter-recognition.data -save svm_letter_recog.xml -svm
The database /home/cobalt/opencv/samples/data/letter-recognition.data is loaded.
Training the classifier ...
data.size() = [16 x 20000]
responses.size() = [1 x 20000]
Recognition rate: train = 18.5%, test = 11.6%
参数:
model = SVM::create();
model->setType(SVM::C_SVC);
model->setKernel(SVM::RBF);
model->trainAuto(tdata);
我建议尝试RBF内核而不是线性。在很多情况下,这是最好的选择。。。
我调试了示例代码并找到了原因。
responses
是字母的ASCII码的Mat
。
然而,由SVM::trainAuto
训练的SVM返回的预测标签的范围为0-25,其对应于26个类别。这也可以通过查看输出文件svm_letter_recog.xml
中的<class_labels>...</class_labels>
来观察到。
因此,在test_and_save_classifier
中,r = model->predict( sample )
和responses.at<int>(i)
明显不相等。
我还发现,如果我们使用SVM::train
,类标签将是65-89,这就是为什么一开始可以得到正常结果的原因。
解决方案
我不确定这是不是一个bug。但如果你现在想在这个样本中使用SVM::trainAuto
,你可以更改
test_and_save_classifier(model, data, responses, ntrain_samples, 0, filename_to_save);
在build_svm_classifier
到中
test_and_save_classifier(model, data, responses, ntrain_samples, 'A', filename_to_save);
更新
CCD_ 12和CCD_ 13在CCD_。该问题是由于以前的错误修复造成的。因此,我创建了一个到OpenCV的pull请求来解决这个问题。