OpenCV SVM 参数的推荐值

Recommended values for OpenCV SVM parameters

对 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%差了。

使用带 trainAuto() 的 RBF 内核最差?

$ ./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);

我调试了示例代码,找到了原因

responses是一个Mat的ASCII码字母。

然而,SVM::trainAuto训练的SVM返回的预测标签范围为0-25,对应26个classes。这也可以通过查看输出文件 svm_letter_recog.xml.

中的 <class_labels>...</class_labels> 来观察

因此在test_and_save_classifier中,r = model->predict( sample )responses.at<int>(i)显然不相等。

我还发现,如果我们使用SVM::train,那么class标签就会变成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);

更新

trainAutotrainclass_labels 中应该有相同的行为。问题是由于之前的错误修复。所以我为 OpenCV 创建了一个 pull request 来解决这个问题。

我建议尝试使用 RBF 内核而不是线性内核。 在很多很多情况下,它是最好的选择...