MATLAB实现手写体0-9数字识别
一、系统架构设计
graph TD
A[数据采集] --> B(预处理)
B --> C{特征提取}
C --> D[传统方法]
C --> E[深度学习]
D --> F[KNN/SVM分类]
E --> G[CNN分类]
F --> H[识别结果]
G --> H
二、核心实现步骤
1. 数据准备与预处理
% 加载MNIST数据集(MATLAB内置)
[XTrain, YTrain] = digitTrain4DArrayData; % 60,000训练样本
[XTest, YTest] = digitTest4DArrayData; % 10,000测试样本
% 数据归一化
XTrain = double(XTrain)/255;
XTest = double(XTest)/255;
% 转换为图像矩阵
trainImages = reshape(XTrain, 28, 28, 1, []);
testImages = reshape(XTest, 28, 28, 1, []);
2. 传统机器学习方法
2.1 特征提取(HOG特征)
% 提取HOG特征
hogFeatureSize = 36; % 9 bins × 4 cells
trainFeatures = extractHOGFeatures(trainImages, 'CellSize', [7 7]);
testFeatures = extractHOGFeatures(testImages, 'CellSize', [7 7]);
2.2 分类器训练
% KNN分类器
mdlKNN = fitcknn(trainFeatures, YTrain, 'NumNeighbors', 5, 'Standardize', true);
% SVM分类器
mdlSVM = fitcecoc(trainFeatures, YTrain, 'Learners', 'linear', 'Coding', 'onevsall');
三、深度学习方法(CNN)
1. 网络结构设计
layers = [
imageInputLayer([28 28 1]) % 输入层
convolution2dLayer(3, 8, 'Padding', 'same') % 卷积层1
batchNormalizationLayer()
reluLayer()
maxPooling2dLayer(2, 'Stride', 2)
convolution2dLayer(3, 16, 'Padding', 'same') % 卷积层2
batchNormalizationLayer()
reluLayer()
maxPooling2dLayer(2, 'Stride', 2)
fullyConnectedLayer(64) % 全连接层
reluLayer()
fullyConnectedLayer(10) % 输出层
softmaxLayer()
classificationLayer()]; % 分类层
2. 模型训练
options = trainingOptions('adam',...
'MaxEpochs', 15,...
'MiniBatchSize', 64,...
'InitialLearnRate', 0.001,...
'Shuffle', 'every-epoch',...
'Verbose', false);
net = trainNetwork(trainImages, YTrain, layers, options);
四、性能评估
1. 测试集验证
predictedLabels = classify(net, testImages);
accuracy = sum(predictedLabels == YTest)/numel(YTest);
fprintf('测试集准确率: %.2f%%
', accuracy*100);
2. 混淆矩阵分析
plotconfusion(YTest, predictedLabels);
title('混淆矩阵分析');
五、优化
1. 数据增强
augmentedTrainingSet = imageDataAugmenter(...
'RandRotation', [-10 10],...
'RandXReflection', true,...
'RandYReflection', true);
augmentedData = augmentedTrainingSet(XTrain);
2. 迁移学习
net = alexnet;
lgraph = layerGraph(net);
newFCLayer = fullyConnectedLayer(10, 'Name', 'new_fc');
newClassLayer = classificationLayer('Name', 'new_classoutput');
lgraph = replaceLayer(lgraph, 'fc1000', newFCLayer);
lgraph = replaceLayer(lgraph, 'ClassificationLayer_fc1000', newClassLayer);
net = trainNetwork(XTrain, YTrain, lgraph, options);
六、工程实现方案
1. 交互式GUI设计(App Designer)
% 创建手写输入界面
fig = uifigure('Name', '手写数字识别');
ax = uiaxes(fig, 'Position', [0.1 0.3 0.8 0.6]);
btn = uibutton(fig, 'Text', '识别', 'Position', [0.4 0.1 0.2 0.1],...
'ButtonPushedFcn', @(btn,event) recognizeDigit());
% 实时绘制手写轨迹
ax.XTick = [];
ax.YTick = [];
ax.XColor = 'w';
ax.YColor = 'w';
hold(ax, 'on');
currentPoint = [0,0];
% 鼠标事件回调
function mouseMoved(~, event)
currentPoint = [event.Position(1), event.Position(2)];
plot(ax, currentPoint(1), currentPoint(2), 'r.', 'MarkerSize', 20);
end
2. 移动端部署
% 生成Android应用
mcc -m HandwritingRecognition -a assets -d compiled;
七、完整代码仓库
% 主程序文件: digitRecognition.m
% 数据加载: loadMNISTData.m
% 特征提取: extractFeatures.m
% 模型训练: trainModels.m
% 测试评估: evaluatePerformance.m
八、参考
- MathWorks官方示例: Digit Classification Using HOG Features https://ww2.mathworks.cn/help/deeplearning/examples/digit-classification-using-hog-features.html
- 参考代码 识别手写体0-9的数字 www.youwenfan.com/contentcso/78288.html
- 周志华《机器学习》第5章支持向量机