Matlab 2022版CNN-LSTM图像分类模型搭建教程:猫狗二分类数据集实战,附程序与图像文件
Matlab深度学习,使用CNN-LSTM进行图像分类。 如何在Matlab中搭建CNN-LSTM也是曾经困扰本人挺长时间的问题。 数据可换成自己的数据。 注意:需要Matlab 2022版本,2021不确定行不行,2020以下肯定是不行。 工作如下: 1、数据集为猫狗二分类数据集,共1000张图像。 按4:1比例随机划分训练集和测试集,训练集为400只猫400只狗,测试集为100只猫和100只狗。 2、搭建CNN-LSTM网络。 3、训练。 4、测试,输出准确率,画出混淆矩阵。 注:本程序只是帮助大家参考如何在Matlab中搭建CNN-LSTM模型,用的卷积核数量很少,LSTM隐含单元数目也非常少,故本实验结果较差。 如需要提高准确率可有偿作修改。 程序包括程序和图像文件,可直接运行 注释详细,可自行修改各个层以提高准确率。

最近在折腾Matlab的CNN-LSTM图像分类,发现网上的教程不是太老就是跑不通。自己踩了半个月坑终于搞定了基础版,虽然准确率有点拉胯(毕竟为了演示随便搭的结构),但好歹能跑起来给各位打个样。

先看数据准备部分。猫狗各500张直接塞进ImageDatastore,注意文件路径的猫狗分类得用不同文件夹存好:
imds = imageDatastore('pet_images','IncludeSubfolders',true,'LabelSource','foldernames');
[imdsTrain,imdsTest] = splitEachLabel(imds,0.8,'randomized');
这里有个坑:Matlab的splitEachLabel如果数据量少可能会分不匀,建议用countEachLabel检查下分布。如果发现训练集猫狗数量不对,得手动调整随机种子重分。

网络结构才是重头戏。咱们用CNN抽特征,再把特征序列喂给LSTM。注意输入层必须用sequenceInputLayer,卷积层后面要接sequenceFolding强制转序列:
layers = [
sequenceInputLayer([227 227 3],'Name','input') % 输入必须带sequence
convolution2dLayer(3,8,'Padding','same','Name','conv1')
batchNormalizationLayer('Name','bn1')
reluLayer('Name','relu1')
maxPooling2dLayer(2,'Stride',2,'Name','pool1')
sequenceFoldingLayer('Name','fold') % 关键转换层
lstmLayer(32,'OutputMode','last','Name','lstm')
fullyConnectedLayer(2,'Name','fc')
softmaxLayer('Name','softmax')
classificationLayer('Name','classOutput')];
这里lstmLayer的OutputMode要设成'last',因为咱们是要整个序列的最终状态做分类。如果遇到维度报错,八成是sequenceFolding的位置没放对,得确保卷积操作在折叠之前完成。

Matlab深度学习,使用CNN-LSTM进行图像分类。 如何在Matlab中搭建CNN-LSTM也是曾经困扰本人挺长时间的问题。 数据可换成自己的数据。 注意:需要Matlab 2022版本,2021不确定行不行,2020以下肯定是不行。 工作如下: 1、数据集为猫狗二分类数据集,共1000张图像。 按4:1比例随机划分训练集和测试集,训练集为400只猫400只狗,测试集为100只猫和100只狗。 2、搭建CNN-LSTM网络。 3、训练。 4、测试,输出准确率,画出混淆矩阵。 注:本程序只是帮助大家参考如何在Matlab中搭建CNN-LSTM模型,用的卷积核数量很少,LSTM隐含单元数目也非常少,故本实验结果较差。 如需要提高准确率可有偿作修改。 程序包括程序和图像文件,可直接运行 注释详细,可自行修改各个层以提高准确率。

训练配置别手贱开太大batchsize,显存分分钟爆炸。建议先用小学习率试水:
options = trainingOptions('adam',...
'ExecutionEnvironment','auto',...
'MiniBatchSize',16,...
'MaxEpochs',10,...
'InitialLearnRate',1e-4,...
'Shuffle','every-epoch');
开训后如果看到loss曲线像心电图,可以试试在卷积层后加dropout。不过注意Matlab的dropout层在序列处理时可能会引发维度错误,这时候得换成spatialDropout2dLayer。
测试阶段要特别注意数据预处理的一致性。有个邪门bug是验证时自动resize和训练时不一致,建议强制指定:
augimdsTest = augmentedImageDatastore([227 227],imdsTest,'ColorPreprocessing','rgb2gray');
predLabels = classify(net,augimdsTest);
accuracy = sum(predLabels == imdsTest.Labels)/numel(imdsTest.Labels)
混淆矩阵画起来倒是简单,但记得把类别顺序固定住,不然猫狗标签可能会反转:
confMat = confusionmat(imdsTest.Labels,predLabels);
confusionchart(confMat,{'cat','dog'})
跑完大概能到60%左右的准确率——确实不咋地,毕竟卷积核只用了8个,LSTM单元也才32个。想要提升的话,可以试试这些魔改方案:
- 把卷积核堆到64+,加残差连接
- LSTM换成biLSTM,单元数提到128
- 在全连接前插globalAveragePooling2dLayer
- 数据增强里加随机旋转和颜色抖动
改的时候注意:每加一层都要算清楚输出维度,Matlab的维度报错信息堪比天书。曾经因为忘了调整sequenceFolding的位置,生生折腾了两天...
完整代码已打包,解压后注意把图像路径改成自己的存放位置。环境变量设不对的话,可能会报什么"无法读取JPEG文件头"的错,这种情况建议用imread先检查下图片是否损坏。
最后说句实在话,真要搞实战还是建议用Python,Matlab的深度学习工具箱在自定义结构时还是有点笨重。不过对于习惯Simulink的朋友来说,这个方案倒是个不错的过渡选择。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)