这基本上是this question的副本,但是无论如何我都在问,因为原始海报要么解决了问题,要么失去了兴趣。
我想使用以下代码使用OpenCV自动训练回归SVM:
CvSVMParams params;
params.svm_type = CvSVM::EPS_SVR;
params.kernel_type = CvSVM::RBF;
params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6);
CvSVM svm;
svm.train_auto(_data, _resp, _var_idx, _train_idx, params);
_data和_resp是保存特征 vector 和响应的Mats,_var_idx包含 Activity 特征,_train_idx是 Activity 样本。对于参数网格,使用默认值。不幸的是,该代码产生以下错误:
当我使用手动选择的参数运行单个回归时,它可以正常工作。当我切换到分类问题(并更改相应的参数和SVM类型)时,它也可以工作。在那种情况下,既要进行单人训练,也要进行自动训练。
有人可以指出是什么问题吗?
编辑:
上面的代码也导致另一个错误:
对于CvSVM::NU_SVR,这与参数nu相同。设置这些参数后,问题消失了,但我不明白为什么首先会发生此错误。当我查看train_auto的文档时,它说p(和nu)是使用它们相应的默认网格进行评估的。那么为什么我必须设置它们呢?
提前致谢。
编辑2:
我举了一个受这个问题困扰的小例子。万一有人想尝试一下并重现问题,以防万一:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
int main() {
Mat X(1000, 2, CV_32FC1);
Mat Y(1000, 1, CV_32FC1);
randu(X, -2, 2);
for(int i = 0; i < 1000; i++){
Y.at<float>(i,0) = pow(X.at<float>(i,0),2) + pow(X.at<float>(i,1),2) - 1;
}
CvSVMParams params;
params.svm_type = CvSVM::EPS_SVR;
params.kernel_type = CvSVM::RBF;
params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6);
params.p = 0.1;
CvSVM svm;
svm.train_auto(X, Y, Mat::ones(1,2, CV_8U), Mat::ones(1,1000, CV_8U), params);
return 0;
}
最佳答案
也许您应该为这些参数分配初始值。
param.C = 1; //initialize parameter
param.p = 5e-3; //initialize parameter
param.gamma = 0.01; //initialize parameter