Datastore для семантических сетей сегментации
Использовать pixelLabelImageDatastore
создать datastore для настройки семантической сети сегментации с помощью глубокого обучения.
возвращает datastore для настройки сети семантической сегментации на основе входа pximds
= pixelLabelImageDatastore(gTruth
)groundTruth
объект или массив groundTruth
объекты. Используйте выходные pixelLabelImageDatastore
объект с функцией Deep Learning Toolbox™ trainNetwork
(Deep Learning Toolbox) для обучения сверточных нейронных сетей семантической сегментации.
возвращает datastore, основанный на входных изображениях datastore и объектах datastore метки пикселя. pximds
= pixelLabelImageDatastore(imds
,pxds
)imds
является ImageDatastore
объект, который представляет обучающий вход в сеть. pxds
является PixelLabelDatastore
объект, который представляет необходимый сетевой выход.
дополнительно использует пары "имя-значение", чтобы задать pximds
= pixelLabelImageDatastore(___,Name,Value
)DispatchInBackground
и OutputSizeMode
свойства. Для 2D данных можно также использовать пары "имя-значение", чтобы задать ColorPreprocessing
, DataAugmentation
, и OutputSize
свойства увеличения. Можно задать несколько пары "имя-значение". Заключайте каждое имя свойства в кавычки.
Для примера, pixelLabelImageDatastore(gTruth,'PatchesPerImage',40)
создает пиксель метки изображения datastore, который случайным образом генерирует 40 закрашенные фигуры от каждого объекта основной истины в gTruth
.
gTruth
- Достоверные данныеgroundTruth
объект | массив groundTruth
объектыДостоверные данные, заданные как groundTruth
объект или как массив groundTruth
объекты. Каждый groundTruth
объект содержит информацию об источнике данных, списке определений меток и всех отмеченных метках для набора меток основной истины.
imds
- Набор изображенийImageDatastore
объектНабор изображений, заданная как ImageDatastore
объект.
pxds
- Набор пиксельных маркированных изображенийPixelLabelDatastore
объектНабор пиксельных маркированных изображений, заданный как PixelLabelDatastore
объект. Объект содержит пиксельные маркированные изображения для каждого изображения, содержащегося в imds
входной объект.
Images
- Имена файлов изображенийЭто свойство доступно только для чтения.
Имена файлов изображений, используемые в качестве источника для основных истин, заданные как вектор символов или массив ячеек из векторов символов.
PixelLabelData
- Имена файлов меток пикселейЭто свойство доступно только для чтения.
Данные о пиксельных метках имена файлов, используемые в качестве источника для основной истины изображений меток, заданные как символ или массив ячеек из символов.
ClassNames
- Имена классовЭто свойство доступно только для чтения.
Имена классов, заданные как массив ячеек из векторов символов.
ColorPreprocessing
- Предварительная обработка цветового канала'none'
(по умолчанию) | 'gray2rgb'
| 'rgb2gray'
Предварительная обработка цветового канала для 2D данных, заданная как 'none'
, 'gray2rgb'
, или 'rgb2gray'
. Используйте это свойство, когда вам нужны данные изображения, созданные источником данных, должны быть только цветными или полутоновыми, но набор обучающих данных включает в себя и то, и другое. Предположим, что вам нужно обучить сеть, которая ожидает цветных изображений, но некоторые из ваших обучающих изображений являются полутоновыми. Задайте ColorPreprocessing
на 'gray2rgb'
для репликации цветовых каналов полутоновых изображений в входе изображений. Использование 'gray2rgb'
опция создает M выходных изображений -by- N -by-3.
The ColorPreprocessing
свойство не поддерживается для 3-D данных. Для выполнения предварительной обработки цветового канала 3-D данных используйте transform
функция.
DataAugmentation
- Предварительная обработка, примененная к входным изображениям'none'
(по умолчанию) | imageDataAugmenter
объектПредварительная обработка, примененная к входным изображениям, задается как imageDataAugmenter
(Deep Learning Toolbox) объект или 'none'
. Когда DataAugmentation
является 'none'
, никакая предварительная обработка не применяется к входным изображениям. Обучающие данные можно увеличить в режиме реального времени во время обучения.
The DataAugmentation
свойство не поддерживается для 3-D данных. Для предварительной обработки 3-D данных используйте transform
функция.
DispatchInBackground
- Диспетчерские наблюдения в фоновом режимеfalse
(по умолчанию) | true
Отправляйте наблюдения в фоновом режиме во время обучения, предсказания и классификации, заданные как false
или true
. Чтобы использовать диспетчеризацию фона, вы должны иметь Toolbox™ Parallel Computing. Если DispatchInBackground
является true
и у вас есть Parallel Computing Toolbox, тогда pixelLabelImageDatastore
асинхронно считывает закрашенные фигуры, добавляет шум и помещает патч- пары в очереди.
MiniBatchSize
- Количество наблюдений в каждой партииКоличество наблюдений, возвращаемых в каждом пакете. Значение по умолчанию равно ReadSize
изображения datastore imds
. Можно изменить значение MiniBatchSize
только после создания datastore. Для обучения, предсказания или классификации MiniBatchSize
для свойства задан размер мини-пакета, заданный в trainingOptions
(Deep Learning Toolbox).
NumObservations
- Общее количество наблюдений в datastoreЭто свойство доступно только для чтения.
Общее количество наблюдений в denoizing image datastore. Количество наблюдений составляет длину одной эпохи обучения.
OutputSize
- Размер выходных изображений[]
(по умолчанию) | вектор из двух положительных целых чиселЭто свойство доступно только для чтения.
Размер выходных изображений, заданный как вектор двух положительных целых чисел. Первый элемент задает количество строк в выходных изображениях, а второй элемент задает количество столбцов. Когда вы задаете OutputSize
, размеры изображений регулируются по мере необходимости. По умолчанию это свойство пустое, что означает, что изображения не корректируются.
The OutputSize
свойство не поддерживается для 3-D данных. Чтобы задать размер выхода 3-D данных, используйте transform
функция.
OutputSizeMode
- Метод, используемый для изменения размера выходных изображений'resize'
(по умолчанию) | 'centercrop'
| 'randcrop'
Метод, используемый для изменения размера выходных изображений, заданный как одно из следующего. Это свойство применяется только при установке OutputSize
к значению, отличному от []
.
'resize'
- Масштабирование изображения в соответствии с выходом. Для получения дополнительной информации см. imresize
.
'centercrop'
- Взять урожай из центра обучающего изображения. Обрезка имеет тот же размер, что и выход.
'randcrop'
- Взять случайный кадр из обучающего изображения. Случайный размер кадра совпадает с размером выхода.
Типы данных: char
| string
combine | Объедините данные из нескольких хранилищ данных |
countEachLabel | Количество вхождений меток пикселей или коробок |
hasdata | Определите, доступны ли данные для чтения |
partitionByIndex | Функции разделения pixelLabelImageDatastore согласно индексам |
preview | Предварительный просмотр подмножества данных в datastore |
read | Чтение данных из datastore |
readall | Чтение всех данных в datastore |
readByIndex | Считайте данные, заданные индексом, из pixelLabelImageDatastore |
reset | Сбросьте datastore в начальное состояние |
shuffle | Возврат перемещенной версии datastore |
transform | Преобразуйте datastore |
Загрузите обучающие данные.
dataSetDir = fullfile(toolboxdir('vision'),'visiondata','triangleImages'); imageDir = fullfile(dataSetDir,'trainingImages'); labelDir = fullfile(dataSetDir,'trainingLabels');
Создайте datastore для изображений.
imds = imageDatastore(imageDir);
Создайте pixelLabelDatastore
для меток основной истины пикселей.
classNames = ["triangle","background"]; labelIDs = [255 0]; pxds = pixelLabelDatastore(labelDir,classNames,labelIDs);
Визуализируйте обучающие изображения и основную истину пиксельные метки.
I = read(imds);
C = read(pxds);
I = imresize(I,5);
L = imresize(uint8(C{1}),5);
imshowpair(I,L,'montage')
Создайте сеть семантической сегментации. Эта сеть использует простую сеть семантической сегментации, основанную на проекте понижающей и повышающей дискретизации.
numFilters = 64; filterSize = 3; numClasses = 2; layers = [ imageInputLayer([32 32 1]) convolution2dLayer(filterSize,numFilters,'Padding',1) reluLayer() maxPooling2dLayer(2,'Stride',2) convolution2dLayer(filterSize,numFilters,'Padding',1) reluLayer() transposedConv2dLayer(4,numFilters,'Stride',2,'Cropping',1); convolution2dLayer(1,numClasses); softmaxLayer() pixelClassificationLayer() ]
layers = 10×1 Layer array with layers: 1 '' Image Input 32×32×1 images with 'zerocenter' normalization 2 '' Convolution 64 3×3 convolutions with stride [1 1] and padding [1 1 1 1] 3 '' ReLU ReLU 4 '' Max Pooling 2×2 max pooling with stride [2 2] and padding [0 0 0 0] 5 '' Convolution 64 3×3 convolutions with stride [1 1] and padding [1 1 1 1] 6 '' ReLU ReLU 7 '' Transposed Convolution 64 4×4 transposed convolutions with stride [2 2] and cropping [1 1 1 1] 8 '' Convolution 2 1×1 convolutions with stride [1 1] and padding [0 0 0 0] 9 '' Softmax softmax 10 '' Pixel Classification Layer Cross-entropy loss
Setup опций обучения.
opts = trainingOptions('sgdm', ... 'InitialLearnRate',1e-3, ... 'MaxEpochs',100, ... 'MiniBatchSize',64);
Объедините изображение и pixel label datastore для обучения.
trainingData = pixelLabelImageDatastore(imds,pxds);
Обучите сеть.
net = trainNetwork(trainingData,layers,opts);
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:00 | 58.11% | 1.3458 | 0.0010 | | 17 | 50 | 00:00:11 | 97.30% | 0.0924 | 0.0010 | | 34 | 100 | 00:00:23 | 98.09% | 0.0575 | 0.0010 | | 50 | 150 | 00:00:34 | 98.56% | 0.0424 | 0.0010 | | 67 | 200 | 00:00:46 | 98.48% | 0.0435 | 0.0010 | | 84 | 250 | 00:00:58 | 98.66% | 0.0363 | 0.0010 | | 100 | 300 | 00:01:09 | 98.90% | 0.0310 | 0.0010 | |========================================================================================|
Чтение и отображение тестового изображения.
testImage = imread('triangleTest.jpg');
imshow(testImage)
Сегментируйте тестовое изображение и отображайте результаты.
C = semanticseg(testImage,net); B = labeloverlay(testImage,C); imshow(B)
Улучшите результаты
Сеть не смогла сегментировать треугольники и классифицировала каждый пиксель как «фон». Обучение, по-видимому, идет хорошо с точностями обучения более 90%. Однако сеть научилась только классифицировать фоновый класс. Чтобы понять, почему это произошло, можно подсчитать вхождение каждой пиксельной метки на наборе данных.
tbl = countEachLabel(pxds)
tbl=2×3 table
Name PixelCount ImagePixelCount
______________ __________ _______________
{'triangle' } 10326 2.048e+05
{'background'} 1.9447e+05 2.048e+05
Большинство меток пикселей предназначены для фона. Плохие результаты обусловлены классом дисбалансом. Классовый дисбаланс смещает процесс обучения в пользу доминирующего класса. Вот почему каждый пиксель классифицируется как «фон». Чтобы исправить это, используйте взвешивание классов для балансировки классов. Существует несколько методов вычисления весов классов. Одним из распространенных методов является обратное взвешивание частот, где веса классов являются обратными частотам классов. Это увеличивает вес, придаваемый недостаточно представленным классам.
totalNumberOfPixels = sum(tbl.PixelCount); frequency = tbl.PixelCount / totalNumberOfPixels; classWeights = 1./frequency
classWeights = 2×1
19.8334
1.0531
Веса классов могут быть заданы с помощью pixelClassificationLayer
. Обновите последний слой, чтобы использовать pixelClassificationLayer
с обратными весами классов.
layers(end) = pixelClassificationLayer('Classes',tbl.Name,'ClassWeights',classWeights);
Обучите сеть снова.
net = trainNetwork(trainingData,layers,opts);
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:00 | 72.27% | 5.4135 | 0.0010 | | 17 | 50 | 00:00:11 | 94.84% | 0.1188 | 0.0010 | | 34 | 100 | 00:00:23 | 96.52% | 0.0871 | 0.0010 | | 50 | 150 | 00:00:35 | 97.29% | 0.0599 | 0.0010 | | 67 | 200 | 00:00:47 | 97.46% | 0.0628 | 0.0010 | | 84 | 250 | 00:00:59 | 97.64% | 0.0586 | 0.0010 | | 100 | 300 | 00:01:10 | 97.99% | 0.0451 | 0.0010 | |========================================================================================|
Повторите попытку сегментации тестового изображения.
C = semanticseg(testImage,net); B = labeloverlay(testImage,C); imshow(B)
Использование взвешивания классов для балансировки классов дало лучший результат сегментации. Дополнительные шаги по улучшению результатов включают увеличение количества эпох, используемых для обучения, добавление дополнительных обучающих данных или изменение сети.
Этот пример использует:
Сконфигурируйте pixel label image datastore, чтобы увеличить данные во время обучения.
Загрузите обучающие изображения и пиксельные метки.
dataSetDir = fullfile(toolboxdir('vision'),'visiondata','triangleImages'); imageDir = fullfile(dataSetDir,'trainingImages'); labelDir = fullfile(dataSetDir,'trainingLabels');
Создайте imageDatastore
объект для хранения обучающих изображений.
imds = imageDatastore(imageDir);
Задайте имена классов и связанные с ними идентификаторы меток.
classNames = ["triangle","background"]; labelIDs = [255 0];
Создайте pixelLabelDatastore
объект для хранения меток основной истины пикселей для обучающих изображений.
pxds = pixelLabelDatastore(labelDir, classNames, labelIDs);
Создайте imageDataAugmenter
объект для случайного поворота и зеркального отражения данных изображения.
augmenter = imageDataAugmenter('RandRotation',[-10 10],'RandXReflection',true)
augmenter = imageDataAugmenter with properties: FillValue: 0 RandXReflection: 1 RandYReflection: 0 RandRotation: [-10 10] RandScale: [1 1] RandXScale: [1 1] RandYScale: [1 1] RandXShear: [0 0] RandYShear: [0 0] RandXTranslation: [0 0] RandYTranslation: [0 0]
Создайте pixelLabelImageDatastore
объект для обучения сети с дополненными данными.
plimds = pixelLabelImageDatastore(imds,pxds,'DataAugmentation',augmenter)
plimds = pixelLabelImageDatastore with properties: Images: {200x1 cell} PixelLabelData: {200x1 cell} ClassNames: {2x1 cell} DataAugmentation: [1x1 imageDataAugmenter] ColorPreprocessing: 'none' OutputSize: [] OutputSizeMode: 'resize' MiniBatchSize: 1 NumObservations: 200 DispatchInBackground: 0
Обучите сеть семантической сегментации с помощью расширенных сверток.
Семантическая сеть сегментации классифицирует каждый пиксель в изображении, получая к изображение, которое сегментировано по классам. Приложения для семантической сегментации включают сегментацию дорог для автономного управления автомобилем и сегментацию раковых камер для медицинского диагностирования. Дополнительные сведения см. в разделе Начало работы с семантической сегментацией с использованием глубокого обучения.
Семантические сети сегментации, такие как DeepLab [1], широко используют расширенные свертки (также известные как атронные свертки), потому что они могут увеличить восприимчивое поле слоя (площадь входа, который могут видеть слои), не увеличивая количество параметров или расчетов.
Загрузка обучающих данных
Пример использует простой набор данных из изображений треугольника 32 на 32 в целях рисунка. Набор данных включает в себя сопровождающие пиксельные достоверные данные. Загрузите обучающие данные с помощью imageDatastore
и a 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: {}
Создайте сеть семантической сегментации
Этот пример использует простую сеть семантической сегментации, основанную на расширенных сверточках.
Создайте источник данных для обучающих данных и получите количество пикселей для каждой метки.
pximdsTrain = pixelLabelImageDatastore(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(pximdsTrain,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:00 | 91.62% | 1.6825 | 0.0010 | | 17 | 50 | 00:00:08 | 88.56% | 0.2393 | 0.0010 | | 34 | 100 | 00:00:15 | 92.08% | 0.1672 | 0.0010 | | 50 | 150 | 00:00:23 | 93.17% | 0.1472 | 0.0010 | | 67 | 200 | 00:00:31 | 94.15% | 0.1313 | 0.0010 | | 84 | 250 | 00:00:38 | 94.47% | 0.1167 | 0.0010 | | 100 | 300 | 00:00:46 | 95.04% | 0.1100 | 0.0010 | |========================================================================================|
Тестирование сети
Загрузите тестовые данные. Создайте 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
.
Сегментация нового изображения
Чтение и отображение тестового изображения triangleTest.jpg
.
imgTest = imread('triangleTest.jpg');
figure
imshow(imgTest)
Сегментируйте тестовое изображение с помощью semanticseg
и отобразите результаты с помощью labeloverlay
.
C = semanticseg(imgTest,net); B = labeloverlay(imgTest,C); figure imshow(B)
The pixelLabelDatastore
pxds
и imageDatastore
imds
хранить файлы, которые находятся в папке в лексикографическом порядке. Например, если у вас есть двенадцать файлов с именем 'file1.jpg'
, 'file2.jpg'
, …, 'file11.jpg'
, и 'file12.jpg'
, затем файлы хранятся в следующем порядке:
'file1.jpg'
'file10.jpg'
'file11.jpg'
'file12.jpg'
'file2.jpg'
'file3.jpg'
...'file9.jpg'
Если порядок файлов в pxds
и imds
не являются одинаковыми, тогда вы можете столкнуться с несоответствием, когда вы считываете основную истину изображение и соответствующие данные о метках с помощью pixelLabelImageDatastore
. Если это происходит, переименуйте файлы пиксельных меток так, чтобы они имели правильный порядок. Например, переименуйте 'file1.jpg'
, …, 'file9.jpg'
на 'file01.jpg'
, …, 'file09.jpg'
.
Чтобы извлечь данные семантической сегментации из groundTruth
объект, сгенерированный Video Labeler, используйте pixelLabelTrainingData
функция.
trainNetwork
(Deep Learning Toolbox)У вас есть измененная версия этого примера. Вы хотите открыть этот пример с вашими правками?
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.