语义分割使用Deep学习

这个例子说明了如何使用深学习培养了语义分割网络。

语义网络分割图像中的每个像素进行分类,从而产生由类分割的图像。对于语义分割的应用包括道路分割为自主驾驶和癌细胞分割的医疗诊断。要了解更多信息,请参阅入门语义分割使用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 =完整文件(TEMPDIR,'pretrainedNetwork');pretrainedNetwork =完整文件(pretrainedFolder,'deeplabv3plusResnet18CamVid.mat');如果〜存在(pretrainedNetwork,'文件')MKDIR(pretrainedFolder);DISP(“预训练下载网(58 MB)......”);websave(pretrainedNetwork,pretrainedURL);结束

甲CUDA的NVIDIA™GPU计算能力3.0或更高,强烈建议用于运行该示例。一个GPU的使用需要并行计算工具箱™。

下载CamVid数据集

从以下网址下载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 =完整文件(outputFolder,'labels.zip');imagesZip =完整文件(outputFolder,'images.zip');如果〜存在(labelsZip,'文件')||〜存在(imagesZip,'文件')MKDIR(outputFolder)DISP(“下载16层MB CamVid数据集的标签......”);websave(labelsZip,labelURL);解压缩(labelsZip,完整文件(outputFolder,'标签'));DISP(“下载557倍MB CamVid数据集的图像......”);websave(imagesZip,IMAGEURL);解压缩(imagesZip,完整文件(outputFolder,“图片”));结束

注:数据的下载时间取决于您的Internet连接。使用上述块MATLAB的命令,直至下载完成。另外,您也可以使用Web浏览器对数据集先下载到本地磁盘。要使用从网上下载的文件,更改导出目录变量上面下载的文件的位置。

加载CamVid图片

imageDatastore加载CamVid图像。该imageDatastore使您能够高效地装载大量收集图像的磁盘上。

imgDir =完整文件(outputFolder,“图片”'701_StillsRaw_full');IMDS = imageDatastore(imgDir);

图像的显示之一。

I = readimage (imd, 1);I = histeq(我);imshow(我)

加载CamVid像素图像标记

pixelLabelDatastore加载CamVid像素标签图像数据。一个pixelLabelDatastore封装了像素标签数据和标签ID的一类名称映射。

我们使培训更容易,我们组32个原班CamVid至11班。指定这些类。

类= [“天空”“建造”“极”“路”“路面”“树”“SignSymbol”“篱笆”“汽车”“行人”“自行车运动员”]。

为了减少32类转换成如图11所示,从原始数据集的多个类被分组在一起。例如,“汽车”是“汽车”,“SUVPickupTruck”,“Truck_Bus”,“火车”和“OtherMoving”的组合。通过使用支持函数返回分组标签的ID万博1manbetxcamvidPixelLabelIDs,其列出在本实施例中的端部。

labelIDs = camvidPixelLabelIDs();

使用类和标签的ID创建pixelLabelDatastore。

labelDir =完整文件(outputFolder,'标签');pxds = pixelLabelDatastore(labelDir,类,labelIDs);

读取并通过覆盖其上的图像的顶部的像素标记的图像的显示之一。

C = readimage(pxds,1);CMAP = camvidColorMap;B = labeloverlay(I,C,“颜色表”,CMAP);imshow(B)pixelLabelColorbar(CMAP,班);

没有颜色的地方覆盖没有像素标签和训练过程中不使用。

分析数据集统计数据

若要查看CamVid数据集,使用类标签的分发countEachLabel。这个函数计算由类标签的像素数。

TBL = 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);bar(1:numel(类),频率)xticks(1:numel(类))xticklabels(task . name)'频率'

理想情况下,所有的类会有意见的数目相等。然而,在CamVid类的不平衡,这在汽车数据集街景的一个常见的问题。这样的场景有更多的天空,建筑物和道路像素比行人和自行车像素,因为天空,建筑物和道路覆盖图像中更多的区域。如果处理不当,因为学习是有利于统治阶级的偏见这种不平衡可能不利于学习的过程。后来在这个例子中,您将使用类的权重来处理这个问题。

CamVid数据集中的图像大小为720×960。在NVIDIA™Titan X上使用12 GB内存进行训练时,选择的图像大小足以容纳足够大的图像批。如果你的GPU没有足够的内存或减少训练批大小,你可能需要调整图像到较小的大小。

准备培训,验证和测试集

Deeplab V3 +使用的是数据集中的图像的60%的培训。图像的其余部分在20%平均分配和用于验证和测试分别20%。下面的代码随机分割图像和像素标签数据到训练,验证和测试集。

[imdsTrain, imdsVal, imdsTest, pxdsTrain, pxdsVal, pxdsTest] = partitionCamVidData(imds,pxds);

在60/20/20分割结果在下面的多家培训,验证和测试图像:

numTrainingImages = numel(imdsTrain.Files)
numTrainingImages = 421
numValImages = numel(imdsVal.Files)
numValImages = 140
numTestingImages = numel(imdsTest.Files)
numTestingImages = 140

创建网络

使用deeplabv3plusLayers函数来创建基于RESNET-18 DeepLab V3 +网络。为应用程序选择最佳的网络需要实证分析,是超参数调整的另一个层次。例如,可以用不同的碱网络如RESNET-50或MobileNet V2实验,或可以尝试其它语义分割网络体系结构,如SegNet,充分卷积网络(FCN),或U-Net的。

%指定网络的图像尺寸。这通常是一样的国家队训练图像尺寸。IMAGESIZE = [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⋮

指定使用的类权重pixelClassificationLayer

pxLayer = pixelClassificationLayer('名称''标签'“类”,tbl.Name,'ClassWeights',classWeights);lgraph = replaceLayer(lgraph,“分类”,pxLayer);

选择培训选项

用于培训的优化算法是动量(SGDM)随机梯度下降。用trainingOptions指定用于SGDM超参数。

%定义的验证数据。pximdsVal = pixelLabelImageDatastore (imdsVal pxdsVal);%定义培训选项。选项= trainingOptions('SGDM'...'LearnRateSchedule'“分段”...'LearnRateDropPeriod'10,...'LearnRateDropFactor',0.3,...'动量',0.9%,...'InitialLearnRate',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指定这些数据增强参数。

增强因子= imageDataAugmenter(“RandXReflection”,真正,...'RandXTranslation',[ -  10 10],'RandYTranslation',[ -  10 10]);

imageDataAugmenter万博1manbetx支持几种其它类型的数据扩充的。其中选择需要的实证分析,是超参数调节的另一个层次。

开始训练

结合使用的训练数据和数据扩充选择pixelLabelImageDatastore。该pixelLabelImageDatastore读取成批的训练数据,应用数据增强,并将增强后的数据发送给训练算法。

pximds = pixelLabelImageDatastore(imdsTrain,pxdsTrain,...'DataAugmentation',增强因子);

使用开始训练trainNetwork如果doTraining国旗是正确的。否则,加载一个预先训练好的网络。

注:培训,验证上的英伟达™泰坦X具有12 GB GPU内存中。如果您的GPU具有较少的内存,你可以的记忆训练中跑出来。如果发生这种情况,可以尝试设置'MiniBatchSize'到1trainingOptions或降低了网络的输入和调整用的训练数据'OutputSize'参数pixelLabelImageDatastore。培训这个网络大约需要5个小时。根据您的GPU硬件,可能需要更长的时间。

doTraining = FALSE;如果doTraining [净,信息] = trainNetwork(pximds,lgraph,选项);其他数据=负载(pretrainedNetwork);净= data.net;结束

测试网络上的一个图片

作为一个快速完整性检查,运行一个测试图像的训练的网络。

I = readimage(imdsTest,35);C = semanticseg(I,净);

显示结果。

B = labeloverlay(I,C,“颜色表”,CMAP,'透明度',0.4);imshow(B)pixelLabelColorbar(CMAP,班);

比较结果C与预期的地面真相储存pxdsTest。绿色和洋红色区域突出区域分割结果不同于预期的地面真相。

expectedResult = readimage(pxdsTest,35);实际= UINT8(C);预期= UINT8(expectedResult);imshowpair(实际,预期)

从外观上看,语义分割结果重叠以及为类,如道路,天空和建筑。然而,像行人和车辆更小的物体并不准确。每类重叠的量可使用交叉点过联盟(IOU)度量,也被称为索引的Jaccard来测量。使用杰卡德功能来衡量借条。

借据= jaccard (C, expectedResult);表(类、借据)
ANS =11×2表班借条____________ _______ “天空” 0.91837 “大厦” 0.84479 “极点” 0.31203 “道” 0.93698 “路面” 0.82838 “树” 0.89636 “SignSymbol” 0.57644 “篱笆” 0.71046 “汽车” 0.66688 “行人” 0.48417 “自行车运动员” 0.68431

IoU度量证实了视觉结果。道路类、天空类和建筑类的IoU得分较高,而行人类和汽车类的IoU得分较低。其他常见的分割指标包括骰子bfscore轮廓匹配分数。

评估培训网络

为了测量多个测试图像,运行精度semanticseg在整个测试集。将4小批量尺寸用于减少存储器的使用,同时分割图像。你可以增加或减少根据您的系统上的GPU内存量此值。

pxdsResults = semanticseg(imdsTest,网,...'MiniBatchSize'4...'WriteLocation'tempdir,...“放牧”,假);

semanticseg返回结果为测试组作为pixelLabelDatastore目的。在每一个测试图像的实际像素标签数据imdsTest写入磁盘中由指定的位置'WriteLocation'参数。用evaluateSemanticSegmentation测量在测试组结果语义分割指标。

度量= evaluateSemanticSegmentation(pxdsResults,pxdsTest,“放牧”,假);

evaluateSemanticSegmentation返回整个数据集、单个类和每个测试图像的各种指标。要查看数据集级别度量,请查看metrics.DataSetMetrics

metrics.DataSetMetrics
ANS =1×5表_______ GlobalAccuracy 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

尽管数据集的整体性能相当高,但类指标显示未充分表示的类,如行人骑自行车不分段以及类,如天空建造。它包括的代表性不足的班级可能会帮助更多的样品附加数据改善的结果。

万博1manbetx支持功能

功能labelIDs = camvidPixelLabelIDs()%返回对应于每一类的标签的ID。%的CamVid数据集有32类。它们分成11个班以下%的原始SegNet培训方法[1]。%的11类是:%的“天空”“建筑”,“极”,“路”,“路面”、“树”、“SignSymbol”,%“篱笆”,“汽车”,“行人”和“自行车运动员”。%CamVid像素标签ID被提供为RGB颜色值。它们分成%11类和返回它们为M×3矩阵的单元阵列。该%原装CamVid类名称列并排RGB值。注意%其他/Void类在下面被排除。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”192 000 064;...%”LaneMkgsNonDriv”]%“路面”[000 000 192;...%“人行道”064 192 128;...% “ParkingBlock”128 128 192;...% “RoadShoulder”]%“树”[128 128 000;...%“树”192 192 000;...% “VegetationMisc”]% “SignSymbol”[192 128 128;...% “SignSymbol”128 128 064;...% “Misc_Text”000 064 064;...% “红绿灯”]%“篱笆”[064 064 128;...%“篱笆”]%的“汽车”[064 000 128;...%的“汽车”064 128 192;...% “SUVPickupTruck”192 128 192;...% “Truck_Bus”192 064 128;...%“火车”128 064 064;...% “OtherMoving”]% “行人”[064 064 000;...% “行人”192 128 064;...%“孩子”064 000 192;...% “CartLuggagePram”064 128 064;...%的“动物”]%“自行车运动员”[000 128 192;...%“自行车运动员”192 000 192;...% “MotorcycleScooter”]};结束
功能pixelLabelColorbar(CMAP,类名)%一彩条添加到当前的轴线。该彩条被格式化%显示与颜色的类名称。颜色表(GCA,CMAP)%加彩条目前的身影。C =彩条(“对等”,GCA);%用途类名的刻度线。c。TickLabels =一会;numClasses =大小(提出,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] = partitionCamVidData(IMDS,pxds)通过随机选择的数据的60%的训练%分区CamVid数据。该其余%用于测试。%设定例如再现初始随机状态。RNG(0);numFiles = numel(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,类,labelIDs);pxdsVal = pixelLabelDatastore(valLabels,类,labelIDs);pxdsTest = pixelLabelDatastore(testLabels,类,labelIDs);结束

参考文献

[1]陈,梁杰等。“编码器 - 解码器与Atrous可分离卷积语义图像分割”。ECCV(2018)。

[2] Brostow, G. J., J. Fauqueur和R. Cipolla。视频中的语义对象类:一个高清晰度地面真相数据库。模式识别快报。卷。30,第2期,2009年,第88-97。

也可以看看

||||||||||

相关话题