exponenta event banner

pixelLabelImageDatastore

Хранилище данных для семантических сетей сегментации

Описание

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

Создание

Описание

пример

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

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

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

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

Входные аргументы

развернуть все

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

Коллекция изображений, указанная как ImageDatastore объект.

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

Свойства

развернуть все

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

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

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

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

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

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

Предварительная обработка цветового канала для 2-D данных, указанных как '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. Для использования фонового диспетчеризации необходимо наличие Toolbox™ параллельных вычислений. Если DispatchInBackground является true и у вас есть панель инструментов параллельных вычислений, то pixelLabelImageDatastore асинхронно считывает исправления, добавляет шум и ставит в очередь пары исправлений.

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

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

Общее число наблюдений в хранилище данных денонсирующего изображения. Количество наблюдений - это продолжительность одной тренировочной эпохи.

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

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

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

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

  • 'resize' - Масштабирование изображения в соответствии с размером вывода. Дополнительные сведения см. в разделе imresize.

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

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

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

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

combineОбъединение данных из нескольких хранилищ данных
countEachLabelКоличество вхождений меток пикселов или полей
hasdataОпределение доступности данных для чтения
partitionByIndexРазделение pixelLabelImageDatastore по индексам
previewПредварительный просмотр подмножества данных в хранилище данных
readСчитывание данных из хранилища данных
readallСчитывание всех данных в хранилище данных
readByIndexСчитывание данных, указанных индексом из pixelLabelImageDatastore
resetСброс хранилища данных в исходное состояние
shuffleВозврат перетасованной версии хранилища данных
transformПреобразовать хранилище данных

Примеры

свернуть все

Загрузите данные обучения.

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

Создайте хранилище данных для изображений.

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 

Настройка параметров обучения.

opts = trainingOptions('sgdm', ...
    'InitialLearnRate',1e-3, ...
    'MaxEpochs',100, ...
    'MiniBatchSize',64);

Объединение хранилища данных изображения и пиксельной метки для обучения.

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)

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

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

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

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 и 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.

Совет

  • 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 объект, сгенерированный маркировщиком видео, используйте pixelLabelTrainingData функция.

См. также

Функции

  • (инструментарий для глубокого обучения)

Объекты

Представлен в R2018a