matlab 使用libsvm工具箱进行手写数字识别

来源:互联网 发布:iphone蓝牙传输软件 编辑:程序博客网 时间:2024/05/27 16:42

上一篇讲到如何在matlab中添加libsvm工具箱,svm的理论就不做介绍了,接下来进行手写数字识别,本文使用svm进行0、1手写数字二分类,多分类情况与其类似。
1、识别过程
下载mnist手写数字图像集,分别选取其中的0、1的500张作为训练数据,另外的100张作为测试数据,程序如下:

clear;clc;% traintrain_fileName='F:\MATLAB\R2014a\work\libsvm-3.11\data\shouxie\train\';train_Files = dir(strcat(train_fileName,'*.bmp'));LengthFiles = length(train_Files);train_img_arr=[];train_label(1:500)=ones(1,500)*0;train_label(501:1000)=ones(1,500)*1;train_label=train_label'; %训练的标签for i = 1:LengthFiles    srcimg = imread(strcat(fileName,Files(i).name));    im=rgb2gray(srcimg);    bwimg=im2bw(im,5/255); %二值化    img_arr = reshape(bwimg, 1, prod(size(bwimg))); %图像展开为一行    img_arr=double(img_arr);    train_img_arr=[train_img_arr;img_arr]; %都必须是double,不然会报错endmodel = svmtrain(train_label, train_img_arr, '-s 0 -c 0.5 -t 2 -g 1 -r 1 -d 3');save('shouxie_model','model');% [predict_label, accuracy, dec_values] =svmpredict(heart_scale_label, heart_scale_inst, model);% testtest_filename='F:\MATLAB\R2014a\work\libsvm-3.11\data\shouxie\test\';test_Files = dir(strcat(test_filename,'*.bmp'));test_LengthFiles = length(test_Files);test_label(1:100)=ones(1,100)'*0;test_label(101:200)=ones(1,100)'*1;test_label=double(test_label'); %测试的标签test_img_arr=[];for i = 1:test_LengthFiles    test_img = imread(strcat(test_filename,test_Files(i).name));    test_im=rgb2gray(test_img);    test_bwimg=im2bw(test_im,5/255);    img_arr1 = reshape(test_bwimg, 1, prod(size(test_bwimg)));    img_arr1=double(img_arr1);    test_img_arr=[test_img_arr;img_arr1];end[predict_label1, accuracy, dec_values] =svmpredict(test_label, test_img_arr, model);

这里写图片描述
在进行分类的时候,本文直接将手写数字图像(28*28)展开为一行作为其特征向量进行训练和测试,当然,也可以采用pca或者其他方法提取其特征,然后再进行svm分类,可以提高其识别率,从图中可以看到识别结果一般,有几个参数需要进一步优化,这里只讲解怎么使用libsvm,网上有人的识别率达到90%多。

2、参数讲解
在使用libsvm工具箱的时候,主要用到了svmtrain、svmpredict两个函数,现在介绍下其中的几个重要的参数。
使用svmtrain后会得到一个model,参数如下:
这里写图片描述
model.Parameters参数意义从上到下依次为,在svmtrain函数可以通过字符串进行设置:
-s svm类型:SVM设置类型(默认0)
-t 核函数类型:核函数设置类型(默认2)
-d degree:核函数中的degree设置(针对多项式核函数)(默认3)
-g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数) (默认类别数目的倒数)
-r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)。

具体解释可以在readme文档中查看,
options:
-s svm_type : set type of SVM (default 0)
0 – C-SVC
1 – nu-SVC
2 – one-class SVM
3 – epsilon-SVR
4 – nu-SVR
-t kernel_type : set type of kernel function (default 2)
0 – linear: u’*v
1 – polynomial: (gamma*u’*v + coef0)^degree
2 – radial basis function: exp(-gamma*|u-v|^2)
3 – sigmoid: tanh(gamma*u’*v + coef0)
4 – precomputed kernel (kernel values in training_set_file)

-d degree : set degree in kernel function (default 3)–核函数中的degree设置(针对多项式核函数)(默认3)
-g gamma : set gamma in kernel function (default 1/num_features)–核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/ k)
-r coef0 : set coef0 in kernel function (default 0)–核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)–设置C-SVC,e -SVR和v-SVR的参数(损失函数)(默认1)
-n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)–设置v-SVC,一类SVM和v- SVR的参数(默认0.5)
-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)–设置e -SVR 中损失函数p的值(默认0.1)
-m cachesize : set cache memory size in MB (default 100)–设置cache内存大小,以MB为单位(默认100)
-e epsilon : set tolerance of termination criterion (default 0.001)–设置允许的终止判据(默认0.001)
-h shrinking : whether to use the shrinking heuristics, 0 or 1 (default 1)–是否使用启发式,0或1(默认1)
-b probability_estimates : whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)
-wi weight : set the parameter C of class i to weight*C, for C-SVC (default 1)–设置第几类的参数C为weight*C(C-SVC中的C)(默认1)
-v n: n-fold cross validation mode–n-fold交互检验模式,n为fold的个数,必须大于等于2
-q : quiet mode (no outputs)

model.nr_class表示有多少类别,这里是二分类;
model.Label表示标签,这里是0、1;
model.totalSV代表总共的支持向量的数目;
model.nSV表示每类样本的支持向量的数目,与model.label相对应的;
rho偏移量-b;

SVM模型有两个非常重要的参数Cgamma。其中 C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。C过大或过小,泛化能力变差。
gamma是选择RBF函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度。

svmpredict函数用法:
[predict_label, accuracy, dec_values] =svmpredict(test_label, test_img_arr, model);
返回三个参数,predict_label为预测的类别,
accuracy有三个值,分别是分类准率(分类问题中用到的参数指标),平均平方误差(MSE (mean squared error)) [回归问题中用到的参数指标],平方相关系数(r2 (squared correlation coefficient))[回归问题中用到的参数指标];
dec_values,一个矩阵包含决策的值或者概率估计。对于n个预测样本、k类的问题,如果指定“-b 1”参数,则n x k的矩阵,每一行表示这个样本分别属于每一个类别的概率;如果没有指定“-b 1”参数,则为n x k*(k-1)/2的矩阵,每一行表示k(k-1)/2个二分类SVM的预测结果;
test_label为测试样本标签,如果未知,可以随意给定,但必须和test_img_arr维数对应,如果已知,则在计算accuracy的时候,会将predict_label与test_label进行比较求准确度(对于多个测试样本)。

在svmtrain的时候设置’-b 1’,svmpredict的时候设置’-b 1’,可以看到dec_values的值为每一个样本属于每一个类别的概率,我们看下第24个测试样本,正确分类应该是数字0,即应该分到第一类,其dec_values值最大的是0.5217属于第三类,即数字2,与predict_label相吻合。设置了’-b 1’后,model中的结果probA和probB不再为空,具体含义等弄明白了再更新。
这里写图片描述
这里写图片描述

参考:
http://blog.sina.com.cn/s/blog_6646924501018fqc.html
http://blog.csdn.net/bryan__/article/details/51506801

0 0