OpenCV 3.0中的SVM训练 参数解析

opencv3.0和2.4的SVM接口有不同,基本可以按照以下的格式来执行:

ml::SVM::Params params;
params.svmType = ml::SVM::C_SVC;
params.kernelType = ml::SVM::POLY;
params.gamma = 3;
Ptr<ml::SVM> svm = ml::SVM::create(params);
Mat trainData; // 每行为一个样本
Mat labels;    
svm->train( trainData , ml::ROW_SAMPLE , labels );
// ...

svm->save("....");//文件形式为xml,可以保存在txt或者xml文件中
Ptr<SVM> svm=statModel::load<SVM>("....");

Mat query; // 输入, 1个通道
Mat res;   // 输出
svm->predict(query, res);

 但是要注意,如果报错的话最好去看opencv3.0的文档,里面有函数原型和解释,我在实际操作的过程中,也做了一些改动

   1)设置参数

    SVM的参数有很多,但是与C_SVC和RBF有关的就只有gamma和C,所以设置这两个就好,终止条件设置和默认一样,由经验可得(其实是查阅了很多的资料,把gamma设置成0.01,这样训练收敛速度会快很多)

Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::RBF);
svm->setGamma(0.01);
svm->setC(10.0);
svm->setTermCriteria(TermCriteria(CV_TERMCRIT_EPS, 1000,FLT_EPSILON));

  svm_type –指定SVM的类型,下面是可能的取值:

  CvSVM::C_SVC C类支持向量分类机。 n类分组 (n \geq 2),允许用异常值惩罚因子C进行不完全分类。
  CvSVM::NU_SVC \nu类支持向量分类机。n类似然不完全分类的分类器。参数为 \nu 取代C(其值在区间【0,1】中,nu越大,决策边界越平滑)。
  CvSVM::ONE_CLASS 单分类器,所有的训练数据提取自同一个类里,然后SVM建立了一个分界线以分割该类在特征空间中所占区域和其它类在特征空间中所占区域。
  CvSVM::EPS_SVR \epsilon类支持向量回归机。训练集中的特征向量和拟合出来的超平面的距离需要小于p。异常值惩罚因子C被采用。
  CvSVM::NU_SVR \nu类支持向量回归机。 \nu 代替了 p。

  kernel_type –SVM的内核类型,下面是可能的取值:

  CvSVM::LINEAR 线性内核。没有任何向映射至高维空间,线性区分(或回归)在原始特征空间中被完成,这是最快的选择。K(x_i, x_j) = x_i^T x_j.
  CvSVM::POLY 多项式内核: K(x_i, x_j) = (\gamma x_i^T x_j + coef0)^{degree}, \gamma > 0.
  CvSVM::RBF 基于径向的函数,对于大多数情况都是一个较好的选择: K(x_i, x_j) = e^{-\gamma ||x_i - x_j||^2}, \gamma > 0.
  CvSVM::SIGMOID Sigmoid函数内核:K(x_i, x_j) = \tanh(\gamma x_i^T x_j + coef0).

  degree – 内核函数(POLY)的参数degree。

  gamma – 内核函数(POLY/ RBF/ SIGMOID)的参数\gamma。

  coef0 – 内核函数(POLY/ SIGMOID)的参数coef0。

  Cvalue – SVM类型(C_SVC/ EPS_SVR/ NU_SVR)的参数C。

  nu – SVM类型(NU_SVC/ ONE_CLASS/ NU_SVR)的参数 \nu。

  p – SVM类型(EPS_SVR)的参数 \epsilon。

  class_weights – C_SVC中的可选权重,赋给指定的类,乘以C以后变成 class\_weights_i * C。所以这些权重影响不同类别的错误分类惩罚项。权重越大,某一类别的误分类数据的惩罚项就越大。

  term_crit – SVM的迭代训练过程的中止条件,解决部分受约束二次最优问题。您可以指定的公差和/或最大迭代次数。

2)训练

Mat trainData;
Mat labels;
trainData = read_mnist_image(trainImage);
labels = read_mnist_label(trainLabel);

svm->train(trainData, ROW_SAMPLE, labels); 

3)保存

svm->save("mnist_dataset/mnist_svm.xml");

3. 测试,比对结果

 (此处的FLT_EPSILON是一个极小的数,1.0 - FLT_EPSILON != 1.0)

Mat testData;
Mat tLabel;
testData = read_mnist_image(testImage);
tLabel = read_mnist_label(testLabel);

float count = 0;
for (int i = 0; i < testData.rows; i++) {
    Mat sample = testData.row(i);
    float res = svm1->predict(sample);
    res = std::abs(res - tLabel.at<unsigned int>(i, 0)) <= FLT_EPSILON ? 1.f : 0.f;
    count += res;
}
cout << "正确的识别个数 count = " << count << endl;
cout << "错误率为..." << (10000 - count + 0.0) / 10000 * 100.0 << "%....\n";

这里没有使用svm->predict(query, res);

然后就查看了opencv的文档,当传入数据是Mat 而不是cvMat时,可以利用predict的返回值(float)来判断预测是否正确。

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
很抱歉,我不会编程,但是我可以向您提供一些参考资料。 要在C语言使用OpenCV进行SVM训练,您需要了解以下内容: 1. C语言基础 2. OpenCVSVM分类器 3. 文文本向量化方法,如词袋模型和TF-IDF 以下是一个简单的示例,展示如何使用OpenCVSVM分类器在文数据集上进行训练和分类。 ``` #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { // 加载文文本数据集 Mat trainingData = loadTrainingData(); // 为SVM分类器设置参数 CvSVMParams params; params.svm_type = CvSVM::C_SVC; params.kernel_type = CvSVM::LINEAR; params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); // 训练SVM模型 CvSVM svm; svm.train_auto(trainingData, Mat(), Mat(), Mat(), params, 10); // 加载测试数据 Mat testData = loadTestData(); // 对测试数据进行分类 Mat results; svm.predict(testData, results); // 将结果输出到控制台 cout << results << endl; return 0; } // 加载文文本数据集 Mat loadTrainingData() { // 将文文本向量化为词袋模型或TF-IDF向量 Mat trainingData = vectorizeTextData(); return trainingData; } // 加载文测试数据集 Mat loadTestData() { // 将文文本向量化为词袋模型或TF-IDF向量 Mat testData = vectorizeTextData(); return testData; } // 将文文本向量化为词袋模型或TF-IDF向量 Mat vectorizeTextData() { // 使用词袋模型或TF-IDF将文文本向量化 return vectorizedData; } ``` 请注意,这只是一个简单的示例,实际上实现一个有效的文文本分类器需要使用更复杂的技术和算法。建议您先了解OpenCVSVM分类器和文文本向量化方法,然后再着手编写代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值