
加载中…
个人资料
- 博客访问:
- 关注人气:
- 获赠金笔:0支
- 赠出金笔:0支
- 荣誉徽章:
SVM训练及预测过程
(2012-07-18 20:57:22)
标签:
svm
训练
预测
过程
方法
|
分类:
2012.7
|
网上有很多关于LibSVM的教程,LibSVM提供了多平台下的可执行文件,在win平台下可以直接通过命令行执行,可以利用提供的可执行文件方便的进行离线的训练和预测,这里不再赘述。这篇文章要做的是把SVM的训练及预测的过程移植到程序当中的方法进行简单阐述,而不是使用提供的可执行文件。
过程首先要建立工程,这里以VC6.0为例,建立好工程后,需要将LibSVM中的svm.h和svm.cpp文件加入到工程当中,文件中包含我们要用到的svm_train,svm_pridect等函数,建立好这些以后需要做的就是填写SVM为我们准备好的模板。训练的数据以文本识别为依据,将字符定位和切割(字符的定位和切分是需要好好研究的)并且二值化后,就得到如下图的二值化图像,-----http://s5/bmiddle/65caa9784c5171f05fbe4&690
我们就可以对二值化图像提取想要的特征,文本识别较为简单,提取简单的特征就可以实现比较好的识别效果,如可以将图片归一化为统一大小后平均分成八部分,计算每一份的黑色像素点数作为特征等,这里选取了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;//类型