0

我使用 surf 和 bow 训练 svm ,现在我预测图像时它总是返回我 1 ,即使我选择负图像时它也返回我 1 作为输出

这是 svm 的参数:

CvSVMParams Params;
Params.svm_type=CvSVM::C_SVC;
Params.kernel_type=CvSVM::LINEAR;
Params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
Params.gamma=3;
CvSVM svm;
svm.train(training_mat,labels,cv::Mat(),cv::Mat(),Params);

这是我的预测代码:

predict_img = cvLoadImage("ss.jpg",0);
detector.detect(predict_img, keypoint2);
RetainBestKeypoints(keypoint2, 20);
dextract.compute( predict_img, keypoint2, descriptors_2);
Mat my_img_3 = descriptors_2.reshape(1,1);
float response = svm.predict(my_img_3);
cout<<response;

这是初始化:

BOWImgDescriptorExtractor dextract(extractor,matcher);
SurfFeatureDetector detector(500);
4

2 回答 2

1

你应该检查你设置的是否足够大C(我在你的代码中没有看到它,所以它应该根据opencv文档设置为1000 )值来强制一个合理的模型,你应该尝试很多值,对于许多实际问题一个必须甚至C使用10^10. 如果太小C,SVM 将简单地寻找具有小范数的超平面,而不真正关注正确的分类。它可以通过Cvalueopencv 实现中的参数访问。

Params.gamma=3;

即使它不会导致错误 - 您不需要设置该gamma值,因为它不用于线性内核,它用于 RBF 内核。

您还应该确保您正在训练相似数量的正样本和负样本(或使用一些类加权技术),因为它也可能导致“微不足道”的模型。

于 2013-08-29T20:02:23.480 回答
1

除了已经提供的答案之外,您将来总会问另一个问题,即如何提高您的 SVM 分类性能,即正确设置模型参数。

为了实现这个目标,您还应该研究 CvParamGrid 提供的网格搜索。

最好的

于 2013-08-30T13:26:03.090 回答