日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于支持向量机的手写数字识别详解(MATLAB GUI代码,提供手写板)

發布時間:2024/5/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于支持向量机的手写数字识别详解(MATLAB GUI代码,提供手写板) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要:本文詳細介紹如何利用MATLAB實現手寫數字的識別,其中特征提取過程采用方向梯度直方圖(HOG)特征,分類過程采用性能優異的支持向量機(SVM)算法,訓練測試數據集為學術及工程上常用的MNIST手寫數字數據集,博主為SVM設置了合適的核函數,最終的測試準確率達99%的較高水平。根據訓練得到的模型,利用MATLAB GUI工具設計了可以手寫輸入或讀取圖片進行識別的系統界面,同時可視化圖片處理過程及識別結果。本套代碼集成了眾多機器學習的基礎技術,適用性極強(用戶可修改圖片文件夾實現自定義數據集訓練),相信會是一個非常好的學習Demo。本博文目錄如下:

文章目錄

  • 前言
  • 1. 效果演示
  • 2. MNIST數據集
  • 3. HOG特征提取
  • 4. 訓練和評估SVM分類器
  • 下載鏈接
  • 結束語

?點擊跳轉至文末所有涉及的完整代碼文件下載頁?

代碼介紹及演示視頻鏈接:https://www.bilibili.com/video/BV1km4y1R7qf/(正在更新中,歡迎關注博主B站視頻)


前言

????機器學習中支持向量機(SVM)算法可謂是個超級經典,也許很多人傾向于使用深度神經網絡解決問題,但在博主看來選擇何種算法應該取決于具體的機器學習任務,對于復雜程度不高、數據量較少的任務,也許經典的機器學習算法能夠更好地解決問題。手寫數字識別這一任務要求正確分類出0-9的手寫數字圖片,最常用的數據集是MNIST,該數據集也是眾多論文中經常用來測試對比算法的對象。博主想說的是其實SVM也可以很好地解決這一問題,本文介紹的代碼就可以實現99%的測試準確率,所以想借此為大家提供一個學習的Demo共同交流。

????博主之前也曾寫過兩篇利用SVM進行分類的博文:基于支持向量機的圖像分類(上篇)和基于支持向量機的圖像分類(下篇:MATLAB實現),詳細介紹了特征提取的基本技術和支持向量機的原理,亦可供大家參考。本文給出了MATLAB實現的完整代碼供大家參考,有基礎的讀者可按照文中的介紹復現出完整程序;對于想獲取全部數據集及程序文件的朋友,可以點擊提供的下載鏈接獲取可直接運行的代碼,原創不易,還請多多支持了。如本文對您有所幫助,敬請點贊、收藏、關注!


1. 效果演示

????找資料的大伙時間寶貴,為了方便大家了解項目,我們老規矩先上效果演示,GUI界面有幾個主要功能:通過手寫板寫入數字進行識別;利用文件瀏覽器選取一張手寫數字的圖片進行識別;同步可視化處理過程中的圖像,顯示最終識別結果。GUI界面如下:


????在手寫板中寫入數字后可點擊下方保存按鈕保存為圖片文件,手寫輸入及讀圖輸入及保存功能的演示動圖如下圖所示。右側為圖像原圖、灰度化處理、二值化處理及特征提取后的圖像,方便了解識別的處理過程:


????本項目所有功能均已在MATLAB R2020b中測試通過,更多演示細節敬請前往博主B站觀看演示視頻,視頻具體演示程序運行效果并介紹如何使用代碼,歡迎關注!


2. MNIST數據集

????MNIST數據集來自美國國家標準與技術研究所(National Institute of Standards and Technology, NIST)。訓練集 (Training Set) 由來自250個不同人手寫的數字構成,其中50%是高中學生,50%來自人口普查局的工作人員;測試集(Test Set) 也是同樣比例的手寫數字數據。


????MNIST數據集可在 http://yann.lecun.com/exdb/mnist/獲取,但由于訪問外網下載速度很慢,博主已將該數據集打包上傳至百度網盤,大家可以通過博主前面發布的博文:深度學習常用數據集介紹與下載(附網盤鏈接)進行下載。MNIST數據集包含了四個部分:

  • Training set images:train-images-idx3-ubyte.gz (9.9MB,解壓后47MB,包含60000個樣本)
  • Training set labels:train-labels-idx1-ubyte.gz(29KB,解壓后60KB,包含60000個標簽)
  • Test set images:t10k-images-idx3-ubyte.gz (1.6MB,解壓后7.8MB,包含10000個樣本)
  • Test set labels: t10k-labels-idx1-ubyte.gz(5KB,解壓后10KB,包含10000個標簽)

????將下載后的數據集文件放在一個文件夾下,用于后續處理,MNIST數據集文件如下圖所示:


????由于MNIST的原始文件并非常見的圖片格式,因此為了方便后續處理,我們先將這幾個文件轉化為mat文件,然后逐個讀取轉換為圖像矩陣并保存為圖片文件。值得注意的是,我們需按照每條樣本數據的標簽將其分別放置在不同的文件夾中,如下方式在train文件夾中創建0-9的文件夾用來存放要寫入的對應標簽的圖片:


????這里寫一個小腳本將數據集圖片按標簽存入對應文件夾中,其中的mat文件為讀取原始數據并轉存后的數據集,MNIST每張圖片的尺寸均為28×28,所以可以先通過reshape恢復數據尺寸,然后利用imwrite函數寫入文件中(路徑為對應標簽的子文件夾),該部分代碼如下:

clear clc % P = loadMNISTImages('mnist/train-images.idx3-ubyte'); % T = loadMNISTLabels('mnist/train-labels.idx1-ubyte'); load('test_data.mat', 'test_X') load('test_label.mat', 'test_Y') load('train_data.mat', 'train_X') load('train_label.mat', 'train_Y') load('validation_data.mat', 'validation_X') load('validation_label.mat', 'validation_Y') % 遍歷每張圖片 disp('現在將訓練數據保存為圖片文件格式') for i = 1:length(train_X)img = reshape(train_X(i, :), 28, 28); % 轉換成28*28的圖片img = img';imwrite(img, ['./mnist/train/', int2str(train_Y(i)), '/', int2str(i), '.jpg']);disp(i); end % 遍歷每張圖片 disp('現在將測試數據保存為圖片文件格式') for i = 1:length(test_X)img = reshape(test_X(i, :), 28, 28); % 轉換成28*28的圖片img = img';imwrite(img, ['./mnist/test/', int2str(test_Y(i)), '/', int2str(i), '.jpg']);disp(i); end

????處理后的子文件夾中將存放對應的圖片文件,其中兩個子文件夾的截圖如下圖所示:


????數據集準備完畢,現在可以通過文件夾讀取圖片了。在MATLAB中可使用imageDatastore函數方便地批量讀取圖片集,它通過遞歸掃描文件夾目錄,將每個文件夾名稱自動作為圖像的標簽,該部分代碼如下:

% 給出訓練和測試數據路徑,利用imageDatastore載入數據集 syntheticDir = fullfile('data','mnist', 'train'); handwrittenDir = fullfile('data','mnist', 'test');% imageDatastore遞歸掃描目錄,將每個文件夾名稱自動作為圖像的標簽 trainSet = imageDatastore(syntheticDir, 'IncludeSubfolders', true, 'LabelSource', 'foldernames'); testSet = imageDatastore(handwrittenDir, 'IncludeSubfolders', true, 'LabelSource', 'foldernames');

????至此訓練和測試數據集分別被存放在trainSet、testSet變量中,可以簡單查看訓練和測試集每類標簽的樣本個數,顯示代碼如下:

trainSetDetail = countEachLabel(trainSet) % 訓練數據 testSetDetail = countEachLabel(testSet) % 測試數據

????執行以上代碼運行結果如下:


????下面讀取幾張訓練和測試集的圖片,顯示原始圖片幫助我們清楚該數據集的實際情況,按照兩行顯示:第一行為訓練圖片,第二行為測試圖片,該部分代碼如下:

figure; % 顯示訓練、測試圖片(第一行是訓練圖片、第二行是測試圖片) subplot(2,5,1);imshow(trainSet.Files{4417}); subplot(2,5,2);imshow(trainSet.Files{23696}); subplot(2,5,3);imshow(trainSet.Files{31739}); subplot(2,5,4);imshow(trainSet.Files{46740}); subplot(2,5,5);imshow(trainSet.Files{54784}); subplot(2,5,6);imshow(testSet.Files{53}); subplot(2,5,7);imshow(testSet.Files{4572}); subplot(2,5,8);imshow(testSet.Files{5163}); subplot(2,5,9);imshow(testSet.Files{8381}); subplot(2,5,10);imshow(testSet.Files{9549});

????執行該代碼可以看到如下的運行結果:


????在提取特征前我們對圖片進行一些必要的預處理操作,首先讀取圖片后進行灰度化,然后進行二值化處理,以方便后續的特征提取。這里我們將原始圖片和二值化后的圖像顯示在一個窗口中,其代碼如下:

exampleImage = readimage(trainSet, 31739); if numel(size(exampleImage))==3exampleImage = rgb2gray(exampleImage); % 灰度化圖片 endprocessedImage = imbinarize(exampleImage);figure; subplot(1,2,1) imshow(exampleImage) title('原始圖像')subplot(1,2,2) imshow(processedImage) title('二值化后圖像')

????執行該代碼可以看到如下的原始圖像與二值化后的對比結果:


3. HOG特征提取

????真正用于訓練分類器的數據并不是原始圖片數據,而是先經過特征提取后得到的特征向量,這里使用的特征類型是HOG,也就是方向梯度直方圖。所以這里重要的一點是正確提取出HOG特征,extractHOGFeaturesMATLAB自帶的HOG特征提取函數,該函數不僅可以有效提取特征,還可以返回特征的可視化結果以方便展示。這里通過調整每個細胞單元的尺寸大小實現不同尺寸的特征提取,可以通過可視化的結果看到細胞單元的尺寸對圖像的形狀信息量的影響:

img = readimage(trainSet, 31739);% 提取HOG特征,并進行HOG可視化 [hog_2x2, vis2x2] = extractHOGFeatures(img,'CellSize',[2 2]); [hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',[4 4]); [hog_8x8, vis8x8] = extractHOGFeatures(img,'CellSize',[8 8]);% 顯示原始圖片 figure; subplot(2,3,1:3); imshow(img); title('原始圖片');% 可視化HOG特征 subplot(2,3,4); plot(vis2x2); title({'CellSize = [2 2]'; ['Length = ' num2str(length(hog_2x2))]});subplot(2,3,5); plot(vis4x4); title({'CellSize = [4 4]'; ['Length = ' num2str(length(hog_4x4))]});subplot(2,3,6); plot(vis8x8); title({'CellSize = [8 8]'; ['Length = ' num2str(length(hog_8x8))]});

????通過以上代碼我們分別提取了2×2、4×48×8三種尺寸的HOG特征,其運行的可視化結果如下:

????從以上結果可以看出2×2的細胞尺寸會編碼更多的形狀信息,這會顯著增加HOG特征向量的維數,相反8×8的細胞尺寸得到的特征量最少。這其實是一個需要調試的參數,一方面應該對足夠的空間信息進行編碼,另一方面需要減少HOG特征向量的維數,為此可以選擇4×4的細胞大小。當然讀者還可以通過反復根據分類器訓練和測試的效果來調整HOG特征的相關參數,以實現最佳參數設置。


4. 訓練和評估SVM分類器

????下面我們使用以上提取的HOG特征訓練支持向量機,以上的代碼只是提取了一張圖片的特征,訓練前我們對整個訓練數據集提取HOG特征并組合,為了方便后面的性能評估,這里對測試數據集也進行特征提取:

cellSize = [4 4]; hogFeatureSize = length(hog_4x4);% 提取HOG特征 tStart = tic; [trainFeatures, trainLabels] = extractHogFromImageSet(trainSet, hogFeatureSize, cellSize); % 訓練集特征提取 [testFeatures, testLabels] = extractHogFromImageSet(testSet, hogFeatureSize, cellSize); % 測試集特征提取tEnd = toc(tStart); fprintf('提取特征所用時間:%.2f秒\n', tEnd);

????由于圖片數量眾多,提取特征過程尚需一定時間,這里對訓練集、測試集提取過程進行計時,因計算機算力不同,執行時間可能會不一致。以下代碼中extractHogFromImageSet函數為自定義函數,封裝了前面所提到的圖像灰度化、二值化和HOG特征提取的代碼,可以方便我們復用代碼,使得程序更加簡潔。

cellSize = [4 4]; hogFeatureSize = length(hog_4x4);% 提取HOG特征 tStart = tic; [trainFeatures, trainLabels] = extractHogFromImageSet(trainSet, hogFeatureSize, cellSize); % 訓練集特征提取 [testFeatures, testLabels] = extractHogFromImageSet(testSet, hogFeatureSize, cellSize); % 測試集特征提取tEnd = toc(tStart); fprintf('提取特征所用時間:%.2f秒\n', tEnd);

????運行以上代碼結果如下:

提取特征所用時間:181.59秒

????構建支持向量機模型,利用提取的訓練集特征進行訓練。首先利用templateSVM函數構建支持向量機模板參數,選擇polynomial核函數,執行標準化處理數據,顯示訓練過程;利用fitcecoc函數執行訓練過程,其代碼如下:

% 訓練支持向量機t = templateSVM('SaveSupportVectors',true, 'Standardize', true, 'KernelFunction','polynomial', ...'KernelScale', 'auto','Verbose', 1); % 利用polynomial核函數, 標準化處理數據,顯示訓練過程(verbose取0時取消顯示)tStart = tic; % 計時開始 classifier = fitcecoc(trainFeatures, trainLabels, 'Learner', t); % 訓練SVM模型 tEnd = toc(tStart); fprintf('訓練模型所用時間:%.2f秒\n', tEnd);

????以上代碼開啟了訓練過程信息顯示,訓練過程中顯示信息如下:

訓練模型所用時間:104.96秒

????等待訓練完成,我們可以使用訓練好的分類器進行預測,這里先利用測試集評估模型并計算分類評價指標,對測試集進行預測的代碼如下:

tStart = tic;% 對測試數據集進行預測 predictedLabels = predict(classifier, testFeatures);tEnd = toc(tStart); fprintf('模型對測試集進行預測所用時間:%.2f秒\n', tEnd);

????運行結果如下:

模型對測試集進行預測所用時間:5.18秒

????得到了預測結果,可以使用混淆矩陣評估結果,以下代碼首先計算混淆矩陣結果,然后將結果打印出來:

% 使用混淆矩陣評估結果 confMat = confusionmat(testLabels, predictedLabels); dispConfusionMatrix(confMat); % 顯示混淆矩陣

????運行結果如下:


????以上代碼顯示了混淆矩陣的結果,但可能還不夠直觀,下面繪制混淆矩陣圖幫助更好了解模型性能:

% 繪制混淆矩陣圖 plotconfusion(testLabels, predictedLabels);

????運行代碼后顯示混淆矩陣圖如下圖所示,每行對角線上的網格(綠色網格)處顯示了某類樣本預測正確的數目及其占比。右下角網格表示分類的準確率,可以看出該分類器具有98.9%的總體分類準確率。

????分類準確率還可以通過以下代碼進行計算:

accuracy = sum(predictedLabels == testLabels) / numel(testLabels); fprintf('模型在測試集上的準確率:%.0f%%\n', accuracy*100);

????同樣可以計算出預測的準確率,這里四舍五入取整可得以下結果:

模型在測試集上的準確率:99%

????通過測試集評估結果,可以看出采用核函數的支持向量機準確率為99%,其性能已逼近深度卷積神經網絡。得到了一個性能優良的分類器,接下來便可以利用模型設計一些有意思的東西了。為此我將該模型用于實際的手寫數字識別中,以下是在MATLAB GUI工具中設計的界面,如若讀者反響熱烈,后期將很快更GUI的設計介紹,還請關注了!


下載鏈接

????若您想獲得博文中涉及的實現完整全部程序文件(包括數據集,m, UI文件等,如下圖),這里已打包上傳至博主的面包多平臺,具體可見參考文章和視頻,已將所有涉及的文件同時打包到里面,點擊即可運行,完整文件截圖如下:

注意:本資源已經過調試通過,下載后可通過MATLAB R2020b運行;訓練主程序為main_showData.mlxDigitClassify_HOG_SVM.m文件,測試程序可運行testImage.mlx,要使用GUI界面請運行DigitClassifyUI.m文件(腳本文件可直接運行);其它程序文件大部分為函數而非可直接運行的腳本,使用時請勿直接點擊運行!???

參考文章:https://www.cnblogs.com/sixuwuxian/p/16163545.html

參考視頻:https://www.bilibili.com/video/BV1km4y1R7qf/


結束語

????由于博主能力有限,博文中提及的方法即使經過試驗,也難免會有疏漏之處。希望您能熱心指出其中的錯誤,以便下次修改時能以一個更完美更嚴謹的樣子,呈現在大家面前。同時如果有更好的實現方法也請您不吝賜教。如果本博文反響較好,其界面部分也將在下篇博文中介紹,所有涉及的GUI界面程序也會作細致講解,敬請期待!

總結

以上是生活随笔為你收集整理的基于支持向量机的手写数字识别详解(MATLAB GUI代码,提供手写板)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。