图像分类作为计算机视觉领域的一个重要问题,随着深度学习技术的快速发展,已经取得了显著的进展。卷积神经网络(CNN)模型被广泛应用于图像分类任务中,如GoogleNet(Szegedy et al., 2015)和ResNet(He et al., 2016)。GoogleNet的主要贡献是提出了Inception模块,通过多尺度卷积操作来增加网络的宽度(Szegedy et al., 2015)。ResNet则采用了残差连接,通过跨层连接的方式解决了深度网络的梯度消失问题,从而使网络可以加深(He et al., 2016)。这些卷积神经网络在多个知名数据集上取得了显著成果,如ImageNet(Deng et al., 2009)和CIFAR-10(Krizhevsky, 2009)。ImageNet是一个大规模视觉识别数据集,包含超过1400万张图片,涵盖了2万多个类别(Deng et al., 2009)。CIFAR-10则是一个小规模数据集,包含60000张32x32像素的彩色图片,分为10个类别(Krizhevsky, 2009)。
除了GoogleNet和ResNet,还有其他卷积神经网络模型在图像分类任务中取得了较好的成绩。例如,VGGNet(Simonyan and Zisserman, 2014)通过使用更小的卷积核(3x3)和更深的网络结构提高了分类性能。DenseNet(Huang et al., 2017)则引入了密集连接,将每一层的特征图与后续所有层进行连接,提高了信息流动性。为了更好地理解卷积神经网络的内部特征,Zeiler和Fergus(2014)提出了一种反卷积网络(DeconvNet),用于可视化各层的特征图。此外,为了防止过拟合,Hinton等人(2012)提出了Dropout方法;为了加速训练过程,Ioffe和Szegedy(2015)提出了Batch Normalization技术。
本章节目的是介绍一种基于深度神经网络的图像分类与训练系统,该系统使用MATLAB实现,并提供友好的图形用户界面,方便用户在不同的网络模型和数据集上进行实验。
在本节中,我们将介绍系统的图形用户界面(GUI)及其功能。该界面允许用户执行以下操作:
(1)选择图片分类:用户可以选择一张图片,系统将根据预训练的卷积神经网络模型对其进行分类,并显示预测结果。
(2)选择文件夹批量识别:用户可以选择一个文件夹,系统将对文件夹中的所有图片进行分类,并在预测完成后生成一个包含结果的列表和可视化展示。
(3)更换不同网络模型:用户可以在GoogleNet和ResNet等预训练模型之间进行切换,以便在不同模型上进行实验。
通过界面选择数据集训练一键训练模型:用户可以选择一个自定义的数据集文件夹,系统将自动训练一个新的卷积神经网络模型,并显示训练过程中的损失和准确率曲线。
在这一节详细阐述如何使用MATLAB实现基于ResNet-50的图像分类模型的训练过程。这里详细解释每个代码段的作用,以便于读者更好地理解模型的训练过程。
首先进行一些准备工作,包括清空MATLAB的环境变量、设置随机数生成器的种子以保证结果的可重复性、获取当前脚本所在的目录并将工作目录切换到该目录。这些操作有助于确保代码可以在不同的计算机上顺利运行。
clear
clc
rng default % 保证结果运行一致
mpath = matlab.desktop.editor.getActiveFilename; % 程序所在目录
[pathstr,~]=fileparts(mpath);
cd(pathstr); % 自动切换至程序所在目录
接下来,我们需要加载数据集,首先指定图像数据所在的目录。然后,使用checkDataset函数对数据集进行检查,以确保数据集中不存在灰度图像或二值图像。如果发现这些图像,就将它们从数据集中删除。使用每个子文件夹的名称作为图像的标签,以便于后续的训练和分类任务。
imgDir = fullfile("./10_ObjectCategories/");
file_list = checkDataset(imgDir); % 执行数据集检查
if isempty(file_list)
disp('未检查到灰度图或二值图')
else
disp('检查到灰度图或二值图, 以下文件已被删除')
disp(file_list)
end
dataSet = imageDatastore(imgDir, 'IncludeSubfolders', true, 'LabelSource', 'foldernames');
trainSetDetail = countEachLabel(dataSet) % 训练数据
数据集加载完成后,我们需要将其划分为训练集、验证集和测试集。这里采用随机划分的方法,将60%的数据作为训练集,20%的数据作为验证集,剩下的20%作为测试集。通过这种方式,可以确保模型在不同类型的数据上都能得到充分的训练和有效的评估。
[imdsTrain,imdsValidation, imdsTest] = splitEachLabel(dataSet, 0.6, 0.2, 'randomize'); % 划分数据集
为了直观展示训练数据,我们随机选择16个训练样本并将它们显示在一个图像中。这有助于了解数据集的大致情况和图像样本的特点。
numTrainImages = numel(imdsTrain.Labels);
idx = randperm(numTrainImages,16);
figure
for i = 1:16
subplot(4,4,i)
I = readimage(imdsTrain,idx(i));
imshow(I)
title(imdsTrain.Labels(idx(i)))
end
然后,我们需要加载一个预训练的ResNet-50模型。ResNet-50是一个具有50层的深度卷积神经网络,已在大型数据集上进行了预训练。通过使用预训练的模型,可以利用在其他数据集上学到的特征来加速训练过程并提高模型性能。
net = resnet50;
layers = net.Layers
inputSize = net.Layers(1).InputSize % 网络输入尺寸
加载预训练模型后,需要对其进行一些修改以适应分类任务。首先,需要替换模型中的全连接层,以适应数据集中的类别数量。接下来,需要替换模型中的分类层,使其与我们的任务相对应。这里采用新的全连接层和分类层来实现这一目的。
lgraph = layerGraph(net);
newLearnableLayer = fullyConnectedLayer(numClasses, ...
'Name','new_fc', ...
'WeightLearnRateFactor',10, ...
'BiasLearnRateFactor',10);
lgraph = replaceLayer(lgraph,'fc1000',newLearnableLayer);
newClassLayer = classificationLayer('Name','new_classoutput');
lgraph = replaceLayer(lgraph,'ClassificationLayer_fc1000',newClassLayer);
执行以上代码输出网络层情况如下:
layers =
具有以下层的 177×1 Layer 数组:
1 'input_1' 图像输入 224×224×3 图像: 'zerocenter' 归一化
2 'conv1' 卷积 64 7×7×3 卷积: 步幅 [2 2],填充 [3 3 3 3]
3 'bn_conv1' 批量归一化 批量归一化: 64 个通道
4 'activation_1_relu' ReLU ReLU
5 'max_pooling2d_1' 最大池化 3×3 最大池化: 步幅 [2 2],填充 [1 1 1 1]
6 'res2a_branch2a' 卷积 64 1×1×64 卷积: 步幅 [1 1],填充 [0 0 0 0]
7 'bn2a_branch2a' 批量归一化 批量归一化: 64 个通道
8 'activation_2_relu' ReLU ReLU
...
为了提高模型的泛化能力,我们在训练过程中使用数据增强技术。数据增强可以通过对训练图像进行随机变换(例如翻转、平移等)来生成更多的训练样本。这有助于模型在面对不同视角、尺度和形态的图像时具有更好的泛化能力。在本例中,采用随机水平翻转以及随机平移的方法进行数据增强。此外,还需要处理灰度图像。由于预训练的ResNet-50模型期望输入为彩色图像,需要将灰度图像转换为伪彩色图像,使其可以被模型正确处理。
pixelRange = [-30 30];
imageAugmenter = imageDataAugmenter( ...
'RandXReflection',true, ...
'RandXTranslation',pixelRange, ...
'RandYTranslation',pixelRange);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
'DataAugmentation',imageAugmenter, 'ColorPreprocessing','gray2rgb');
augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);
augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest);
在完成数据预处理和模型修改后,需要设置训练选项。这里,选择随机梯度下降法(SGDM)作为优化器,并设置批大小为32、最大迭代次数为2、初始学习率为1e-4。此外,还设置了每轮打乱训练数据的顺序、指定验证集以及验证频率等参数。最后,选择实时绘制训练进度曲线,以便于观察模型训练过程中的性能变化。
options = trainingOptions('sgdm', ...
'MiniBatchSize',32, ...
'MaxEpochs',2, ...
'InitialLearnRate',1e-4, ...
'Shuffle','every-epoch', ...
'ValidationData',augimdsValidation, ...
'ValidationFrequency',3, ...
'Verbose', true, ...
'Plots','training-progress');
接下来,使用修改后的模型和训练选项对训练集进行训练。在训练过程中,模型会根据设定的验证频率使用验证集对性能进行评估。这有助于了解模型在未知数据上的泛化能力。
model = trainNetwork(augimdsTrain,lgraph,options);
执行以上代码进行训练,训练的过程输出如下:
在单 GPU 上训练。
正在初始化输入数据归一化。
|=============================================================================|
| 轮 | 迭代 | 经过的时间 | 小批量准确度 | 验证准确度 | 小批量损失 | 验证损失 | 基础学习率 |
| | | (hh:mm:ss) | | | | | |
|=============================================================================|
| 1 | 1 | 00:00:03 | 9.38% | 8.82% | 2.3537 | 2.3766 | 1.0000e-04 |
| 1 | 3 | 00:00:06 | 9.38% | 21.24% | 2.2348 | 2.0908 | 1.0000e-04 |
| 1 | 6 | 00:00:09 | 43.75% | 53.51% | 1.6566 | 1.6016 | 1.0000e-04 |
| 1 | 9 | 00:00:11 | 62.50% | 67.13% | 1.3257 | 1.2302 | 1.0000e-04 |
| 1 | 12 | 00:00:14 | 68.75% | 71.94% | 1.1022 | 0.9980 | 1.0000e-04 |
| 1 | 15 | 00:00:17 | 87.50% | 78.56% | 0.5462 | 0.8436 | 1.0000e-04 |
...
训练完成后,将训练好的模型保存到文件中,以便于后续的使用和分析。
save('ResNet_10_classes.mat', 'model');
为了评估模型的性能,使用测试集进行分类。通过将模型预测的结果与真实标签进行比较,可以计算出模型在测试集上的准确率。这是衡量模型性能的一个重要指标。
[YPred,scores] = classify(model, augimdsTest);
YTest = imdsTest.Labels;
accuracy = mean(YPred == YTest)
为了更直观地展示模型的预测效果,随机选择四个测试样本并将它们显示在一个图像中。这有助于直观地了解模型在不同类型图像上的预测效果。
idx = randperm(numel(imdsTest.Files),4);
figure
for i = 1:4
subplot(2,2,i)
I = readimage(imdsTest,idx(i));
imshow(I)
label = YPred(idx(i));
title(string(label));
end
最后,绘制混淆矩阵以展示模型在各个类别上的性能。混淆矩阵是一种常用的可视化方法,可以直观地显示模型在不同类别上的正确分类和误分类情况。通过混淆矩阵,可以进一步分析模型在哪些类别上表现较好,以及在哪些类别上存在改进空间。
figure
plotconfusion(imdsTest.Labels, YPred); % 绘制混淆矩阵图
本节介绍如何在MATLAB中实现图像分类与训练系统的设计:该系统将分为两个部分,第一部分是预测部分,负责选择图片、文件夹分类和更换模型;第二部分是训练部分,负责选择数据集、设置训练参数、一键训练模型并评估。将结合GUI界面展示系统的设计框架和实现方法。
在本图像分类与训练系统中,可以通过一个技术逻辑图来概括整个系统的结构和工作流程。以下是技术逻辑图的文字描述:
5. 总结与展望
本博客介绍了基于深度神经网络的图像分类与训练系统(MATLAB实现)。从引言开始,介绍基于GoogleNet、ResNet进行图像分类的背景、意义,系统研究现状及相关算法。随后,展示了系统的界面演示效果,包括选择图片分类、选择文件夹批量识别、更换不同网络模型和通过界面选择数据集一键训练模型等功能。在第三节中,详细介绍了神经网络训练的过程,包括训练代码、训练曲线和模型评估结果。第四节讲述了系统实现的两个部分:预测部分和训练部分,结合GUI界面给出了设计框架和实现。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删