关于libsvm的c++训练的有关例子
关于libsvm的c++训练的有关例子**
本人是小白,因为在学习图像处理的过程中,需要用到libsvm,因此将在使用过程中遇到的问题记录下来,方便以后自己查看,也希望能够帮助其他的初学者。
首先关于libsvm的介绍libsvm下载可以从其官网免费获得,可以根据自己的需要下载版本,本人下载的是3.23版本.
不同文件夹对应不同版本的libsvm,其中README是关于libsvm的介绍,里面都是英文,这个是一位博主介绍的中文版本。看完之后就开始准备数据,首先就是将数据归一化,libsvm自带归一化的工具,具体使用方法见博客。由于我个人采用数据的特殊性,因此没有用自带的归一化的工具。然后就是生成libsvm训练是所需要的数据格式,数据格式如下:Label 1:value 2:value ….
Label:如果是分类,就是类别的标识,可以随意定,我定的是0和1。原始数据如下图所示:
生后的数据格式如下图所示
生成数据的代码我采用的主要是参考博主的代码,并进行一点改进。
int main()
{
struct featureVector {
string label;
vector<string> values;
};
string line, word, buff; //分别保存来自文件的一行和一个单词
string inAdress, outAdress;
cout << "input the infile address" << endl;
cin >> inAdress;
cout << "input the outfile address" << endl;
cin >> outAdress;
ifstream infile(inAdress);//格式如"D://t.txt"
ofstream outfile(outAdress);//格式如"D://tt.txt"
vector<featureVector> objectPic; //保存来自文件的所有记录
while (getline(infile, line)) {
int i = 0;
featureVector info; //创建一个保存记录数据的对象
istringstream record(line); //将记录绑定在刚刚读入的行
record >> info.label; //读取label
while (i!=9) //读取特征向量数据
{
if (i != 0) //每行的第一个为标签,不用序号
{
buff = i + '0'; //values是一个string型的vector,所以要将i转换一下类型
info.values.push_back(buff);
info.values.push_back(":");
info.values.push_back(word); //保持它们
}
record >> word;
i++;
}
objectPic.push_back(info); //将此记录追加到objectPic的末尾
}
for (const auto &entry : objectPic) { //对objectPic中的每一项
int j = 0;
outfile << entry.label;
for (const auto &nums : entry.values) {
if (j % 3 == 0) //在每一个向量的值后面才需要加上空格
outfile << " ";
outfile << nums;
j++;
}
outfile << "\n"; //一条记录输出完后换行
}
getchar();
return 0;
}
``
数据格式准备完毕以后就是开始进行训练,首先新建一个工程文件,将svm.h和svm.cpp加入工程。可以参考博主
首先对数据进行训练,将svm-train加入工程(注意:为保证代码不是一闪而过,在svm-train.c里面加了一句)system(“pause”)
将准备好的数据格式文件加入工程文件目录下,接下来就是配置参数。参数的配置
关于配置参数的说明如下:
options(操作参数):可用的选项即表示的涵义如下所示
-s svm类型:设置SVM 类型,默认值为0,可选类型有:
0 – C- SVC
1 – n - SVC
2 – one-class-SVM
3 – e - SVR
4 – n - SVR
-t 核函数类型:设置核函数类型,默认值为2,可选类型有:
0 – 线性核:u’v
1 – 多项式核: (gu’v+ coef 0)deg ree
2 – RBF 核:e( u v 2) g -
3 – sigmoid 核:tanh(gu’*v+ coef 0)
-d degree:核函数中的degree设置,默认值为3; -g g :设置核函数中的g ,默认值为1/ k ;
-r coef 0:设置核函数中的coef 0,默认值为0;
-c cost:设置C- SVC、e - SVR、n - SVR中从惩罚系数C,默认值为1;
-n n :设置n - SVC、one-class-SVM 与n - SVR 中参数n ,默认值0.5;
-p e :设置n - SVR的损失函数中的e ,默认值为0.1;
-m cachesize:设置cache内存大小,以MB为单位,默认值为40;
-e e :设置终止准则中的可容忍偏差,默认值为0.001;
-h shrinking:是否使用启发式,可选值为0 或1,默认值为1;
-b 概率估计:是否计算SVC或SVR的概率估计,可选值0 或1,默认0;
-wi weight:对各类样本的惩罚系数C加权,默认值为1;
-v n:n折交叉验证模式。
其中-g选项中的k是指输入数据中的属性数。操作参数 -v 随机地将数据剖分为n 部分并计算交叉检验准确度和均方根误差。以上这些参数设置可以按照SVM 的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM 类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。training_set_file是要进行训练的数据集;model_file是训练结束后产生的模型文件,该参数如果不设置将采用默认的文件名,也可以设置成自己惯用的文件名。
在关于分类问题是的时候一般选用C- SVC,关于核函数的选择,本人也不是十分清楚,看过博主里面有详细的介绍。我个人选择RBF核函数,而使用核函数最主要的就是关于核参数-g和-c的设置,令人高兴的是libsvm已经有关于-g和-c的参数寻优的工程。但是需要Python和gnuplot两个软件,关于Python的下载本人就不在叙述,网上有很多的教程。关于gnuplot的下载:https://sourceforge.net/projects/gnuplot/files/gnuplot/ 下载完直接解压就行,不用安装。准备完毕之后。使用IDLE打开grid.py, grid.py在libsvm/tools里面,切记不要使用notepad++等其他软件打开该文件。
找到gnuplot 的安装目录,打开gnuplot\bin\,复制该目录替换上面的c:\tmp\gnuplot\bin\pgnuplot.exe”,在windows环境下的修改方式如下:
本人的pgnuplot.exe目录在F:\GNUPLOT\gnuplot。因此替换成如下目录,对自己准备好的训练集进行参数寻优,本人的训练集命名为111.txt.将训练集和grid.py放在相同目录下执行cmd,输入一下命令 python grid.py 111.txt
结果如下,第一个参数为c,第二个参数为g,因此在libsvm训练时将参数命名如下:
-s 0 -t 2 -c 2048 -g 8 -h 0 111.txt myModel1
111.txt为训练数据集,myModel1为训练结束后的模型。训练结果如下:
接下来就是对模型进行测试,将svm-train移除工程,将svm-predic添加进来进行测试,配置参数如下-b 0 222.txt myModel1 predFile.txt。222.txt为测试数据,predFile.txt,为测试结果。命令参数设置完成调试,就可以得出测试结果:
同时,也可以配合其他程序进行预测,也就是来一组数据对数据进行一次预测。
{
svm_model* model = svm_load_model("myModel1"); // 保存训练好的模型,下次使用时就可直接导入
double data[8] = { 0.0413223,0.206612 ,0.107438 ,0.0661157, 0.0909091 , 0.289256 , 0.14876 , 0.0495868 };//数组
int feature_size = 8;//特征数
svm_node* node = new svm_node[1 + feature_size];
for (int i = 0; i < feature_size; i++)
{
node[i].index = i + 1;
node[i].value = data[i];
}
node[feature_size].index = -1;
double pred = svm_predict(model, node);
cout << "predict: " << pred << endl;
system("pause");
}
预测结果如图所示,到这libsvm训练结束,这篇博客仅供参考使用,由于第一次写博客,排版可能比较乱,也可能会有错误的地方,欢迎大家指正。同时对于参考的博主的博文表示感谢,如有侵权的地方联系删除。