pixelLabelImageDatastore

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

Описание

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

Создание

Описание

пример

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

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 выходные изображения.

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

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

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

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

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

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

Общее количество наблюдений в шумоподавлении отображает datastore. Количество наблюдений является продолжительностью одной учебной эпохи.

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

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

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

Метод раньше изменял размер выходных изображений в виде одного из следующих. Это свойство применяется только, когда вы устанавливаете OutputSize к значению кроме [].

  • 'resize' — Масштабируйте изображение, чтобы соответствовать выходному размеру. Для получения дополнительной информации смотрите imresize.

  • 'centercrop' — Возьмите обрезку из центра учебного изображения. Обрезка имеет тот же размер как выходной размер.

  • 'randcrop' — Возьмите случайную обрезку из учебного изображения. Случайная обрезка имеет тот же размер как выходной размер.

Типы данных: char | string

Функции объекта

combineОбъедините данные от нескольких datastores
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 = 
  10x1 Layer array with layers:

     1   ''   Image Input                  32x32x1 images with 'zerocenter' normalization
     2   ''   Convolution                  64 3x3 convolutions with stride [1  1] and padding [1  1  1  1]
     3   ''   ReLU                         ReLU
     4   ''   Max Pooling                  2x2 max pooling with stride [2  2] and padding [0  0  0  0]
     5   ''   Convolution                  64 3x3 convolutions with stride [1  1] and padding [1  1  1  1]
     6   ''   ReLU                         ReLU
     7   ''   Transposed Convolution       64 4x4 transposed convolutions with stride [2  2] and cropping [1  1  1  1]
     8   ''   Convolution                  2 1x1 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);

Создайте пиксельный 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:20 |       97.30% |       0.0924 |          0.0010 |
|      34 |         100 |       00:00:39 |       98.09% |       0.0575 |          0.0010 |
|      50 |         150 |       00:00:58 |       98.56% |       0.0424 |          0.0010 |
|      67 |         200 |       00:01:18 |       98.48% |       0.0435 |          0.0010 |
|      84 |         250 |       00:01:37 |       98.66% |       0.0363 |          0.0010 |
|     100 |         300 |       00:01:57 |       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(trainingData)
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:19 |       94.84% |       0.1188 |          0.0010 |
|      34 |         100 |       00:00:38 |       96.53% |       0.0871 |          0.0010 |
|      50 |         150 |       00:00:55 |       97.29% |       0.0599 |          0.0010 |
|      67 |         200 |       00:01:14 |       97.46% |       0.0628 |          0.0010 |
|      84 |         250 |       00:01:33 |       97.64% |       0.0586 |          0.0010 |
|     100 |         300 |       00:01:51 |       97.99% |       0.0451 |          0.0010 |
|========================================================================================|

Попытайтесь сегментировать тестовое изображение снова.

C = semanticseg(testImage,net);
B = labeloverlay(testImage,C);
imshow(B)

Используя взвешивание класса, чтобы сбалансировать классы привел к лучшему результату сегментации. Дополнительные шаги, чтобы улучшить результаты включают увеличение числа эпох, используемых в обучении, добавлении большего количества обучающих данных или изменении сети.

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

Загрузите учебные изображения и пиксельные метки.

dataSetDir = fullfile(toolboxdir('vision'),'visiondata','triangleImages');
imageDir = fullfile(dataSetDir,'trainingImages');
labelDir = fullfile(dataSetDir,'trainingLabels');

Создайте imageDatastore возразите, чтобы содержать учебные изображения.

imds = imageDatastore(imageDir);

Задайте имена классов и их связанную метку IDs.

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

Загрузите обучающие данные

Пример использует простой набор данных 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: {}

Создайте сеть Семантической Сегментации

Этот пример использует простую сеть семантической сегментации на основе расширенных сверток.

Создайте источник данных для обучающих данных и получите количество пикселей для каждой метки.

pximdsTrain = pixelLabelImageDatastore(imdsTrain,pxdsTrain);
tbl = countEachLabel(pximdsTrain)
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:10 |       88.56% |       0.2393 |          0.0010 |
|      34 |         100 |       00:00:19 |       92.08% |       0.1672 |          0.0010 |
|      50 |         150 |       00:00:30 |       93.17% |       0.1472 |          0.0010 |
|      67 |         200 |       00:00:39 |       94.15% |       0.1313 |          0.0010 |
|      84 |         250 |       00:00:47 |       94.47% |       0.1167 |          0.0010 |
|     100 |         300 |       00:00:55 |       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)

Советы

  • 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