这个例子展示了如何创建一个具有残差连接的深度学习神经网络,并在CIFAR-10数据上进行训练。残差连接是卷积神经网络结构中的一个流行元素。使用剩余连接可以改善网络的梯度流,并可以训练更深层次的网络。
对于许多应用程序来说,使用由简单的层序列组成的网络就足够了。然而,一些应用程序需要具有更复杂的图结构的网络,其中各层可以有来自多个层的输入和向多个层的输出。这些类型的网络通常被称为有向无环图(DAG)网络。残余网络是DAG网络的一种,它有绕过主网络层的残余(或捷径)连接。剩余连接使参数梯度更容易从输出层传播到网络的早期层,这使得训练更深层次的网络成为可能。这种增加的网络深度可以在更困难的任务中获得更高的精度。
按照以下步骤创建和训练具有图形结构的网络。
创建一个LayerGraph
对象使用layerGraph
. 层图指定了网络体系结构。可以创建空图层图,然后向其中添加图层。还可以直接从网络层阵列创建层图。在这种情况下,,layerGraph
一个接一个地连接数组中的层。
使用将图层添加到图层图中addLayers
,并从图中删除层搬运工
.
连接层到其他层使用connectLayers
,并使用断开图层与其他图层的连接disconnectLayers
.
使用情节
.
使用trainNetwork
.经过训练的网络是DAGNetwork
对象。
对新数据进行分类和预测分类
和预测
.
这个例子展示了如何从头开始构建一个残留网络。您也可以使用resnetLayers
函数。该功能可以快速构建图像分类任务的残差网络。
您还可以加载预训练网络进行图像分类。有关更多信息,请参阅预先训练的深度神经网络.
下载CIFAR-10数据集[1]。该数据集包含60000个图像。每个图像的大小为32×32,并有三个颜色通道(RGB)。数据集的大小为175 MB。下载过程可能需要时间,具体取决于您的internet连接。
datadir = tempdir;downloadCIFARData (datadir);
将CIFAR-10训练和测试图像作为4-D阵列加载。训练集包含50000个图像,测试集包含10000个图像。使用CIFAR-10测试映像进行网络验证。
[XTrain、YTrain、XValidation、YValidation]=loadCIFARData(数据目录);
您可以使用以下代码显示训练图像的随机样本。
图;idx = randperm(大小(XTrain, 4), 20);我= imtile (XTrain (:,:,:, idx),“拇指指甲大小”(96、96));imshow (im)
创建一个增强图像数据存储
目的用于网络训练。在训练期间,数据存储沿着垂直轴随机翻转训练图像,并随机将它们水平和垂直转换为4个像素。数据增强有助于防止网络过度拟合和记忆训练图像的确切细节。
imageSize = [32 32 3];pixelRange = [-4 4];imageAugmenter = imageDataAugmenter (...“随机选择”,真的,...“随机翻译”pixelRange,...“RandYTranslation”,pixelRange);augimdsTrain=增强的图像数据存储(图像大小,XTrain,YTrain,...“DataAugmentation”,影像增强器,...“OutputSizeMode”,“randcrop”);
剩余的网络架构由以下几部分组成:
具有卷积层、批量规范化层和ReLU层顺序连接的主分支。
剩余的连接绕过主分支的卷积单元。剩余连接和卷积单元的输出按元素添加。当激活的大小改变时,剩余连接还必须包含1×1卷积层。剩余连接使参数梯度更容易从输出层流向网络的早期层,这使得训练更深层次的网络成为可能。
创建主要分支
首先创建网络的主分支。主要分支包括五个部分。
包含图像输入层和带有激活的初始卷积的初始部分。
3个不同尺寸的卷积层(32 × 32, 16 × 16, 8 × 8)。每个阶段都包含N卷积的单位。在本部分示例中,N = 2。每个卷积单元包含两个具有激活的3×3卷积层netWidth
参数是网络宽度,定义为网络第一级卷积层中的滤波器数量。第二级和第三级中的第一个卷积单元将空间维度的采样降低两倍。为了在整个网络中保持每个卷积层中所需的计算量大致相同,请在每次执行空间下采样时将过滤器的数量增加两倍。
具有全局平均池、完全连接、softmax和分类层的最后一部分。
使用卷积单位(numF、步幅、标记)
创建一个卷积单元。numF
是每层中卷积滤波器的数量,步
是单位的第一个卷积层的步幅,和标签
是一个字符数组,用于在层名称前加前缀convolutionalUnit
函数在示例末尾定义。
给所有层赋予唯一的名称。在卷积单元的层有名字开始“SjUk”
哪里j
阶段指标是和吗k
是该阶段内卷积单元的索引。例如“S2U1”
表示阶段2,单元1。
netWidth = 16;[imageInputLayer([32 32 3],]),“名字”,“输入”) convolution2dLayer (3 netWidth“填充”,“相同”,“名字”,“convInp”)批处理规范化层(“名字”,“BNInp”) reluLayer (“名字”,“reluInp”) convolutionalUnit (netWidth 1“S1U1”) additionLayer (2“名字”,“地址11”) 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“名字”,“地址22”) reluLayer (“名字”,“relu22”)卷积单元(4*netWidth,2,“S3U1”) additionLayer (2“名字”,“add31”) reluLayer (“名字”,“relu31”)卷积单元(4*netWidth,1,“S3U2”) additionLayer (2“名字”,“add32”) reluLayer (“名字”,“relu32”)平均池2层(8,“名字”,“globalPool”) fullyConnectedLayer (10“名字”,“fcFinal”) softmaxLayer (“名字”,“softmax”) classificationLayer (“名字”,“classoutput”) ];
从图层阵列创建图层图。layerGraph
连接中的所有层层
按顺序。绘制图层图。
lgraph = layerGraph(层);图(“单位”,“归一化”,“位置”,[0.2 0.2 0.6 0.6]);情节(lgraph);
创建剩余连接
在卷积单元周围添加剩余连接。大多数剩余连接不执行任何操作,只需向卷积单元的输出添加元素。
创建残留连接从“reluInp”
到“地址11”
层。因为您在创建该层时指定了添加层的输入数量为2,所以该层有两个带有名称的输入“三机”
和“in2”
.第一个卷积单元的最后一层已经连接到“三机”
输入。然后,加法层将第一个卷积单元的输出和“reluInp”
层。
以相同的方式,连接“relu11”
层的第二个输入“add12”
层。通过绘制层图,检查你已经正确地连接了层。
lgraph = connectLayers (lgraph,“reluInp”,“add11/in2”);lgraph = connectLayers (lgraph,“relu11”,“add12 / in2”);图(“单位”,“归一化”,“位置”,[0.2 0.2 0.6 0.6]);情节(lgraph);
当卷积单元中的层激活改变大小时(即,当它们在空间上下采样,在通道维度上上上采样),剩余连接中的激活也必须更改大小。通过使用1×1卷积层及其批处理规范化层来更改剩余连接中的激活大小。
skip1=[convolution2dLayer(1,2*netWidth,“步”2.“名字”,“skipConv1”)批处理规范化层(“名字”,“skipBN1”)]; lgraph=addLayers(lgraph,skip1);lgraph=连接层(lgraph,“relu12”,“skipConv1”);lgraph = connectLayers (lgraph,“skipBN1”,“add21/in2”);
在网络的第二阶段添加标识连接。
lgraph = connectLayers (lgraph,“relu21”,“add22 / in2”);
通过另一个1 × 1卷积层及其批处理归一化层改变第二和第三阶段之间的剩余连接中的激活大小。
skip2=[convolution2dLayer(1,4*netWidth,“步”2.“名字”,“skipConv2”)批处理规范化层(“名字”,“skipBN2”));lgraph = addLayers (lgraph skip2);lgraph = connectLayers (lgraph,“relu22”,“skipConv2”);lgraph = connectLayers (lgraph,“skipBN2”,“add31/in2”);
添加最后的身份连接并绘制最后的层图。
lgraph = connectLayers (lgraph,“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.10.1 0.8 0.8]);绘图(lgraph)
指定培训选项。训练80年代的网络。选择与小批量大小成比例的学习率,并在60个epoch后将学习率降低10倍。每个epoch使用验证数据验证网络一次。
miniBatchSize = 128;learnRate = 0.1 * miniBatchSize / 128;valFrequency =地板(大小(XTrain 4) / miniBatchSize);选择= trainingOptions (“sgdm”,...“InitialLearnRate”learnRate,...“MaxEpochs”, 80,...“MiniBatchSize”,小批量,...“详细频率”valFrequency,...“洗牌”,“every-epoch”,...“阴谋”,“训练进步”,...“冗长”假的,...“ValidationData”,{XValidation,YValidation},...“ValidationFrequency”valFrequency,...“LearnRateSchedule”,“分段”,...“LearnRateDropFactor”, 0.1,...“LearnRateDropPeriod”、60);
使用trainNetwork
,设置doTraining
旗帜真正的
. 否则,请加载预训练网络。在一个好的GPU上训练网络大约需要两个小时。如果您没有GPU,那么培训需要更长的时间。
doTraining = false;如果doTraining trainedNet=列车网络(AugimdTrain、lgraph、选项);其他的负载(“cifarnet - 20 - 16. -垫”,“trainedNet”);结束
在训练集(无数据扩充)和验证集上计算网络的最终精度。
(YValPred,聚合氯化铝)= (trainedNet XValidation)进行分类;validationError = mean(YValPred ~= YValidation);YTrainPred =分类(trainedNet XTrain);= mean(YTrainPred ~= YTrain);disp (“训练错误:”+列车错误*100+“%”)
训练误差:2.862%
disp ("验证错误:"+ validationError * 100 +“%”)
验证错误:9.76%
绘制混淆矩阵。通过使用列和行摘要显示每个类的精度和召回率。网络最常把猫和狗混淆。
图(“单位”,“归一化”,“位置”,[0.2 0.2 0.4 0.4]); cm=混淆图(YValidation,YValPred);cm.标题=“验证数据的混淆矩阵”; cm.摘要=“column-normalized”;厘米。RowSummary =“行规范化”;
您可以使用以下代码显示9个测试图像的随机样本,以及它们的预测类和这些类的概率。
图idx = randperm(size(XValidation,4),9);为i = 1:元素个数(idx)次要情节(3 3 i) imshow (XValidation (:,:,:, idx(我)));概率= num2str (100 * max(聚合氯化铝(idx(我),:)),3);predClass = char (YValPred (idx (i)));标题([predClass,', ',prob,'%'])结束
卷积单位(numF、步幅、标记)
创建一个由两个卷积层和相应的批处理规范化和ReLU层组成的层数组。numF
为卷积滤波器的个数,步
是第一个卷积层的步长,并且标签
是附加在所有层名称前的标记。
函数layers =[卷积2dlayer (3,numF, numF,)]“填充”,“相同”,“步”步,“名字”,标签,“conv1”]) batchNormalizationLayer (“名字”,标签,“BN1”]) reluLayer (“名字”,标签,“relu1”numF]) convolution2dLayer(3日,“填充”,“相同”,“名字”,标签,“conv2”]) batchNormalizationLayer (“名字”,标签,“BN2”])];结束
[1] Alex Krizhevsky,“从微小图像中学习多层特征”(2009)。https://www.cs.toronto.edu/~kriz/learning-features-2009-TR.pdf
何开明,张翔宇,任少青,孙健“图像识别的深度残差学习”。在计算机视觉与模式识别IEEE会议论文集, 770 - 778页。2016.
resnetLayers
|resnet3dLayers
|trainNetwork
|trainingOptions
|layerGraph
|分析网络