使用扩张卷积进行语义分割
使用扩张卷积训练语义分割网络。
语义分割网络对图像中的每个像素进行分类,从而生成按类分割的图像。语义分割的应用包括自动驾驶中的道路分割以及医疗诊断中的癌细胞分割。要了解详细信息,请参阅Getting Started with Semantic Segmentation Using Deep Learning (Computer Vision Toolbox)。
像 DeepLab [1] 这样的语义分割网络广泛使用扩张卷积(也称为空洞卷积),因为它们可以增加层的感受野(层可以看到的输入区域),而不增加参数或计算量。
加载训练数据
该示例使用 32×32 三角形图像的简单数据集进行说明。该数据集包括附带的像素标签真实值数据。使用 imageDatastore
和 pixelLabelDatastore
加载训练数据。
dataFolder = fullfile(toolboxdir('vision'),'visiondata','triangleImages'); imageFolderTrain = fullfile(dataFolder,'trainingImages'); labelFolderTrain = fullfile(dataFolder,'trainingLabels');
为图像创建一个 imageDatastore
。
imdsTrain = imageDatastore(imageFolderTrain);
为真实值像素标签创建一个 pixelLabelDatastore
。
classNames = ["triangle" "background"]; labels = [255 0]; pxdsTrain = pixelLabelDatastore(labelFolderTrain,classNames,labels)
pxdsTrain = PixelLabelDatastore with properties: Files: {200x1 cell} ClassNames: {2x1 cell} ReadSize: 1 ReadFcn: @readDatastoreImage AlternateFileSystemRoots: {}
创建语义分割网络
此示例使用一个基于扩张卷积的简单语义分割网络。
创建一个用于训练数据的数据源,并获取每个标签的像素计数。
ds = combine(imdsTrain,pxdsTrain); tbl = countEachLabel(pxdsTrain)
tbl=2×3 table
Name PixelCount ImagePixelCount
______________ __________ _______________
{'triangle' } 10326 2.048e+05
{'background'} 1.9447e+05 2.048e+05
大多数像素标签用于背景。这种类不平衡使学习过程偏向主导类。要解决此问题,请使用类权重来平衡各类。您可以使用几种方法来计算类权重。一种常见的方法是逆频率加权,其中类权重是类频率的倒数。此方法会增加指定给表示不足的类的权重。使用逆频率加权计算类权重。
numberPixels = sum(tbl.PixelCount); frequency = tbl.PixelCount / numberPixels; classWeights = 1 ./ frequency;
使用输入大小对应于输入图像大小的图像输入层创建一个用于像素分类的网络。接下来,指定三个由卷积层、批量归一化层和 ReLU 层组成的模块。对于每个卷积层,指定 32 个具有递增扩张系数的 3×3 滤波器,并通过将 'Padding'
选项设置为 'same'
来填充输入以使输入的大小与输出相同。要对像素进行分类,请包括一个具有 K 个 1×1 卷积的卷积层(其中 K 是类的数量),其后是一个 softmax 层和一个具有逆类权重的 pixelClassificationLayer
。
inputSize = [32 32 1]; filterSize = 3; numFilters = 32; numClasses = numel(classNames); layers = [ imageInputLayer(inputSize) convolution2dLayer(filterSize,numFilters,'DilationFactor',1,'Padding','same') batchNormalizationLayer reluLayer convolution2dLayer(filterSize,numFilters,'DilationFactor',2,'Padding','same') batchNormalizationLayer reluLayer convolution2dLayer(filterSize,numFilters,'DilationFactor',4,'Padding','same') batchNormalizationLayer reluLayer convolution2dLayer(1,numClasses) softmaxLayer pixelClassificationLayer('Classes',classNames,'ClassWeights',classWeights)];
训练网络
指定训练选项。
options = trainingOptions('sgdm', ... 'MaxEpochs', 100, ... 'MiniBatchSize', 64, ... 'InitialLearnRate', 1e-3);
使用 trainNetwork
训练网络。
net = trainNetwork(ds,layers,options);
Training on single CPU. Initializing input data normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | Accuracy | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:01 | 91.62% | 1.6825 | 0.0010 | | 17 | 50 | 00:00:17 | 88.56% | 0.2393 | 0.0010 | | 34 | 100 | 00:00:30 | 92.08% | 0.1672 | 0.0010 | | 50 | 150 | 00:00:43 | 93.17% | 0.1472 | 0.0010 | | 67 | 200 | 00:00:57 | 94.15% | 0.1313 | 0.0010 | | 84 | 250 | 00:01:14 | 94.47% | 0.1167 | 0.0010 | | 100 | 300 | 00:01:29 | 95.04% | 0.1100 | 0.0010 | |========================================================================================| Training finished: Max epochs completed.
测试网络
加载测试数据。为图像创建一个 imageDatastore
。为真实值像素标签创建一个 pixelLabelDatastore
。
imageFolderTest = fullfile(dataFolder,'testImages'); imdsTest = imageDatastore(imageFolderTest); labelFolderTest = fullfile(dataFolder,'testLabels'); pxdsTest = pixelLabelDatastore(labelFolderTest,classNames,labels);
使用测试数据和经过训练的网络进行预测。
pxdsPred = semanticseg(imdsTest,net,'MiniBatchSize',32,'WriteLocation',tempdir);
Running semantic segmentation network ------------------------------------- * Processed 100 images.
使用 evaluateSemanticSegmentation
评估预测准确度。
metrics = evaluateSemanticSegmentation(pxdsPred,pxdsTest);
Evaluating semantic segmentation results ---------------------------------------- * Selected metrics: global accuracy, class accuracy, IoU, weighted IoU, BF score. * Processed 100 images. * Finalizing... Done. * Data set metrics: GlobalAccuracy MeanAccuracy MeanIoU WeightedIoU MeanBFScore ______________ ____________ _______ ___________ ___________ 0.95237 0.97352 0.72081 0.92889 0.46416
有关评估语义分割网络的详细信息,请参阅evaluateSemanticSegmentation
(Computer Vision Toolbox)。
分割新图像
读取并显示测试图像 triangleTest.jpg
。
imgTest = imread('triangleTest.jpg');
figure
imshow(imgTest)
使用 semanticseg
分割测试图像,并使用 labeloverlay
显示结果。
C = semanticseg(imgTest,net); B = labeloverlay(imgTest,C); figure imshow(B)
另请参阅
pixelLabelDatastore
(Computer Vision Toolbox) | pixelLabelImageDatastore
(Computer Vision Toolbox) | semanticseg
(Computer Vision Toolbox) | labeloverlay
(Image Processing Toolbox) | countEachLabel
(Computer Vision Toolbox) | pixelClassificationLayer
(Computer Vision Toolbox) | trainingOptions
| trainNetwork
| evaluateSemanticSegmentation
(Computer Vision Toolbox) | convolution2dLayer
相关主题
- 使用深度学习进行语义分割
- 使用深度学习对多光谱图像进行语义分割
- Getting Started with Semantic Segmentation Using Deep Learning (Computer Vision Toolbox)
- Label Pixels for Semantic Segmentation (Computer Vision Toolbox)
- 预训练的深度神经网络