主要内容

图像分类残差网络训练

这个例子展示了如何创建一个带有剩余连接的深度学习神经网络,并在CIFAR-10数据上进行训练。残差连接是卷积神经网络体系结构中一个很受欢迎的元素。使用剩余连接可以改善网络中的梯度流,并可以训练更深层次的网络。

对于许多应用程序,使用由简单层序列组成的网络就足够了。然而,一些应用程序要求网络具有更复杂的图结构,其中层可以有来自多个层的输入和多个层的输出。这些类型的网络通常被称为有向无环图(DAG)网络。残余网络是一种DAG网络,它具有绕过主网络层的残余(或捷径)连接。剩余连接使参数梯度更容易从输出层传播到网络的早期层,这使得训练更深层次的网络成为可能。这种增加的网络深度可以在更困难的任务中获得更高的准确性。

要创建和训练具有图结构的网络,请遵循以下步骤。

  • 创建一个LayerGraph对象使用layerGraph.层图指定网络架构。您可以创建一个空的图层图,然后向其添加图层。您还可以直接从网络层数组创建层图。在这种情况下,layerGraph一个接一个地连接数组中的层。

  • 添加图层到图层图使用addLayers,并使用removeLayers

  • 连接层到其他层使用connectLayers,并使用disconnectLayers

  • 绘制网络架构使用情节

  • 使用trainNetwork.训练过的网络是一个DAGNetwork对象。

  • 利用新数据进行分类和预测分类而且预测

这个例子展示了如何从头开始构建一个剩余网络。属性也可以创建残留网络resnetLayers函数。该函数允许您快速构造图像分类任务的残差网络。

您还可以加载预先训练的网络进行图像分类。有关更多信息,请参见预训练的深度神经网络

准备数据

下载CIFAR-10数据集[1]。该数据集包含60,000张图像。每张图像大小为32x32,有三个颜色通道(RGB)。数据集的大小为175 MB。根据您的互联网连接,下载过程可能需要时间。

Datadir = tempdir;downloadCIFARData (datadir);

将CIFAR-10训练和测试图像加载为4-D数组。训练集包含50,000张图像,测试集包含10,000张图像。使用CIFAR-10测试图像进行网络验证。

[XTrain,YTrain,XValidation,YValidation] = loadCIFARData(datadir);

您可以使用以下代码显示训练图像的随机样本。

图;idx = randperm(size(XTrain,4),20);im = imtile(XTrain(:,:,:,idx),“ThumbnailSize”(96、96));imshow (im)

创建一个augmentedImageDatastore对象用于网络培训。在训练期间,数据存储沿垂直轴随机翻转训练图像,并在水平和垂直上将它们随机转换为4个像素。数据增强有助于防止网络过度拟合和记忆训练图像的确切细节。

imageSize = [32 32 3];pixelRange = [-4 4];imageAugmenter = imageDataAugmenter(...“RandXReflection”,真的,...“RandXTranslation”pixelRange,...“RandYTranslation”, pixelRange);augimdsTrain = augmentedimagedastore (imageSize,XTrain,YTrain,...“DataAugmentation”imageAugmenter,...“OutputSizeMode”“randcrop”);

定义网络架构

剩余网络架构由以下组件组成:

  • 一个由卷积、批处理归一化和ReLU层依次连接的主分支。

  • 剩余的连接绕过了主分支的卷积单元。剩余连接和卷积单元的输出逐元素添加。当激活的大小发生变化时,剩余连接也必须包含1 × 1的卷积层。剩余连接使参数梯度更容易从输出层流向网络的早期层,这使得训练更深层次的网络成为可能。

创建分支机构

首先创建网络的主分支。主要分支包括五个部分。

  • 包含图像输入层和带有激活的初始卷积的初始部分。

  • 具有不同特征大小的卷积层的三个阶段(32 × 32、16 × 16和8 × 8)。每个阶段包含N卷积的单位。在这一部分的例子中,N = 2.每个卷积单元包含两个带有激活的3 × 3卷积层。的netWidth参数为网络宽度,定义为网络第一阶段卷积层中的过滤器数量。第二和第三阶段的第一个卷积单元将空间维度降低了两倍。为了保持整个网络中每个卷积层所需的计算量大致相同,每次执行空间下采样时,将过滤器的数量增加两倍。

  • 最后一个部分具有全局平均池化、全连接、softmax和分类层。

使用convolutionalUnit (numF、跨步、标签)创建一个卷积单元。numF是每层卷积滤波器的个数,单位的第一卷积层的步幅,和标签是一个字符数组,放在层名前面。的convolutionalUnit函数在示例的末尾定义。

给所有层赋予唯一的名称。卷积单元中的层名称以“SjUk”,在那里j阶段索引和k是卷积单元在这一阶段的下标。例如,“S2U1”表示阶段2,单元1。

netWidth = 16;图层= [imageInputLayer([32 32 3],“名字”“输入”) convolution2dLayer (3 netWidth“填充”“相同”“名字”“convInp”) batchNormalizationLayer (“名字”“BNInp”) reluLayer (“名字”“reluInp”) convolutionalUnit (netWidth 1“S1U1”) additionLayer (2“名字”“add11”) reluLayer (“名字”“relu11”) convolutionalUnit (netWidth 1“S1U2”) additionLayer (2“名字”“add12”) reluLayer (“名字”“relu12”) convolutionalUnit (2 * netWidth 2“S2U1”) additionLayer (2“名字”“add21”) reluLayer (“名字”“relu21”) convolutionalUnit (2 * netWidth 1“S2U2”) additionLayer (2“名字”“add22”) reluLayer (“名字”“relu22”) convolutionalUnit (4 * netWidth 2“S3U1”) additionLayer (2“名字”“add31”) reluLayer (“名字”“relu31”) convolutionalUnit (4 * netWidth 1“S3U2”) additionLayer (2“名字”“add32”) reluLayer (“名字”“relu32”) averagePooling2dLayer (8,“名字”“globalPool”) fullyConnectedLayer (10“名字”“fcFinal”) softmaxLayer (“名字”“softmax”) classificationLayer (“名字”“classoutput”));

从图层数组创建一个图层图。layerGraph连接所有的层按顺序。绘制层图。

lgraph = layerGraph(图层);图(“单位”“归一化”“位置”,[0.2 0.2 0.6 0.6]);情节(lgraph);

创建剩余连接

在卷积单元周围添加剩余连接。大多数剩余连接不执行任何操作,只是简单地将元素添加到卷积单元的输出中。

创建剩余连接“reluInp”“add11”层。因为您在创建层时指定了添加层的输入数量为两个,所以该层有两个带有名称的输入“三机”而且“in2”.第一卷积单元的最后一层已经连接到“三机”输入。然后,加法层将第一个卷积单元的输出和“reluInp”层。

以同样的方式,连接“relu11”层的第二个输入“add12”层。通过绘制图层图,检查是否已经正确连接了图层。

lgraph = connectLayers(“reluInp”“add11 / in2”);lgraph = connectLayers(“relu11”“add12 / in2”);图(“单位”“归一化”“位置”,[0.2 0.2 0.6 0.6]);情节(lgraph);

当卷积单元中的层激活改变大小时(即当它们在空间上被下采样,在通道维度上被上采样),剩余连接中的激活也必须改变大小。通过使用1 × 1卷积层及其批处理归一化层来改变剩余连接中的激活大小。

skip1 = [convolution2dLayer(1,2*netWidth,“步”2,“名字”“skipConv1”) batchNormalizationLayer (“名字”“skipBN1”));lgraph = addLayers(lgraph,skip1);lgraph = connectLayers(“relu12”“skipConv1”);lgraph = connectLayers(“skipBN1”“add21 / in2”);

在网络的第二阶段添加身份连接。

lgraph = connectLayers(“relu21”“add22 / in2”);

将第二阶段和第三阶段之间的剩余连接中的激活大小更改为另一个1 × 1卷积层及其批处理归一化层。

skip2 = [convolution2dLayer(1,4*netWidth,“步”2,“名字”“skipConv2”) batchNormalizationLayer (“名字”“skipBN2”));lgraph = addLayers(lgraph,skip2);lgraph = connectLayers(“relu22”“skipConv2”);lgraph = connectLayers(“skipBN2”“add31 / in2”);

添加最后一个标识连接并绘制最终层图。

lgraph = connectLayers(“relu31”“add32 / in2”);图(“单位”“归一化”“位置”,[0.2 0.2 0.6 0.6]);情节(lgraph)

建立更深层次的网络

要为任意深度和宽度的CIFAR-10数据创建带有剩余连接的层图,请使用支持函数金宝appresidualCIFARlgraph

lgraph = residualCIFARlgraph(netWidth,numUnits,unitType)为具有剩余连接的CIFAR-10数据创建层图。

  • netWidth是网络宽度,定义为网络的前3 × 3卷积层中的过滤器数量。

  • numUnits是网络主分支中卷积单元的个数。因为网络由三个阶段组成,每个阶段都有相同数量的卷积单元,numUnits必须是3的整数倍。

  • unitType卷积单元的类型是否指定为“标准”“瓶颈”.一个标准的卷积单元由两个3 × 3的卷积层组成。瓶颈卷积单元由三个卷积层组成:1 × 1层用于通道维度的下采样,3 × 3卷积层和1 × 1层用于通道维度的上采样。因此,瓶颈卷积单元的卷积层数比标准单元多50%,但空间3 × 3卷积的数量只有一半。这两种单元类型具有相似的计算复杂度,但是当使用瓶颈单元时,在剩余连接中传播的特征总数要大四倍。总深度定义为连续卷积层和全连接层的最大数量,为2*numUnits标准单元网络为+ 2,3*numUnits有瓶颈单元的网络+ 2。

创建一个带有9个标准卷积单元(每个阶段3个单元)和16个宽度的剩余网络。总网络深度为2*9+2 = 20。

numUnits = 9;netWidth = 16;lgraph = residualCIFARlgraph(netWidth,numUnits,“标准”);图(“单位”“归一化”“位置”,[0.1 0.1 0.8 0.8]);情节(lgraph)

列车网络的

指定培训选项。训练网络80个epoch。选择与迷你批处理大小成比例的学习率,并在60个epoch后将学习率降低10倍。使用验证数据每个epoch验证一次网络。

miniBatchSize = 128;learnRate = 0.1*miniBatchSize/128;valFrequency = floor(size(XTrain,4)/miniBatchSize);选项= trainingOptions(“个”...“InitialLearnRate”learnRate,...“MaxEpochs”, 80,...“MiniBatchSize”miniBatchSize,...“VerboseFrequency”valFrequency,...“洗牌”“every-epoch”...“阴谋”“训练进步”...“详细”假的,...“ValidationData”{XValidation, YValidation},...“ValidationFrequency”valFrequency,...“LearnRateSchedule”“分段”...“LearnRateDropFactor”, 0.1,...“LearnRateDropPeriod”、60);

训练网络使用trainNetwork,设置doTraining旗帜真正的.否则,加载一个预先训练好的网络。在一个好的GPU上训练网络大约需要两个小时。如果你没有GPU,那么训练需要更长的时间。

doTraining = false;如果doTraining trainedNet = trainNetwork(augimdsTrain,lgraph,options);其他的负载(“cifarnet - 20 - 16. -垫”“trainedNet”);结束

评估训练网络

计算网络在训练集(没有数据增强)和验证集上的最终精度。

[YValPred,probs] = category (trainedNet,XValidation);validationError = mean(YValPred ~= YValidation);YTrainPred =分类(trainedNet,XTrain);trainError = mean(YTrainPred ~= YTrain);disp (“训练错误:”+ trainError*100 +“%”)
训练误差:2.862%
disp ("验证错误:"+ validationError*100 +“%”)
验证错误:9.76%

绘制混淆矩阵。通过使用列和行摘要显示每个类的精度和召回率。该网络最常见的混淆猫和狗。

图(“单位”“归一化”“位置”,[0.2 0.2 0.4 0.4]);cm = confusionchart(YValidation,YValPred);厘米。Title =验证数据混淆矩阵;厘米。ColumnSummary =“column-normalized”;厘米。RowSummary =“row-normalized”

您可以使用以下代码显示9个测试图像的随机样本以及它们的预测类和这些类的概率。

figure idx = randperm(size(XValidation,4),9);i = 1:元素个数(idx)次要情节(3 3 i) imshow (XValidation (:,:,:, idx(我)));Prob = num2str(100*max(probs(idx(i),:)),3);(YValPred(idx(i)));标题([predClass,”、“概率,“%”])结束

convolutionalUnit (numF、跨步、标签)创建带有两个卷积层和相应的批处理归一化层和ReLU层的层数组。numF是卷积滤波器的个数,第一卷积层的步幅,和标签是一个附加在所有层名之前的标记。

函数图层= convolution2dLayer(3,numF, stride,tag)“填充”“相同”“步”步,“名字”,标签,“conv1”]) batchNormalizationLayer (“名字”,标签,“BN1”]) reluLayer (“名字”,标签,“relu1”numF]) convolution2dLayer(3日,“填充”“相同”“名字”,标签,“conv2”]) batchNormalizationLayer (“名字”,标签,“BN2”)));结束

参考文献

[1]克里哲夫斯基,亚历克斯。“从微小的图像中学习多层特征。”(2009)。https://www.cs.toronto.edu/~kriz/learning-features-2009-TR.pdf

[2]何开明,张翔宇,任少卿,孙健。“用于图像识别的深度剩余学习。”在IEEE计算机视觉和模式识别会议论文集,第770-778页。2016.

另请参阅

|||||

相关的话题