• svm 中采用自动搜索参数的方式获得参数值


    载时自http://blog.csdn.net/u011177305/article/details/46458801?locationNum=1

    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修道者博文的文章,使用其如下代码

    [html] view plain copy
     
     print?
    1. CvSVMParams param;    
    2.   param.svm_type = CvSVM::EPS_SVR;    
    3.   param.kernel_type = CvSVM::RBF;    
    4.   param.C = 1;  //给参数赋初始值  
    5.   param.p = 5e-3;  //给参数赋初始值  
    6.   param.gamma = 0.01;  //给参数赋初始值  
    7.   param.term_crit = cvTermCriteria(CV_TERMCRIT_EPS, 100, 5e-3);   
    8.   //对不用的参数step设为0  
    9.   CvParamGrid nuGrid = CvParamGrid(1,1,0.0);  
    10.   CvParamGrid coeffGrid = CvParamGrid(1,1,0.0);  
    11.   CvParamGrid degreeGrid = CvParamGrid(1,1,0.0);  
    12.   
    13.   CvSVM regressor;  
    14.   regressor.train_auto(PCA_training,tr_label,NULL,NULL,param,  
    15.     10,  
    16.     regressor.get_default_grid(CvSVM::C),  
    17.     regressor.get_default_grid(CvSVM::GAMMA),  
    18.     regressor.get_default_grid(CvSVM::P),  
    19.     nuGrid,  
    20.     coeffGrid,  
    21.     degreeGrid);  
    用上面的代码的就可以自动训练优化出参数了,最后想查看优化后的参数值可以使用CvSVMParams params_re = regressor.get_params()函数来获得各优化后的参数值。
    [html] view plain copy
     
     print?
    1. CvSVMParams params_re = regressor.get_params();  
    2.   regressor.save("training_srv.xml");  
    3.   float C = params_re.C;  
    4.   float P = params_re.p;  
    5.   float gamma = params_re.gamma;  
    6.   printf(" Parms: C = %f, P = %f,gamma = %f  ",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;
    大家不妨尝试一下。
  • 相关阅读:
    面向对象编程
    多任务-线程
    浅析IoC框架
    Android:关于声明文件中android:process属性说明
    Android闹钟设置的解决方案
    【转】RelativeLayout和LinearLayout及FrameLayout性能分析
    SurfaceView浅析
    SQLite Vacuum
    SQLiteStatement优化SQLite操作
    基于Android SQLite的升级详解
  • 原文地址:https://www.cnblogs.com/hust-yingjie/p/6500646.html
Copyright © 2020-2023  润新知