Opencv中的SVM参数优化

    SVM(支持向量机)是机器学习算法里用得最多的算法。SVM最常用的是用于分类,不过SVM也可以用于回归,我的实验中就是用SVM来实现SVR(支持向量回归)。对于功能这么强的算法,opencv中自然也是有集成好了,我们可以直接调用。
    网上讲opencv中SVM使用的文章有很多,但讲SVM参数优化的文章却很少。所以在这里不重点讲怎么使用SVM,而是谈谈怎样通过opencv中自带的库优化SVM中的各参数。
    相信用SVM做过实验的人都知道,SVM的各参数对实验结果有很大的影响,比如C,gama,P,coef等等。下面就是CvSVMParams类的原型。
C++: CvSVMParams::CvSVMParams()
C++: CvSVMParams::CvSVMParams(int svm_type, 
int kernel_type, 
double degree, 
double gamma, 
double coef0, 
double Cvalue, 
double nu,                   
double p, 
CvMat* class_weights,
CvTermCriteria term_crit
        )

 构造函数的参数(一共10个):
<1>svm_type:指定SVM的类型(5种):
CvSVM::C_SVC : C类支持向量分类机。 n类分组  (n≥2),允许用异常值惩罚因子C进行不完全分类。
CvSVM::NU_SVC : 类支持向量分类机。n类似然不完全分类的分类器。参数为取代C(其值在区间【0,1】中,nu越大,决策边界越平滑)。
CvSVM::ONE_CLASS : 单分类器,所有的训练数据提取自同一个类里,然后SVM建立了一个分界线以分割该类在特征空间中所占区域和其它类在特征空间中所占区域。
CvSVM::EPS_SVR : 类支持向量回归机。训练集中的特征向量和拟合出来的超平面的距离需要小于p。异常值惩罚因子C被采用。
CvSVM::NU_SVR : 类支持向量回归机。 代替了 p。 
<2>kernel_type:SVM的内核类型(4种):
CvSVM::LINEAR : 线性内核,没有任何向映射至高维空间,线性区分(或回归)在原始特征空间中被完成,这是最快的选择。
              opencv,svm,优化,参数0.
CvSVM::POLY : 多项式内核:
               opencv,svm,优化,参数1.
CvSVM::RBF : 基于径向的函数,对于大多数情况都是一个较好的选择:
               opencv,svm,优化,参数2.
CvSVM::SIGMOID : Sigmoid函数内核:
              opencv,svm,优化,参数3.
<3> degree:内核函数(POLY)的参数degree。
<4> gamma:内核函数(POLY/ RBF/ SIGMOID)的参数  opencv,svm,优化,参数4。
<5> coef0:内核函数(POLY/ SIGMOID)的参数coef0。
<6> Cvalue:SVM类型(C_SVC/ EPS_SVR/ NU_SVR)的参数C。
<7> nu:SVM类型(NU_SVC/ ONE_CLASS/ NU_SVR)的参数   opencv,svm,优化,参数5。
<8> p:SVM类型(EPS_SVR)的参数  opencv,svm,优化,参数6。
<9> class_weights:C_SVC中的可选权重,赋给指定的类,乘以C以后变成   opencv,svm,优化,参数7。所以这些权重影响不同类别的错误分类惩罚项。权重越大,某一类别的误分类数据的惩罚项就越大。
<10> term_crit:SVM的迭代训练过程的中止条件,解决部分受约束二次最优问题。您可以指定的公差和/或最大迭代次数。
    当然对于一个特定的SVM训练器,里面的所有参数不一定全用。比如我用的svm_type为EPS_SVR,那么我要用到的参数主要就是p,c,gama这三个参数。下面是设置参数的代码
CvSVMParams param;  
param.svm_type = CvSVM::EPS_SVR;  //我的实验是用SVR作回归分析,可能大部分人的实验是用SVM来分类,方法都一样
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); 
       设置参数后就可以用CvSVM.train()进行训练了,下面是train的原型
C++: bool CvSVM::train(const Mat& trainData,  
      const Mat& responses,  
const Mat& varIdx=Mat(),  
const Mat& sampleIdx=Mat(),  
CvSVMParams params=CvSVMParams() 
              ) 
      我在用train完成训练预测时出现了过拟合的情况,即对于训练集的数据有很好的预测结果,但对不在训练集的测试集预测值都一样。于是我开始调整参数,调了半天也没个好结果。
     后面我发现其实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
)

      自动训练函数的参数注释(13个)
前5个参数参考构造函数的参数注释。
k_fold: 交叉验证参数。训练集被分成k_fold的自子集。其中一个子集是用来测试模型,其他子集则成为训练集。所以,SVM算法复杂度是执行k_fold的次数。
*Grid: (6个)对应的SVM迭代网格参数。
balanced: 如果是true则这是一个2类分类问题。这将会创建更多的平衡交叉验证子集。
    自动训练函数的使用说明
这个方法根据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。
     这里需要注意的是,对于需要的优化的参数虽然train_auto可以自动选择最优值,但在代码中也要先赋初始值,要不然编译能通过,但运行时会报错。下面是示例代码
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);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本
引用提到了OpenCV官方文档关于SVM(支持向量机)的相关内容。OpenCV是一个开源计算机视觉库,提供了众多图像处理和计算机视觉算法。SVM是其之一的机器学习算法,用于二分类或多分类问题的建模和预测。 在OpenCV 4.3版本SVM类的相关文档可以在OpenCV官方文档找到。SVM类的主要功能是通过训练数据集来构建支持向量机模型,并且可以使用该模型对新的数据进行分类预测。SVM类提供了多种参数和方法,可以对模型进行定制和优化。 如果您想要了解有关OpenCV 4.3版本SVM类的详细信息,建议您参考OpenCV官方文档提供的文档链接。在该文档,您可以找到有关SVM类的使用方法、参数说明和示例代码等内容,以帮助您更好地理解和应用这个机器学习算法。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [OpenCVSVM目标分类简单示例](https://blog.csdn.net/sss_369/article/details/90404331)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [指针式仪表倾斜校正opencv算法python代码及仪表图像(包含倾斜的和模板图像)](https://download.csdn.net/download/sunnyrainflower/88221223)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值