pixelLabelImageDatastore

Datastore для семантических сетей сегментации

Описание

Использовать pixelLabelImageDatastore создать datastore для настройки семантической сети сегментации с помощью глубокого обучения.

Создание

Описание

пример

pximds = pixelLabelImageDatastore(gTruth) возвращает datastore для настройки сети семантической сегментации на основе входа groundTruth объект или массив groundTruth объекты. Используйте выходные pixelLabelImageDatastore объект с функцией Deep Learning Toolbox™ trainNetwork (Deep Learning Toolbox) для обучения сверточных нейронных сетей семантической сегментации.

pximds = pixelLabelImageDatastore(imds,pxds) возвращает datastore, основанный на входных изображениях datastore и объектах datastore метки пикселя. imds является ImageDatastore объект, который представляет обучающий вход в сеть. pxds является PixelLabelDatastore объект, который представляет необходимый сетевой выход.

pximds = pixelLabelImageDatastore(___,Name,Value) дополнительно использует пары "имя-значение", чтобы задать DispatchInBackground и OutputSizeMode свойства. Для 2D данных можно также использовать пары "имя-значение", чтобы задать ColorPreprocessing, DataAugmentation, и OutputSize свойства увеличения. Можно задать несколько пары "имя-значение". Заключайте каждое имя свойства в кавычки.

Для примера, pixelLabelImageDatastore(gTruth,'PatchesPerImage',40) создает пиксель метки изображения datastore, который случайным образом генерирует 40 закрашенные фигуры от каждого объекта основной истины в gTruth.

Входные параметры

расширить все

Достоверные данные, заданные как groundTruth объект или как массив groundTruth объекты. Каждый groundTruth объект содержит информацию об источнике данных, списке определений меток и всех отмеченных метках для набора меток основной истины.

Набор изображений, заданная как ImageDatastore объект.

Набор пиксельных маркированных изображений, заданный как PixelLabelDatastore объект. Объект содержит пиксельные маркированные изображения для каждого изображения, содержащегося в imds входной объект.

Свойства

расширить все

Это свойство доступно только для чтения.

Имена файлов изображений, используемые в качестве источника для основных истин, заданные как вектор символов или массив ячеек из векторов символов.

Это свойство доступно только для чтения.

Данные о пиксельных метках имена файлов, используемые в качестве источника для основной истины изображений меток, заданные как символ или массив ячеек из символов.

Это свойство доступно только для чтения.

Имена классов, заданные как массив ячеек из векторов символов.

Предварительная обработка цветового канала для 2D данных, заданная как 'none', 'gray2rgb', или 'rgb2gray'. Используйте это свойство, когда вам нужны данные изображения, созданные источником данных, должны быть только цветными или полутоновыми, но набор обучающих данных включает в себя и то, и другое. Предположим, что вам нужно обучить сеть, которая ожидает цветных изображений, но некоторые из ваших обучающих изображений являются полутоновыми. Задайте ColorPreprocessing на 'gray2rgb' для репликации цветовых каналов полутоновых изображений в входе изображений. Использование 'gray2rgb' опция создает M выходных изображений -by- N -by-3.

The ColorPreprocessing свойство не поддерживается для 3-D данных. Для выполнения предварительной обработки цветового канала 3-D данных используйте transform функция.

Предварительная обработка, примененная к входным изображениям, задается как imageDataAugmenter (Deep Learning Toolbox) объект или 'none'. Когда DataAugmentation является 'none', никакая предварительная обработка не применяется к входным изображениям. Обучающие данные можно увеличить в режиме реального времени во время обучения.

The DataAugmentation свойство не поддерживается для 3-D данных. Для предварительной обработки 3-D данных используйте transform функция.

Отправляйте наблюдения в фоновом режиме во время обучения, предсказания и классификации, заданные как false или true. Чтобы использовать диспетчеризацию фона, вы должны иметь Toolbox™ Parallel Computing. Если DispatchInBackground является true и у вас есть Parallel Computing Toolbox, тогда pixelLabelImageDatastore асинхронно считывает закрашенные фигуры, добавляет шум и помещает патч- пары в очереди.

Количество наблюдений, возвращаемых в каждом пакете. Значение по умолчанию равно ReadSize изображения datastore imds. Можно изменить значение MiniBatchSize только после создания datastore. Для обучения, предсказания или классификации MiniBatchSize для свойства задан размер мини-пакета, заданный в trainingOptions (Deep Learning Toolbox).

Это свойство доступно только для чтения.

Общее количество наблюдений в denoizing image datastore. Количество наблюдений составляет длину одной эпохи обучения.

Это свойство доступно только для чтения.

Размер выходных изображений, заданный как вектор двух положительных целых чисел. Первый элемент задает количество строк в выходных изображениях, а второй элемент задает количество столбцов. Когда вы задаете OutputSize, размеры изображений регулируются по мере необходимости. По умолчанию это свойство пустое, что означает, что изображения не корректируются.

The OutputSize свойство не поддерживается для 3-D данных. Чтобы задать размер выхода 3-D данных, используйте transform функция.

Метод, используемый для изменения размера выходных изображений, заданный как одно из следующего. Это свойство применяется только при установке 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)

Figure contains an axes. The axes contains an object of type image.

Сегментируйте тестовое изображение с помощью semanticseg и отобразите результаты с помощью labeloverlay.

C = semanticseg(imgTest,net);
B = labeloverlay(imgTest,C);
figure
imshow(B)

Figure contains an axes. The axes contains an object of type image.

Совет

  • 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 функция.

Введенный в R2018a