这个例子说明了如何使用深学习培养了语义分割网络。
语义网络分割图像中的每个像素进行分类,从而产生由类分割的图像。对于语义分割的应用包括道路分割为自主驾驶和癌细胞分割的医疗诊断。要了解更多信息,请参阅入门语义分割使用Deep学习。
为了说明训练过程,本实施例列车Deeplab V3 + [1],一种类型的卷积神经网络的(CNN)设计用于语义的图像分割。其他类型的网络对语义分割的包括完全卷积网络(FCN),SegNet,和U-Net的。这里显示的训练过程可以被应用到这些网络了。
本例使用CamVid数据集[2]从剑桥大学进行培训。此数据集是包含在驾驶时获得的街道级视图的图像的集合。该数据集提供了像素级标签32个语义类别包括汽车,行人和道路。
本示例创建Deeplab V3 +网络与来自预训练RESNET-18网络初始化权重。RESNET-18是非常适合于具有有限处理资源的应用程序的有效网络。其他预训练的网络,诸如MobileNet v2或RESNET-50也可以根据应用的需要使用。有关详细信息,请参阅预训练深层神经网络(深学习工具箱)。
为了获得预训练RESNET-18,安装深度学习工具箱™模型RESNET-18网络。安装完成后,运行下面的代码来验证安装是否正确。
resnet18 ();
此外,还可以下载DeepLab v3+的预训练版本。预训练模型允许您运行整个示例,而无需等待培训完成。
pretrainedURL ='//www.tianjin-qmedu.com/万博1manbetxsupportfiles/vision/data/deeplabv3plusResnet18CamVid.mat';pretrainedFolder = fullfile (tempdir,'pretrainedNetwork');pretrainedNetwork =完整文件(pretrainedFolder,'deeplabv3plusResnet18CamVid.mat');如果〜存在(pretrainedNetwork,“文件”)MKDIR(pretrainedFolder);DISP(“预训练下载网(58 MB)......”);websave(pretrainedNetwork,pretrainedURL);结束
有CUDA能力的女妖™ 运行此示例时,强烈建议使用计算能力为3.0或更高版本的GPU。使用GPU需要并行计算工具箱™.
从以下url下载CamVid数据集。
IMAGEURL ='http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/files/701_StillsRaw_full.zip';labelURL ='http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/LabeledApproved_full.zip';outputFolder =完整文件(TEMPDIR,“CamVid”);labelsZip = fullfile (outputFolder,'labels.zip');imagesZip=fullfile(输出文件夹,'images.zip');如果〜存在(labelsZip,“文件”)| | ~存在(图像ZIP,“文件”)mkdir(outputFolder)显示(“下载16层MB CamVid数据集的标签......”);websave(labelsZip,labelURL);解压缩(labelsZip,完整文件(outputFolder,'标签'));DISP(“下载557倍MB CamVid数据集的图像......”);websave(imagesZip,IMAGEURL);解压缩(imagesZip,完整文件(outputFolder,'图片'));结束
注:数据的下载时间取决于您的Internet连接。使用上述块MATLAB的命令,直至下载完成。另外,您也可以使用Web浏览器对数据集先下载到本地磁盘。要使用从网上下载的文件,更改输出文件夹
以上变量指定下载文件的位置。
采用imageDatastore
加载视频图像。的imageDatastore
使您能够有效地在磁盘上加载大量图像。
imgDir = fullfile (outputFolder,'图片','701_StillsRaw_full');imd = imageDatastore (imgDir);
显示其中一个图像。
I = readimage(IMDS,1);I = histeq(I);imshow(I)
采用pixelLabelDatastore
到负载CamVid像素标签的图像数据。一个pixelLabelDatastore
封装了像素标签数据和标签ID的一类名称映射。
我们让训练变得更容易,我们将CamVid中的32个原始类归为11个类。指定这些类。
类= [“天空”“建造”“极”“道路”“路面”“树”“标志符号”“篱笆”“汽车”“行人”“自行车”]。
为了将32个类减少到11个,将原始数据集中的多个类组合在一起。例如,“Car”是“Car”、“SUVPickupTruck”、“Truck-Bus”、“Train”和“OtherMoving”的组合。使用支持函数返回分组标签id万博1manbetx摄像机像素标签
,它列在本例的末尾。
labelIDs = camvidPixelLabelIDs();
使用类和标签的ID创建pixelLabelDatastore。
labelDir=fullfile(输出文件夹,'标签');pxds = pixelLabelDatastore(labelDir,类,labelIDs);
读取并通过覆盖其上的图像的顶部的像素标记的图像的显示之一。
C=读取图像(pxds,1);cmap=camvidColorMap;B=labeloverlay(I,C,“ColorMap”,CMAP);imshow(B)pixelLabelColorbar(CMAP,班);
没有颜色覆盖的区域没有像素标签,并且在训练期间不使用。
若要查看CamVid数据集,使用类标签的分发countEachLabel
。这个函数根据类标签来计算像素的数量。
台= countEachLabel (pxds)
TBL =11×3表名称PixelCount ImagePixelCount ______________ __________ _______________ { '天空'} 7.6801e + 07 4.8315e + 08 { '大厦'} 1.1737e + 08 4.8315e + 08 { '极'} 4.7987e + 06 4.8315e + 08 { '道'}1.4054e + 08 4.8453e + 08 { '路面'} 3.3614e + 07 4.7209e + 08 { '树'} 5.4259e + 07 4.479e + 08 { 'SignSymbol'} 5.2242e + 06 4.6863e + 08 {'栅栏'} 6.9211e + 06 2.516e + 08 {' 汽车”} 2.4437e + 07 4.8315e + 08 { '行人'} 3.4029e + 06 4.4444e + 08 { '自行车运动员'} 2.5912e + 06 2.6196e + 08
通过可视化类的像素数。
频率= tbl.PixelCount /总和(tbl.PixelCount);杆(1:numel(类),频率)xticks(1:numel(类))xticklabels(tbl.Name)xtickangle(45)ylabel('频率')
理想情况下,所有类都有相同数量的观察结果。然而,CamVid中的类是不平衡的,这是街景汽车数据集中的一个常见问题。这些场景的天空、建筑物和道路像素比行人和骑自行车的像素多,因为天空、建筑物和道路在图像中覆盖的区域更多。如果处理不当,这种不平衡可能会损害学习过程,因为学习偏向优势阶级。在本例的后面,您将使用类权重来处理这个问题。
在CamVid数据集的图像是由960×720的尺寸。图像尺寸被选择为使得有足够大的一批图像可以与12 GB的存储器上的NVIDIA™泰坦X训练期间适合在存储器中。您可能需要将图像调整到更小的尺寸,如果你的GPU没有足够的内存或减少培训批量大小。
Deeplab V3 +使用的是数据集中的图像的60%的培训。图像的其余部分在20%平均分配和用于验证和测试分别20%。下面的代码随机分割图像和像素标签数据到训练,验证和测试集。
[imdsTrain,imdsVal,imdsTest,pxdsTrain,pxdsVal,pxdsTest] = partitionCamVidData(IMDS,pxds);
60/20/20分割产生以下数量的训练、验证和测试图像:
numTrainingImages =元素个数(imdsTrain.Files)
numTrainingImages = 421
numValImages = numel(imdsVal.Files)
numValImages = 140
numTestingImages = numel(imdsTest.Files)
数字图像=140
使用deeplabv3plusLayers公司
函数创建一个基于ResNet-18的DeepLab v3+网络。为您的应用程序选择最佳网络需要经验分析,这是超参数调优的另一个层次。例如,您可以尝试使用不同的基础网络,如ResNet-50或MobileNet v2,或者您可以尝试其他语义分割网络架构,如SegNet、全卷积网络(FCN)或U-Net。
%指定网络的图像尺寸。这通常是一样的国家队训练图像尺寸。图像大小=[720 960 3];%指定的类的数量。numClasses = numel(类);%创建DeepLab v3+。lgraph = deeplabv3plusLayers(imageSize, numClasses,“resnet18”);
如图所示早些时候,在CamVid类不均衡。为了提高训练,你可以使用类的权重,以平衡类。使用前面与计算的像素数的标签countEachLabel
并计算出中位数频率类的权重。
imageFreq = tbl.PixelCount ./ tbl.ImagePixelCount;classWeights =中间值(imageFreq)./ imageFreq
classWeights =11×10.3182 0.2082 5.0924 0.1744 0.7103 0.4175 4.5371 1.8386 1.0000 6.6059⋮
指定使用的类权重像素分类层
。
pxLayer = pixelClassificationLayer('名称','标签',“类”,tbl.Name,'类权重',classWeights);lgraph = replaceLayer (lgraph,“分类”,px层);
用于培训的优化算法是动量(SGDM)随机梯度下降。采用trainingOptions
指定用于SGDM的超参数。
%定义验证数据。pximdsVal = pixelLabelImageDatastore(imdsVal,pxdsVal);%定义培训选项。选项= trainingOptions(“个”,…“LearnRateSchedule”,“分段”,…'LearnRateDropPeriod'10…'LearnRateDropFactor',0.3,…“动力”,0.9分,…'初始清除日期',1E-3,…“L2Regularization”,0.005,…'ValidationData',pximdsVal,…'MaxEpochs'30,…“MiniBatchSize”8,…“洗牌”,“每个历元”,…'CheckpointPath'tempdir,…'VerboseFrequency'2,…“情节”,“训练进步”,…“ValidationPatience”,4);
学习率采用的是分段的时间表。学习速率是由0.3每10个历元的因子减小。这使得网络具有较高的初始学习率快速学习,同时能够找到一个解决方案接近局部最优一次学习率下降。
网络不受验证数据每历元通过设置测试'ValidationData'
参数。的“ValidationPatience”
设置为4,停止训练初期验证准确性收敛时。这可以防止网络过度拟合的训练数据集。
小批处理大小为8,用于减少训练时的内存使用。你可以增加或减少根据您的系统上的GPU内存量此值。
此外,'CheckpointPath'
被设置为一个临时位置。此名称 - 值对使网络检查站的保存在每个训练时代的结束。如果培训是系统故障或停电中断的原因,您可以继续从已保存的检查点的训练。确保位置的指定'CheckpointPath'
有足够的空间来存储网络检查站。例如,储存100个Deeplab V3 +检查点要求6〜GB的磁盘空间,因为每个检查点是61 MB。
数据增强正在训练,以提供网络更多的例子,因为它有助于提高网络的精确度时使用。在这里,为+/- 10像素随机左/右的反射和随机X / Y平移用于数据增强。使用图像数据增强器
指定这些数据增强参数。
增量= imageDataAugmenter ('RandXReflection',真正,…“RandXTranslation”-10年[10],“兰迪翻译”,[-10 10]);
图像数据增强器
万博1manbetx支持其他几种类型的数据扩充。其中的选择需要经验分析,是另一个层次的超参数调整。
结合使用的训练数据和数据扩充选择pixelLabelImageDatastore
。的pixelLabelImageDatastore
读取的训练数据的批次,施加数据增强,并且增强的数据发送给训练算法。
pximds = pixelLabelImageDatastore (imdsTrain pxdsTrain,…'DataAugmentation'、增压器);
开始培训使用列车网络
如果昏睡
标志为true。否则,加载预训练网络。
注:培训,验证上的英伟达™泰坦X具有12 GB GPU内存中。如果您的GPU具有较少的内存,你可以的记忆训练中跑出来。如果发生这种情况,可以尝试设置“MiniBatchSize”
1在trainingOptions
或降低了网络的输入和调整用的训练数据'输出大小'
参数pixelLabelImageDatastore
。培训这个网络大约需要5个小时。根据您的GPU硬件,可能需要更长的时间。
doTraining = FALSE;如果doTraining [净,信息] = trainNetwork(pximds,lgraph,选项);其他的data=load(预训练网络);net=data.net;结束
作为一个快速的完整性检查,在一个测试映像上运行这个训练好的网络。
I=读取图像(imdsTest,35);C=语义示例(I,net);
显示结果。
我= labeloverlay (C“Colormap”,CMAP,'透明度',0.4);imshow (B) pixelLabelColorbar(提出、类);
比较结果C
与预期的地面实况存储在pxdsTest
。绿色和红色区域突出的地方分割结果与预期的地面实况不同领域。
expectedResult = readimage (pxdsTest 35);实际= uint8 (C);预期= uint8 (expectedResult);预计imshowpair(实际)
从视觉上看,语义分割结果对于诸如road、sky和building之类的类有很好的重叠。然而,像行人和汽车这样较小的物体并没有那么精确。每个类的重叠量可以使用intersection over union(IoU)度量来度量,也称为Jaccard索引。使用杰卡德
测量IoU的函数。
IOU =杰卡德(C,expectedResult);表(类,IOU)
ans =11×2桌学校下设“天”字0.91837“楼”字0.84479“路”字0.31203“路”字0.83698“路”字0.82838“树”字0.89636“标志”字0.57644“栅栏”字0.71046“车”字0.66688“行人”字0.48417“自行车”字0.68431
借据指标确认的视觉效果。路,天空和建筑类具有高欠条分数,而类如行人与汽车得低分。其他常见的细分指标包括骰子
和bfscore
轮廓匹配得分。
为了测量多个测试图像,运行精度语义
在整个测试集。将4小批量尺寸用于减少存储器的使用,同时分割图像。你可以增加或减少根据您的系统上的GPU内存量此值。
pxdsResults=semanticseg(imdsTest,net,…“MiniBatchSize”4,…'WriteLocation',TEMPDIR,…“详细”,假);
语义
将测试集的结果返回为pixelLabelDatastore
宾语。在每一个测试图像的实际像素标签数据IMD测试
写入磁盘中由指定的位置'WriteLocation'
参数。使用evaluateSemanticSegmentation
对测试集结果进行语义分割度量。
度量= evaluateSemanticSegmentation(pxdsResults,pxdsTest,“详细”,假);
evaluateSemanticSegmentation
返回整个数据集的各种度量,为各个类,并对于每一个测试图像。要查看数据集级别的指标,检查metrics.DataSetMetrics度量
。
metrics.DataSetMetrics度量
ans =表1×5GlobalAccuracy MeanAccuracy MeanIoU WeightedIoU MeanBFScore ______________ ____________ _______ ___________ ___________ 0.87695 0.85392 0.6302 0.80851 0.65051
数据集度量提供了网络性能的高级概述。要查看每个类对总体性能的影响,请使用metrics.ClassMetrics
。
metrics.ClassMetrics
ans =11×3表精度借条MeanBFScore ________ _______ ___________天空0.93112 0.90209 0.8952大厦0.78453 0.76098 0.58511极0.71586 0.21477 0.51439路0.93024 0.91465 0.76696路面0.88466 0.70571 0.70919树0.87377 0.76323 0.70875 SignSymbol 0.79358 0.39309 0.48302栅栏0.81507 0.46484 0.48564汽车0.90956 0.76799 0.69233步行0.87629 0.4366 0.60792自行车运动员0.87844 0.60829 0.55089
虽然整体数据集的性能是相当高的,该类指标显示,代表性不足类如行人
,骑自行车的
和汽车
不分段以及类,如路
,天空
和建造
。它包括的代表性不足的班级可能会帮助更多的样品附加数据改善的结果。
功能labelIDs=摄像机像素labelIDs()%返回对应于每一类的标签的ID。%CamVid数据集有32个类。把他们分成11个班%最初的SegNet训练方法[1]。%% 11类是:% “天空”, “建设”, “极”, “道”, “路面”, “树”, “SignSymbol”%“篱笆”,“汽车”,“行人”和“自行车运动员”。%%CamVid像素标签ID作为RGB颜色值提供。把他们分成% 11类,并将其作为m×3矩阵的单元数组返回。的每个RGB值旁边都列出了%原始的CamVid类名。请注意%,所述其他/空隙类如下排除。labelIDs = {…%的“天空”[128 128 128;…%的“天空”]%“建设”[000 128 064;…%“桥”128 000 000;…%“建设”064 192 000;…%“墙”064 000 064;…%的“隧道”192 000 128;…%“牌楼”]%“极点”[192 192 128;…%”Column_Pole”000 000 064元;…% “交通拥挤”]%的道路[128 064 128;…%“道路”128 000 192个;…% “LaneMkgsDriv”192000064;…% “LaneMkgsNonDriv”]%“路面”[000 000 192;…%“人行道”064 192 128;…% “ParkingBlock”128 128 192;…% “RoadShoulder”]%的“树”[128128 000;…%的“树”192.192万;…%”VegetationMisc”]%”SignSymbol”[192 128 128;…%”SignSymbol”128 128 064;…% “Misc_Text”000 064 064;…%”TrafficLight”]%“篱笆”[064 064 128;…%“篱笆”]%“汽车”[064000128;…%“汽车”064 128 192;…% “SUVPickupTruck”192 128 192;…%“卡车巴士”192 064 128;…%“训练”128 064 064;…%“其他移动”]%“行人”[064 064 000;…%“行人”192 128 064个;…%“孩子”064 000 192;…% “CartLuggagePram”064 128 064;…%“动物”]%“自行车运动员”[000 128 192;…%“自行车运动员”192 000 192个;…% “MotorcycleScooter”]};结束
功能一会pixelLabelColorbar(提出)向当前轴添加一个颜色栏。颜色栏被格式化了%以显示类名的颜色。颜色表(GCA,CMAP)%将颜色栏添加到当前图形。c = colorbar (“同行”,GCA);使用类名作为标记。c.TickLabels =类名;numClasses =尺寸(CMAP,1);%中心标记标签。c.Ticks = 1 /(numClasses * 2):1 / numClasses:1;清除标记。c。TickLength = 0;结束
功能cmap=camvidColorMap()%定义由CamVid数据集使用的颜色表。cmap = [128,128,128]%天空128 0 0% 建造192 192 192极%128 64 128%的道路60 40 222路面%128 128 0%树192 128 128%SignSymbol64 64 128%护栏64 0 128%的车64 64 0%行人0 128 192自行车运动员%]。%在[0 1]之间正常化。cmap=cmap./255;结束
功能[imdsTrain,imdsVal,imdsTest,pxdsTrain,pxdsVal,pxdsTest]=部分视频数据(imds,pxds)%随机抽取60%的数据进行训练,对CamVid数据进行分区。这个% rest用于测试。设定初始随机状态,例如再现性。rng (0);numFiles =元素个数(imds.Files);shuffledIndices = randperm (numFiles);%用途用于训练图像的60%。numTrain = round(0.60 * numFiles);trainingIdx = shuffledIndices (1: numTrain);%要用于验证图像的20%numVal = round(0.20 * numFiles);valIdx = shuffledIndices (numTrain + 1: numTrain + numVal);使用%,其余用于测试。testIdx = shuffledIndices(numTrain + numVal + 1:结束);%创建训练和测试图像数据存储。trainingImages = imds.Files(trainingIdx);valImages = imds.Files(valIdx);testImages = imds.Files(testIdx);imdsTrain = imageDatastore(trainingImages);imdsVal = imageDatastore(valImages);imdsTest = imageDatastore(testImages);%提取物类和标签的ID信息。类= pxds.ClassNames;labelIDs = camvidPixelLabelIDs();%创建的培训和测试像素标签数据存储。trainingLabels=pxds.Files(trainingIdx);valLabels=pxds.Files(valIdx);testLabels=pxds.Files(testIdx);pxdsTrain=pixelLabelDatastore(trainingLabels,classes,labelid);pxdsVal=pixelLabelDatastore(valLabels,classes,labelid);pxdsTest=pixelLabelDatastore(testLabels,classes,labelid);结束
陈亮杰等。"具有可分离卷积的编码解码器用于语义图像分割。"“大会(2018)。
[2] Brostow,G. J.,J. Fauqueur和R.泊拉。“语义对象类的视频:一个高清地面真实的数据库。”模式识别的字母。第30卷,2009年第2期,第88-97页。
countEachLabel
|evaluateSemanticSegmentation
|图像数据增强器
|labeloverlay
|像素分类层
|pixelLabelDatastore
|pixelLabelImageDatastore
|segnetLayers
|语义
|列车网络
|trainingOptions