1. 程式人生 > >matlab 使用libsvm工具箱進行手寫數字識別

matlab 使用libsvm工具箱進行手寫數字識別

上一篇講到如何在matlab中新增libsvm工具箱,svm的理論就不做介紹了,接下來進行手寫數字識別,本文使用svm進行0、1手寫數字二分類,多分類情況與其類似。
1、識別過程
下載mnist手寫數字影象集,分別選取其中的0、1的500張作為訓練資料,另外的100張作為測試資料,程式如下:

clear;clc;

% train
train_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,不然會報錯 end model = 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);
% test test_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不再為空,具體含義等弄明白了再更新。
這裡寫圖片描述
這裡寫圖片描述