【发布时间】:2014-12-15 01:33:10
【问题描述】:
我已经坚持了一段时间了。 OpenCV 的 SVM 实现似乎不适用于线性内核。我相当确定代码中没有错误:当我将 kernel_type 更改为 RBF 或 POLY 时,保持其他所有内容不变,它可以工作。
我说它不起作用的原因是,我保存生成的模型并检查它。它显示支持向量计数为 1。RBF 或 POLYnomial 内核不是这种情况。
代码本身并没有什么特别之处,我之前使用过 OpenCV 的 SVM 实现,但从来没有使用过线性内核。我尝试在 POLY 内核中将degree 设置为 1,结果是相同的模型。这让我相信这里有些问题。
代码结构,如果需要的话:
Mat trainingdata; //acquire from files. done and correct.
Mat testingdata; //acquire from files. done and correct again.
Mat labels; //corresponding labels. checked and correct.
SVM my_svm;
SVMParams my_params;
my_params.svm_type = SVM::C_SVC;
my_params.kernel_type = SVM::LINEAR; //or poly, with my_params.degree = 1.
my_param.C = 0.02; //doesn't matter if I set it to 20000, makes no difference.
my_svm.train( trainingdata, labels, Mat(), Mat(), my_params );
//train_auto(..) function with 10-fold cross-validation takes the same time as above (~2sec)!
Mat responses;
my_svm.predict( testingdata, responses );
//responses matrix is all wrong.
我有一个类的 500 个样本和另一个类的 600 个样本要测试,我得到的正确分类是:1/500 和 597/600。
最疯狂的部分: 我在 libSVM 的 MATLAB 包装器上使用相同的数据进行了相同的实验,并且它可以工作。 只是试图做一个 OpenCV 版本。
【问题讨论】:
-
你确定数据是线性可分的吗?它与更高级的内核一起工作的事实强烈表明非线性可分数据......您是否使用线性内核训练 libSVM?
-
你知道SVM的公式吗?将 C 设置为 0.02 或 20000 时应该会有差异。请确保设置正确。它不能对所有参数都相同。此外,您应该将 epsilon 参数设置为 0.001,默认值是其他 AFAIK。最后一件事,当你运行
train_auto()而不是train()时会发生什么? -
尝试改编标准示例examples/cpp/points_classifier.cpp 还有svm分类器。我已经检查过了,它确实有效。
-
@SchighSchagh 我复制了我在 libSVM 中所做的实验。它在那里就像一个魅力。
-
@guneykayim 我知道 SVM 的公式,并且我了解 C 对模型的作用。这就是为什么我对 C 的价值没有产生任何影响感到惊讶的原因。
train_auto()什么都不做。给我C = 1。我试过了。