MATLAB GUI版深度神经网络图像分类与训练详解

1. 引言

图像分类作为计算机视觉领域的一个重要问题,随着深度学习技术的快速发展,已经取得了显著的进展。卷积神经网络(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实现,并提供友好的图形用户界面,方便用户在不同的网络模型和数据集上进行实验。

  1. 提供一个基于MATLAB的图像分类与训练系统,支持多种卷积神经网络模型,如GoogleNet和ResNet。
  2. 系统提供友好的图形用户界面,支持选择图片分类、选择文件夹批量识别、更换不同网络模型等功能。
  3. 系统可以通过界面选择数据集进行训练,并给出训练曲线和模型评估结果。


2. 系统界面演示效果

在本节中,我们将介绍系统的图形用户界面(GUI)及其功能。该界面允许用户执行以下操作:

(1)选择图片分类:用户可以选择一张图片,系统将根据预训练的卷积神经网络模型对其进行分类,并显示预测结果。


(2)选择文件夹批量识别:用户可以选择一个文件夹,系统将对文件夹中的所有图片进行分类,并在预测完成后生成一个包含结果的列表和可视化展示。


(3)更换不同网络模型:用户可以在GoogleNet和ResNet等预训练模型之间进行切换,以便在不同模型上进行实验。


通过界面选择数据集训练一键训练模型:用户可以选择一个自定义的数据集文件夹,系统将自动训练一个新的卷积神经网络模型,并显示训练过程中的损失和准确率曲线。


3. 神经网络训练

在这一节详细阐述如何使用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);  % 绘制混淆矩阵图



4. 系统实现

本节介绍如何在MATLAB中实现图像分类与训练系统的设计:该系统将分为两个部分,第一部分是预测部分,负责选择图片、文件夹分类和更换模型;第二部分是训练部分,负责选择数据集、设置训练参数、一键训练模型并评估。将结合GUI界面展示系统的设计框架和实现方法。

在本图像分类与训练系统中,可以通过一个技术逻辑图来概括整个系统的结构和工作流程。以下是技术逻辑图的文字描述:

  1. 用户界面(GUI):用户界面是整个系统的核心部分,它负责接收用户的输入和指令。用户界面包括两个主要部分:预测部分和训练部分。预测部分允许用户选择图片、文件夹和模型进行分类;训练部分允许用户选择数据集、设置训练参数并一键训练模型。
  2. 数据预处理:在用户选择了数据集后,系统将对数据进行预处理,包括数据增强和灰度图像转换。这一步骤确保输入的数据符合模型的要求,同时增强模型的泛化能力。
  3. 模型训练:在用户设置好训练参数后,系统将使用第三节中介绍的方法对模型进行训练。在训练过程中,系统会实时绘制训练进度曲线,以便用户了解模型的训练情况。
  4. 模型评估:训练完成后,系统将自动评估模型的性能,并将结果展示给用户。这有助于用户了解模型在未知数据上的泛化能力。
  5. 图像分类:在预测部分,用户可以选择图片、文件夹和模型进行分类。系统将根据用户的选择加载相应的模型,并对选择的图片或文件夹中的图像进行分类。


5. 总结与展望

本博客介绍了基于深度神经网络的图像分类与训练系统(MATLAB实现)。从引言开始,介绍基于GoogleNet、ResNet进行图像分类的背景、意义,系统研究现状及相关算法。随后,展示了系统的界面演示效果,包括选择图片分类、选择文件夹批量识别、更换不同网络模型和通过界面选择数据集一键训练模型等功能。在第三节中,详细介绍了神经网络训练的过程,包括训练代码、训练曲线和模型评估结果。第四节讲述了系统实现的两个部分:预测部分和训练部分,结合GUI界面给出了设计框架和实现。

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空