一、系统设计
% 主程序流程
1. 数据加载与预处理
2. BP神经网络模型构建
3. 网络训练与参数优化
4. 测试集验证与性能评估
5. GUI交互界面开发
二、核心代码实现
1. 数据预处理(MNIST数据集)
matlab
%% 加载MNIST数据集
load('mnist.mat'); % 包含train_images, train_labels, test_images, test_labels
% 数据归一化(0-1范围)
train_data = double(train_images)/255;
test_data = double(test_images)/255;
% 标签one-hot编码
train_labels = ind2vec(train_labels' + 1);
test_labels = ind2vec(test_labels' + 1);
% 数据集划分(80%训练,20%验证)
cv = cvpartition(size(train_data,2),'HoldOut',0.2);
val_data = train_data(:,cv.test);
val_labels = train_labels(:,cv.test);
train_data = train_data(:,cv.training);
train_labels = train_labels(:,cv.training);
2. BP神经网络模型构建
matlab
%% 网络参数设置
input_neurons = 784; % 输入层(28x28)
hidden_neurons = 128; % 隐藏层
output_neurons = 10; % 输出层(0-9)
%% 创建网络结构
net = patternnet(hidden_neurons);
% 设置训练参数
net.trainParam.epochs = 500; % 最大迭代次数
net.trainParam.lr = 0.01; % 学习率
net.trainParam.goal = 1e-5; % 目标误差
net.trainParam.showWindow = false; % 关闭训练窗口
% 自适应学习率调整
net.trainParam.lr_inc = 1.05; % 误差下降时增加学习率
net.trainParam.lr_dec = 0.7; % 误差上升时减少学习率
% 激活函数配置
net.layers{1}.transferFcn = 'logsig'; % 隐藏层Sigmoid
net.layers{2}.transferFcn = 'softmax';% 输出层Softmax
3. 网络训练与优化
matlab
%% 交叉验证优化
k = 5; % 5折交叉验证
best_acc = 0;
best_hidden = 0;
for hidden = [64,128,256]
cv = cvpartition(size(train_data,2),'KFold',k);
acc = zeros(k,1);
for i = 1:k
% 划分训练/验证集
trainIdx = cv.training(i);
valIdx = cv.test(i);
% 训练网络
net = train(net, train_data(:,trainIdx), train_labels(:,trainIdx));
% 验证准确率
outputs = net(val_data(:,valIdx));
[~,pred] = max(outputs);
acc(i) = mean(pred == find(train_labels(:,valIdx)));
end
% 更新最佳参数
mean_acc = mean(acc);
if mean_acc > best_acc
best_acc = mean_acc;
best_hidden = hidden;
end
end
% 使用最佳参数重新训练
net = patternnet(best_hidden);
net = train(net, train_data, train_labels);
4. 测试与评估
matlab
%% 测试集预测
outputs = net(test_data);
[~,pred] = max(outputs);
[~,true] = max(test_labels);
%% 性能指标计算
accuracy = mean(pred == true);
confusion = confusionmat(true, pred);
class_acc = diag(confusion)/sum(confusion,2);
%% 可视化结果
figure;
subplot(2,1,1);
bar(class_acc*100);
title('分类准确率(%)');
xlabel('数字类别');
ylabel('准确率');
ylim([80 100]);
subplot(2,1,2);
confusionchart(true, pred);
title('混淆矩阵');
三、GUI界面开发
matlab
%% 创建交互界面
function digit_recognition_gui
f = uifigure('Name','手写数字识别系统','Position',[100,100,800,600]);
% 输入区域
ax_input = uiaxes(f,'Position',[0.1,0.3,0.4,0.6]);
title(ax_input,'手写数字区域');
img = zeros(28,28);
imgPlot = imagesc(ax_input,img,'k');
colormap(ax_input,gray);
% 控制按钮
btn_clear = uibutton(f,'Text','清除','Position',[600,450,100,30],...
'ButtonPushedFcn',@(btn,event) clearCanvas(img,imgPlot));
btn_recognize = uibutton(f,'Text','识别','Position',[600,400,100,30],...
'ButtonPushedFcn',@(btn,event) recognizeDigit(img,net));
btn_exit = uibutton(f,'Text','退出','Position',[600,350,100,30],...
'ButtonPushedFcn',@(btn,event) delete(f));
% 结果显示
uilabel(f,'Text','识别结果:','Position',[600,300,150,22],...
'FontSize',14,'FontWeight','bold');
resultLabel = uilabel(f,'Text','','Position',[600,270,150,22],...
'FontSize',16,'FontColor',[0,0.5,0]);
%% 回调函数
function clearCanvas(img,imgPlot)
img(:,:) = 0;
refresh(imgPlot);
resultLabel.Text = '';
end
function recognizeDigit(img,net)
% 图像预处理
img = imresize(img, [28,28]);
img = double(img > 0.5); % 二值化
input = img(:)';
% 网络预测
output = net(input);
[~,idx] = max(output);
resultLabel.Text = sprintf('识别结果: %d (%.1f%%)', idx-1, max(output)*100);
end
end
四、应用扩展
- 实时手写识别 集成到移动端APP(通过MATLAB Compiler) 支持触摸屏输入和实时反馈
- 多语言扩展 添加汉字识别模块(需扩展数据集至3755个字符)
- 异常检测 基于重构误差的异常书写检测(使用Autoencoder)
五、参考
- LeCun Y, Cortes C, Burges C J. MNIST handwritten digit database[R]. AT&T Labs, 2010.
- 代码 基于matlab利用BP神经网络开发的手写数字识别 www.youwenfan.com/contentcsn/79993.html
- MathWorks. Deep Learning Toolbox User's Guide, 2023.
- 刘建伟, 刘媛. 基于BP神经网络的数字识别系统设计[J]. 计算机应用研究, 2018.