LibSVM C++ 版本用法


发布于

|

分类

强攻了一周,总算放弃了。

Python调LibSVM的话,直接用scikit-learn包就好了。现在问题是,C和C++怎么来调用。

不用写代码的方法

LibSVM很良心地给了个Demo,就是那个预测心脏大小的例子。源文件在svm-train.c,直接编译出来就能用。

这样的话就要遵守这个程序的输入格式(具体可参考heart_scale这个文件):

首先,每一行分为两个部分:标签和特征。

标签就是类别啦,例子中是+1和-1。其实用什么都行的。而且标签可以不连续。

然后是特征。需要按照index:value的形式给出。并且,如果缺失几个标签也是无所谓的,只要连index一起缺失就好了。

之后运行编译好的svm_train文件即可开始训练。参数啊什么的也可以运行时指定。

写代码的方法

如果想集成进自己的C/C++代码,也不难。

svm.hsvm.c一起放进项目中,并在自己文件里面引用svm.h

首先来构造我们的数据对象:svm_problem。这个对象又三部分构成:l是「有多少数据」、x是「特征矩阵」,y是对应的标签。其中,x的类型是svm_mode,里面也分为两部分,indexvalue

约定是这样的:例如我有10个样本,每个样本经过OpenCV特征提取后,均可得到32维特征向量。所以我们的代码可以这样来写:

auto feature = feature_extract(...);

svm_problem problem;
problem.l = 10;
problem.x = new svm_node*[10];
problem.y = new double[10];
for (int i=0; i<10; ++i){
    problem.x[i] = new svm_node[32+1];
    for(int j=0; j<32; ++j){
        problem.x[i][j].index = j + 1;
        problem.x[i][j].value = feature.at<float>(i,j);
    }
    problem.x[i][32] = -1;
    problem.y[i] = label[i];
}

其中要点是,index从1开始,最后补个-1。

如何训练svm,写它的训练参数。例如下面这段代码:

svm_parameter param{C_SVC, RBF, 3, 0.1, 0, 20, 1e-3, 1, 0, nullptr, nullptr, 0.5, 0.1, 0, 0};

具体含义可以看头文件。

然后愉快地开始训练吧:

auto model = svm_train(&problem, &param);

最后,训练完毕,要保存一下呀

if (svm_save_model(output_file.c_str(), model)) {
    std::cerr << "Save SVM to [" << output_file << "] FAILED" << std::endl;
} else {
    std::cout << "Save SVM to [" << output_file << "] SUCCEED." << std::endl;
}

好了,大致就这么多。


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注