svm 中采用自动搜索参数的方式获得参数值
2015-06-11 16:07
309 查看
opencv中SVM类是提供了优化参数值功能的,下面讲讲具体的做法。
要让svm自动优化参数,那么训练时就不能再用train函数了,而应该用train_auto函数。下面是train_auto的函数原型
C++: bool CvSVM:: train_auto (const Mat & trainData ,
const Mat & responses ,
const Mat & varIdx ,
const Mat & sampleIdx ,
CvSVMParams params ,
int k_fold=10 ,
CvParamGrid Cgrid=CvSVM::get_default_grid(CvSVM::C) ,
CvParamGrid gammaGrid=CvSVM::get_default_grid(CvSVM::GAMMA) ,
CvParamGrid pGrid=CvSVM::get_default_grid(CvSVM::P) ,
CvParamGrid nuGrid=CvSVM::get_default_grid(CvSVM::NU) ,
CvParamGrid coeffGrid=CvSVM::get_default_grid(CvSVM::COEF) ,
CvParamGrid degreeGrid=CvSVM::get_default_grid(CvSVM::DEGREE) ,
bool balanced=false
)
自动训练函数的使用说明:
这个方法根据CvSVMParams中的最佳参数C, gamma, p, nu, coef0, degree自动训练SVM模型。参数被认为是最佳的交叉验证,其测试集预估错误最小。如果没有需要优化的参数,相应的网格步骤应该被设置为小于或等于1的值。
例如,为了避免gamma的优化,设置gamma_grid.step = 0,gamma_grid.min_val, gamma_grid.max_val 为任意数值。所以params.gamma 由gamma得出。
最后,如果参数优化是必需的,但是相应的网格却不确定,你可能需要调用函数CvSVM::get_default_grid(),创建一个网格。例如,对于gamma,调用CvSVM::get_default_grid(CvSVM::GAMMA)。该函数为分类运行 (params.svm_type=CvSVM::C_SVC 或者 params.svm_type=CvSVM::NU_SVC) 和为回归运行 (params.svm_type=CvSVM::EPS_SVR
或者 params.svm_type=CvSVM::NU_SVR)效果一样好。如果params.svm_type=CvSVM::ONE_CLASS,没有优化,并指定执行一般的SVM。
参考IT修道者博文的文章,使用其如下代码
params_re = regressor.get_params()函数来获得各优化后的参数值。
OpenCV Error: Assertion failed (sv_count != 0) in do_train, file /home/.../opencv-2.4.9/modules/ml/src/svm.cpp,
line 1346
该问题在stack overflow中有人提出,不过没有解决方案。
我修改了一下
大家不妨尝试一下。
要让svm自动优化参数,那么训练时就不能再用train函数了,而应该用train_auto函数。下面是train_auto的函数原型
C++: bool CvSVM:: train_auto (const Mat & trainData ,
const Mat & responses ,
const Mat & varIdx ,
const Mat & sampleIdx ,
CvSVMParams params ,
int k_fold=10 ,
CvParamGrid Cgrid=CvSVM::get_default_grid(CvSVM::C) ,
CvParamGrid gammaGrid=CvSVM::get_default_grid(CvSVM::GAMMA) ,
CvParamGrid pGrid=CvSVM::get_default_grid(CvSVM::P) ,
CvParamGrid nuGrid=CvSVM::get_default_grid(CvSVM::NU) ,
CvParamGrid coeffGrid=CvSVM::get_default_grid(CvSVM::COEF) ,
CvParamGrid degreeGrid=CvSVM::get_default_grid(CvSVM::DEGREE) ,
bool balanced=false
)
自动训练函数的使用说明:
这个方法根据CvSVMParams中的最佳参数C, gamma, p, nu, coef0, degree自动训练SVM模型。参数被认为是最佳的交叉验证,其测试集预估错误最小。如果没有需要优化的参数,相应的网格步骤应该被设置为小于或等于1的值。
例如,为了避免gamma的优化,设置gamma_grid.step = 0,gamma_grid.min_val, gamma_grid.max_val 为任意数值。所以params.gamma 由gamma得出。
最后,如果参数优化是必需的,但是相应的网格却不确定,你可能需要调用函数CvSVM::get_default_grid(),创建一个网格。例如,对于gamma,调用CvSVM::get_default_grid(CvSVM::GAMMA)。该函数为分类运行 (params.svm_type=CvSVM::C_SVC 或者 params.svm_type=CvSVM::NU_SVC) 和为回归运行 (params.svm_type=CvSVM::EPS_SVR
或者 params.svm_type=CvSVM::NU_SVR)效果一样好。如果params.svm_type=CvSVM::ONE_CLASS,没有优化,并指定执行一般的SVM。
参考IT修道者博文的文章,使用其如下代码
CvSVMParams param; param.svm_type = CvSVM::EPS_SVR; param.kernel_type = CvSVM::RBF; param.C = 1; //给参数赋初始值 param.p = 5e-3; //给参数赋初始值 param.gamma = 0.01; //给参数赋初始值 param.term_crit = cvTermCriteria(CV_TERMCRIT_EPS, 100, 5e-3); //对不用的参数step设为0 CvParamGrid nuGrid = CvParamGrid(1,1,0.0); CvParamGrid coeffGrid = CvParamGrid(1,1,0.0); CvParamGrid degreeGrid = CvParamGrid(1,1,0.0); CvSVM regressor; regressor.train_auto(PCA_training,tr_label,NULL,NULL,param, 10, regressor.get_default_grid(CvSVM::C), regressor.get_default_grid(CvSVM::GAMMA), regressor.get_default_grid(CvSVM::P), nuGrid, coeffGrid, degreeGrid);用上面的代码的就可以自动训练优化出参数了,最后想查看优化后的参数值可以使用CvSVMParams
params_re = regressor.get_params()函数来获得各优化后的参数值。
CvSVMParams params_re = regressor.get_params(); regressor.save("training_srv.xml"); float C = params_re.C; float P = params_re.p; float gamma = params_re.gamma; printf("\nParms: C = %f, P = %f,gamma = %f \n",C,P,gamma);不过根据我的测试发现如下错误:
OpenCV Error: Assertion failed (sv_count != 0) in do_train, file /home/.../opencv-2.4.9/modules/ml/src/svm.cpp,
line 1346
该问题在stack overflow中有人提出,不过没有解决方案。
我修改了一下
CvParamGrid CvParamGrid_C(pow(2.0,-5), pow(2.0,15), pow(2.0,2)); CvParamGrid CvParamGrid_gamma(pow(2.0,-15), pow(2.0,3), pow(2.0,2)); if (!CvParamGrid_C.check() || !CvParamGrid_gamma.check()) cout<<"The grid is NOT VALID."<<endl; CvSVMParams paramz; paramz.kernel_type = CvSVM::RBF; paramz.svm_type = CvSVM::C_SVC; paramz.term_crit = cvTermCriteria(CV_TERMCRIT_ITER,100,0.000001); svm.train_auto(trainingData, labels, Mat(), Mat(), paramz,10, CvParamGrid_C, CvParamGrid_gamma, CvSVM::get_default_grid(CvSVM::P), CvSVM::get_default_grid(CvSVM::NU), CvSVM::get_default_grid(CvSVM::COEF), CvSVM::get_default_grid(CvSVM::DEGREE), true); paramz = svm.get_params(); cout<<"gamma:"<<paramz.gamma<<endl; cout<<"C:"<<paramz.C<<endl;
大家不妨尝试一下。
相关文章推荐
- openssl编程之客户端
- android 获取手机信息工具类
- hdu 4911 Inversion(找到的倒数)
- 易宝支付原理
- DEV GridControl小结。。转载的
- Contains Duplicate
- 缓存
- A Few Words about my ProRes Encoder
- JavaScript语法中的九个陷阱
- c#使用unit在mac环境下测试
- C# 获得当前目录的一些方法(转)
- Android drawable-nodpi 的作用
- 多线程之线程池任务管理通用模板
- 动画库tween.js--常用的运动算法
- [整理]Android在线源码
- Linux使用 tar命令-g参数进行增量+差异备份、还原文件
- MDT 2013 从入门到精通之客户端映像捕获
- MDT 2013 从入门到精通之客户端映像捕获
- [POJ_1068]Parencodings
- 8种移动APP导航设计模式