网上有很多关于LibSVM的教程,LibSVM提供了多平台下的
可执行文件,在win平台下可以直接通过命令行执行,可以利用提供的可
执行文件方便的进行离线的训练和预测,这里不再赘述。这篇文章要做的是把SVM的训练及预测的过程移植到程序当中的方法进行简单阐述,而不是使用提供的可执行文件。
过程首先要建立工程,这里以VC6.0为例,建立好工程后,需要将LibSVM中的svm.h和svm.cpp文件加入到工程当中,文件中包含我们要用到的svm_train,svm_pridect等函数,
建立好这些以后需要做的就是填写SVM为我们准备好的模板。
训练的数据以文本识别为依据,将字符定位和切割(字符的定位和切分是需要好好研究的)并且二值化后,就得到如下图的二值化图像,-----
我们就可以对二值化图像提取想要的特征,文本识
别较为简单,提取简单的特征就可以实现比较好的识别效果,如可以将图片归一化为统一大小后平均分成八部分,计算每一份的黑色像素点数作为特征等,这里选取了125维的向量作为每一幅图像的特征。
做好这些准备工作后,就可以开始SVM模型的训练了,就像做菜,原料准备好了,接下来就是煎炒焖炖了,训练可以分为三步:
1、将提取的特征存入一个文本文件当中,方便以后的使用,这里不用特殊的格式,每一幅图像一个特征向量的存好就行了。
2、将提取的特征格式化,SVM训练提取数据的时候需要按照特殊的格式,也就是SVM给我们规定的模板。SVM包含几个重要的元素:
struct svm_problem
{
int l;//记录样本的总数
double *y;//指向样本所属类别的数组
struct svm_node **x;//指向一个存储内容为指针的数组
};
简单的说,svm_problem用来存储本次参加运算的所有样本(数据集)以及所属类别,成员变量l存储样本总数,y存储样本的分类,x存储的是样本的特征值。
struct svm_node
{
int index;
double value;
};
svm_node是用来存储单幅图像的特征数据的,打个比方说,svm_problem是一群羊,那么svm_node就是这一群羊中的一只了。需要注意的是,svm_node的存储空间应该比特征数大一位,最后一位index值必须以-1结束。
我们需要做的就是为l,x,y以及svm_node赋值,使其满足SVM的格式,具体程序如下:
svm_problem prob;
svm_node *node;
prob.l = feature_count;//样本个数
prob.y = new double[prob.l];//分配空间
node = new svm_node[(PROBLEM_DIMENSION+1) * prob.l];
//样本特征存储空间,注意是连续的空间
prob.x = new svm_node *[prob.l];
//分配空间
for(int i = 0; i < prob.l; i++)
{
for(int j = 0; j < PROBLEM_DIMENSION; j++)
{
node[(PROBLEM_DIMENSION + 1) * i + j].index = j + 1;
node[(PROBLEM_DIMENSION + 1) * i + j].value = rFeature->FeatureData[j];
}
node[(PROBLEM_DIMENSION + 1) * i + PROBLEM_DIMENSION].index = -1;
prob.x[i] = &node[(PROBLEM_DIMENSION + 1) * i]; //相当与移动指针(PROBLEM_DIMENSION + 1)
//* i这一位,把这一位的地址传给prob.x[i]
prob.y[i] = rFeature->FeatureType;//类别
rFeature++;
}
其中rFeature为自定义的FEATURE类型
typedef struct
{
char FeatureType;//类型
double FeatureData[PROBLEM_DIMESION];//特征数据PROBLEM_DIMESION定义为125
}FEATURE;
3、格式组装好后,就需要设定SVM的训练参数,以及训练了
svm有如下类型
C_SVC,NU_SVC,ONE_CLASS,EPSILON_SVR,NU_SVR
核函数有如下类型
LINEAR,POLY,RBF,SIGMOID
参数格式规定如下:
struct svm_parameter
{
int svm_type;//SVM的类型
int kernel_type;核函数
double degree;//多项式参数
double gamma;//核函数为poly/rbf/sigmoid的参数
double coef0;//核函数为poly/sigmoid的参数
//下面是训练所需的参数
double cache_size;//训练所需的内存MB为单位
double eps;//训练停止的标准
double C;//惩罚因子,越大训练时间越长
int nr_weight;//权重的数目,目前只有两个值,默认为0
int *weight_label;//权重,元素个数由nr_weight决定
double* weight;//C_SVC权重
double nu;
double p;
int shrinking;//训练过程是否使用压缩
int probability;//是否做概率估计
};
具体的代码实例如下:
svm_parameter para;
para.svm_type = C_SVC;
para.kernel_type = RBF;
para.degree = 3;
para.gamma = 0.0001;
para.coef0 = 0;
para.nu = 0.5;
para.cache_size = 100;
para.C = 10;
para.eps = 1e-5;
para.p = 0.1;
para.shrinking = 1;
para.probability = 0;
para.nr_weight = 0;
para.weight_label = NULL;
para.weight = NULL;
参数都设置好后就是训练了,直接调用svm.cpp中的函数:
svm_model *model;
model = svm_train(&prob, ¶);//训练
svm_save_model(model_name,model);//保存模型
具体的函数说明都可以查得到,model的结构规定也可以见svm中,不在赘述。
接下来是利用训练好的model进行预测的过程,过程非常简单,分为两步:
1、装载模型
svm_model* model;
model = svm_load_model(modelPath);
2、预测
double p = svm_predict(model,node);
node中保存的是要进行分类的图像的特征值。
这样,整个训练以及预测的过程就结束了。
Python完整的svr模型进行多维的预测代码
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章