Main Content

创建简单的深度学习神经网络以用于分类

此示例说明如何创建和训练简单的卷积神经网络来进行深度学习分类。

卷积神经网络是深度学习的基本工具,尤其适用于图像识别。

该示例演示如何:

  • 加载和浏览图像数据。

  • 定义神经网络架构。

  • 指定训练选项。

  • 训练神经网络。

  • 预测新数据的标签并计算分类准确度。

有关如何以交互方式创建和训练简单图像分类神经网络的示例,请参阅图像分类快速入门

加载和浏览图像数据

使用 imageDatastore 函数将位数数据加载为图像数据存储,并指定包含图像数据的文件夹。通过图像数据存储可以存储大图像数据,包括无法放入内存的数据,并在卷积神经网络的训练过程中高效分批读取图像。

unzip("DigitsData.zip");
dataFolder = "DigitsData";
imds = imageDatastore(dataFolder, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");

显示数据存储中的部分图像。

figure
tiledlayout("flow");
perm = randperm(10000,20);
for i = 1:20
    nexttile
    imshow(imds.Files{perm(i)});
end

计算每个类别中的图像数量。labelCount 是一个表,其中列出了标签,以及每个标签对应的图像数量。数据存储包含数字 0-9 的总共 10000 个图像,每个数字对应 1000 个图像。您可以在神经网络的最后一个全连接层中指定类数作为 OutputSize 参量。

classNames = categories(imds.Labels);
labelCount = countEachLabel(imds)
labelCount=10×2 table
    Label    Count
    _____    _____

      0      1000 
      1      1000 
      2      1000 
      3      1000 
      4      1000 
      5      1000 
      6      1000 
      7      1000 
      8      1000 
      9      1000 

您必须在神经网络的输入层中指定图像的大小。检查 digitData 中第一个图像的大小。每个图像的大小均为 28×28×1 像素。

img = readimage(imds,1);
size(img)
ans = 1×2

    28    28

指定训练集和验证集

将数据划分为训练数据集和验证数据集,以使训练集中的每个类别包含 750 个图像,并且验证集包含对应每个标签的其余图像。splitEachLabel 将数据存储 imds 拆分为两个新的数据存储 imdsTrainimdsValidation

numTrainFiles = 750;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,"randomize");

定义神经网络架构

定义卷积神经网络架构。

layers = [
    imageInputLayer([28 28 1])
    
    convolution2dLayer(3,8,Padding="same")
    batchNormalizationLayer
    reluLayer
    
    maxPooling2dLayer(2,Stride=2)
    
    convolution2dLayer(3,16,Padding="same")
    batchNormalizationLayer
    reluLayer
    
    maxPooling2dLayer(2,Stride=2)
    
    convolution2dLayer(3,32,Padding="same")
    batchNormalizationLayer
    reluLayer
    
    fullyConnectedLayer(10)
    softmaxLayer];

图像输入层 imageInputLayer 用于指定图像大小,在本例中为 28×28×1。这些数字对应于高度、宽度和通道大小。数字数据由灰度图像组成,因此通道大小(颜色通道)为 1。对于彩色图像,通道大小为 3,对应于 RGB 值。您不需要打乱数据,因为 trainnet 默认会在训练开始时打乱数据。trainnet 还可以在训练过程中的每轮训练开始时自动打乱数据。

卷积层在卷积层中,第一个参量是 filterSize,它是训练函数在沿图像扫描时使用的滤波器的高度和宽度。在此示例中,数字 3 表示滤波器大小为 3×3。您可以为滤波器的高度和宽度指定不同大小。第二个参量是滤波器数量 numFilters,它是连接到同一输入区域的神经元数量。此参数决定了特征图的数量。使用 Padding 名称-值参量输入特征图进行填充。对于默认步幅为 1 的卷积层,"same" 填充可确保空间输出大小与输入大小相同。您也可以使用 convolution2dLayer 的名称-值参量定义该层的步幅和学习率。

批量归一化层批量归一化层对神经网络中的激活值和梯度传播进行归一化,使神经网络训练成为更简单的优化问题。在卷积层和非线性部分(例如 ReLU 层)之间使用批量归一化层,来加速神经网络训练并降低对神经网络初始化的敏感度。使用 batchNormalizationLayer 创建批量归一化层。

ReLU 层批量归一化层后接一个非线性激活函数。最常见的激活函数是修正线性单元 (ReLU)。使用 reluLayer 创建 ReLU 层。

最大池化层卷积层(带激活函数)有时会后跟下采样操作,以减小特征图的空间大小并删除冗余空间信息。通过下采样可以增加更深卷积层中的滤波器数量,而不会增加每层所需的计算量。下采样的一种方法是使用最大池化,可使用 maxPooling2dLayer 创建。最大池化层返回由第一个参量 poolSize 指定的矩形输入区域的最大值。在此示例中,该矩形区域的大小是 [2,2]。Stride 名称-值参量指定训练函数在沿输入扫描时所采用的步长。

全连接层卷积层和下采样层后跟一个或多个全连接层。顾名思义,全连接层中的神经元将连接到前一层中的所有神经元。该层将先前层在图像中学习的所有特征组合在一起,以识别较大的模式。最后一个全连接层将特征组合在一起来对图像进行分类。因此,最后一个全连接层中的 OutputSize 参数等于目标数据中的类数。在此示例中,输出大小为 10,对应于 10 个类。使用 fullyConnectedLayer 创建全连接层。

softmax 层 softmax 激活函数对全连接层的输出进行归一化。softmax 层的输出由总和为 1 的多个正数组成,这些数字随后可被分类层用作分类概率。使用 softmaxLayer 函数在最后一个全连接层后创建一个 softmax 层。

指定训练选项

指定训练选项。在选项中进行选择需要经验分析。要通过运行试验探索不同训练选项配置,您可以使用Experiment Manager

  • 使用具有动量的随机梯度下降 (SGDM) 训练神经网络,初始学习率为 0.01。

  • 将最大训练轮数设置为 4。一轮训练是对整个训练数据集的一个完整训练周期。

  • 每轮训练都会打乱数据。

  • 通过指定验证数据和验证频率,监控训练过程中的神经网络准确度。软件基于训练数据训练神经网络,并在训练过程中按固定时间间隔计算基于验证数据的准确度。验证数据不用于更新神经网络权重。

  • 在图中显示训练进度并监控准确度。

  • 禁用详尽输出。

options = trainingOptions("sgdm", ...
    InitialLearnRate=0.01, ...
    MaxEpochs=4, ...
    Shuffle="every-epoch", ...
    ValidationData=imdsValidation, ...
    ValidationFrequency=30, ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=false);

使用训练数据训练神经网络

使用 layers 定义的架构、训练数据和训练选项训练神经网络。默认情况下,trainnet 使用 GPU(如果有),否则使用 CPU。在 GPU 上训练需要 Parallel Computing Toolbox™ 和支持的 GPU 设备。有关受支持设备的信息,请参阅GPU Computing Requirements (Parallel Computing Toolbox)。您还可以使用 trainingOptionsExecutionEnvironment 名称-值参量指定执行环境。

训练进度图显示了小批量损失和准确度以及验证损失和准确度。有关训练进度图的详细信息,请参阅监控深度学习训练进度。损失是交叉熵损失。准确度是神经网络分类正确的图像的百分比。

net = trainnet(imdsTrain,layers,"crossentropy",options);

对验证图像进行分类并计算准确度

对测试图像进行分类。要使用多个观测值进行预测,请使用 minibatchpredict 函数。要将预测分数转换为标签,请使用 scores2label 函数。minibatchpredict 函数自动使用 GPU(如果有)。否则,该函数使用 CPU。

scores = minibatchpredict(net,imdsValidation);
YValidation = scores2label(scores,classNames);

计算分类准确度。准确度是正确预测的标签的百分比。

TValidation = imdsValidation.Labels;
accuracy = mean(YValidation == TValidation)
accuracy = 0.9928

另请参阅

| | | |

相关主题