Datastore для сетей семантической сегментации
Используйте pixelLabelImageDatastore
создать datastore для обучения сеть семантической сегментации использование глубокого обучения.
возвращает datastore для того, чтобы обучить сеть семантической сегментации на основе входа pximds
= pixelLabelImageDatastore(gTruth
)groundTruth
объект или массив groundTruth
объекты. Используйте выход pixelLabelImageDatastore
объект с Deep Learning Toolbox™ функционирует trainNetwork
обучать сверточные нейронные сети семантической сегментации.
возвращает 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
данные Ground TruthgroundTruth
возразите | массив groundTruth
объектыДостоверные данные, заданные как groundTruth
возразите или как массив groundTruth
объекты. Каждый groundTruth
объект содержит информацию об источнике данных, списке определений метки и всех отмеченных метках для набора меток основной истины.
imds
— Набор изображенийImageDatastore
объектНабор изображений, заданных как ImageDatastore
объект.
pxds
— Набор пикселя пометил изображенияPixelLabelDatastore
объектНабор пикселя пометил изображения, заданные как PixelLabelDatastore
объект. Объект содержит пиксель помеченные изображения для каждого изображения, содержавшегося в imds
входной объект.
Images
— Имена файла образаЭто свойство доступно только для чтения.
Имена файла образа, используемые в качестве источника для изображений основной истины, заданных как вектор символов или массив ячеек из символьных векторов.
PixelLabelData
— Имена файлов метки PixelЭто свойство доступно только для чтения.
Имена файлов данных о пиксельных метках, используемые в качестве источника для основной истины, помечают изображения, заданные как символ или массив ячеек символов.
ClassNames
— Имена классовЭто свойство доступно только для чтения.
Имена классов, заданные как массив ячеек из символьных векторов.
ColorPreprocessing
— Предварительная обработка цветового канала'none'
(значение по умолчанию) | 'gray2rgb'
| 'rgb2gray'
Предварительная обработка цветового канала для 2D данных, заданных как 'none'
, 'gray2rgb'
, или 'rgb2gray'
. Используйте это свойство, когда вам нужны данные изображения, созданные по условию, источник должен быть только цветной или шкалой полутонов, но набор обучающих данных включает обоих. Предположим, что необходимо обучить сеть, которая ожидает цветные изображения, но некоторые учебные изображения являются шкалой полутонов. Установите ColorPreprocessing
к 'gray2rgb'
реплицировать цветовые каналы полутоновых изображений во входном наборе изображений. Используя 'gray2rgb'
опция создает M-by-N-by-3 выходные изображения.
ColorPreprocessing
свойство не поддержано для 3-D данных. Чтобы выполнить предварительную обработку цветового канала 3-D данных, используйте transform
функция.
DataAugmentation
— Предварительная обработка применяется к входным изображениям'none'
(значение по умолчанию) | imageDataAugmenter
объектПредварительная обработка примененного к входным изображениям, заданным как imageDataAugmenter
объект или 'none'
. Когда DataAugmentation
'none'
, никакая предварительная обработка не применяется, чтобы ввести изображения. Обучающие данные могут быть увеличены в режиме реального времени во время обучения.
DataAugmentation
свойство не поддержано для 3-D данных. Чтобы предварительно обработать 3-D данные, используйте transform
функция.
DispatchInBackground
— Диспетчеризируйте наблюдения в фонеfalse
(значение по умолчанию) | true
Диспетчеризируйте наблюдения в фоновом режиме во время обучения, прогноза и классификации, заданной как false
или true
. Чтобы использовать фоновую диспетчеризацию, у вас должен быть Parallel Computing Toolbox™. Если DispatchInBackground
true
и у вас есть Parallel Computing Toolbox, затем pixelLabelImageDatastore
асинхронно закрашенные фигуры чтений, добавляет шум, и очереди исправляют пары.
MiniBatchSize
— Количество наблюдений в каждом пакетеКоличество наблюдений, которые возвращены в каждом пакете. Значение по умолчанию равно ReadSize
из datastore изображений imds
. Можно изменить значение MiniBatchSize
только после того, как вы создаете datastore. Для обучения, прогноза, или классификации, MiniBatchSize
свойство установлено в мини-пакетный размер, заданный в trainingOptions
.
NumObservations
— Общее количество наблюдений в datastoreЭто свойство доступно только для чтения.
Общее количество наблюдений в шумоподавлении отображает datastore. Количество наблюдений является продолжительностью одной учебной эпохи.
OutputSize
— Размер выходных изображений[]
(значение по умолчанию) | вектор двух положительных целых чиселЭто свойство доступно только для чтения.
Размер выходных изображений, заданных как вектор двух положительных целых чисел. Первый элемент задает количество строк в выходных изображениях, и второй элемент задает количество столбцов. Когда вы задаете OutputSize
, размеры изображения настроены по мере необходимости. По умолчанию это свойство пусто, что означает, что изображения не настроены.
OutputSize
свойство не поддержано для 3-D данных. Чтобы установить выходной размер 3-D данных, используйте transform
функция.
OutputSizeMode
— Метод раньше изменял размер выходных изображений'resize'
(значение по умолчанию) | 'centercrop'
| 'randcrop'
Метод раньше изменял размер выходных изображений, заданных как одно из следующих. Это свойство применяется только, когда вы устанавливаете OutputSize
к значению кроме []
.
'resize'
— Масштабируйте изображение, чтобы соответствовать выходному размеру. Для получения дополнительной информации смотрите imresize
.
'centercrop'
— Возьмите обрезку из центра учебного изображения. Обрезка имеет тот же размер как выходной размер.
'randcrop'
— Возьмите случайную обрезку из учебного изображения. Случайная обрезка имеет тот же размер как выходной размер.
Типы данных: char |
string
combine | Объедините данные от нескольких datastores |
countEachLabel | Считайте вхождение меток поля или пикселя |
hasdata | Определите, доступны ли данные для чтения |
partitionByIndex | Раздел pixelLabelImageDatastore согласно индексам |
preview | Подмножество данных в datastore |
read | Считайте данные из datastore |
readall | Считывайте все данные в datastore |
readByIndex | Считайте данные, заданные индексом от pixelLabelImageDatastore |
reset | Сброс Datastore к начальному состоянию |
shuffle | Переставьте данные в pixelLabelImageDatastore |
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),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 output cropping [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 GPU. Initializing image normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | Accuracy | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:00 | 31.86% | 0.6934 | 0.0010 | | 17 | 50 | 00:00:03 | 94.52% | 0.5564 | 0.0010 | | 34 | 100 | 00:00:07 | 95.25% | 0.4415 | 0.0010 | | 50 | 150 | 00:00:11 | 95.14% | 0.3722 | 0.0010 | | 67 | 200 | 00:00:14 | 94.52% | 0.3336 | 0.0010 | | 84 | 250 | 00:00:18 | 95.25% | 0.2931 | 0.0010 | | 100 | 300 | 00:00:21 | 95.14% | 0.2708 | 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 GPU. Initializing image normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | Accuracy | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:00 | 47.50% | 0.6925 | 0.0010 | | 17 | 50 | 00:00:04 | 19.67% | 0.6837 | 0.0010 | | 34 | 100 | 00:00:08 | 75.77% | 0.4433 | 0.0010 | | 50 | 150 | 00:00:12 | 85.00% | 0.4018 | 0.0010 | | 67 | 200 | 00:00:16 | 87.00% | 0.3568 | 0.0010 | | 84 | 250 | 00:00:20 | 88.03% | 0.3153 | 0.0010 | | 100 | 300 | 00:00:24 | 90.42% | 0.2890 | 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
Этот пример использует:
Задайте и создайте пользовательский слой классификации пикселей, который использует потерю Dice.
Можно использовать этот слой, чтобы обучить сети семантической сегментации. Чтобы узнать больше о создании пользовательских слоев глубокого обучения, смотрите, Задают Пользовательские Слои Глубокого обучения (Deep Learning Toolbox).
Поставьте на карту потерю
Потеря Dice основана на коэффициенте подобия Sørensen-Dice для измерения перекрытия между двумя сегментированными изображениями. Обобщенная потеря Dice [1,2] поскольку между одним изображением и соответствующая основная истина дают
,
где количество классов, число элементов по первым двум измерениям , и специфичный для класса фактор взвешивания, который управляет вкладом, который каждый класс делает к потере. обычно обратная область ожидаемой области:
Это взвешивание помогает возразить, что влияние более крупных областей на Dice выигрывает, и облегчает для сети изучать, как сегментировать меньшие области.
Шаблон слоя классификации
Скопируйте шаблон слоя классификации в новый файл в MATLAB®. Этот шаблон обрисовывает в общих чертах структуру слоя классификации и включает функции, которые задают поведение слоя. Остальная часть примера показывает, как завершить dicePixelClassificationLayer
.
classdef dicePixelClassificationLayer < nnet.layer.ClassificationLayer properties % Optional properties end methods function loss = forwardLoss(layer, Y, T) % Layer forward loss function goes here. end function dLdY = backwardLoss(layer, Y, T) % Layer backward loss function goes here. end end end
Объявите свойства слоя
По умолчанию пользовательские выходные слои имеют следующие свойства:
Name
— Имя слоя, заданное как вектор символов или скаляр строки. Чтобы включать этот слой в график слоя, необходимо задать непустое уникальное имя слоя. Если вы обучаете серийную сеть с этим слоем и Name
установлен в ''
, затем программное обеспечение автоматически присваивает имя в учебное время.
Description
— Короткое описание слоя, заданного как вектор символов или скаляр строки. Это описание появляется, когда слой отображен в Layer
массив. Если вы не задаете описание слоя, то программное обеспечение отображает имя класса слоя.
Type
— Тип слоя, заданного как вектор символов или скаляр строки. Значение Type
появляется, когда слой отображен в Layer
массив. Если вы не задаете тип слоя, то программное обеспечение отображает 'Classification layer'
или 'Regression layer'
.
Пользовательские слои классификации также имеют следующее свойство:
Classes
— Классы выходного слоя, заданного как категориальный вектор, массив строк, массив ячеек из символьных векторов или 'auto'
. Если Classes
'auto'
, затем программное обеспечение автоматически устанавливает классы в учебное время. Если вы задаете массив строк или массив ячеек из символьных векторов str
, затем программное обеспечение устанавливает классы выходного слоя к categorical(str,str)
. Значением по умолчанию является 'auto'
.
Если слой не имеет никаких других свойств, то можно не использовать properties
раздел.
Потеря Dice требует, чтобы маленькое постоянное значение предотвратило деление на нуль. Задайте свойство, Epsilon
, содержать это значение.
classdef dicePixelClassificationLayer < nnet.layer.ClassificationLayer properties(Constant) % Small constant to prevent division by zero. Epsilon = 1e-8; end ... end
Создайте функцию конструктора
Создайте функцию, которая создает слой и инициализирует свойства слоя. Задайте любые переменные, требуемые создать слой как входные параметры к функции конструктора.
Задайте дополнительное имя входного параметра, чтобы присвоить Name
свойство при создании.
function layer = dicePixelClassificationLayer(name) % layer = dicePixelClassificationLayer(name) creates a Dice % pixel classification layer with the specified name. % Set layer name. layer.Name = name; % Set layer description. layer.Description = 'Dice loss'; end
Создайте прямую функцию потерь
Создайте функцию с именем forwardLoss
это возвращает взвешенную перекрестную энтропийную потерю между прогнозами, сделанными сетью и учебными целями. Синтаксис для forwardLoss
loss = forwardLoss(layer, Y, T)
, где Y
выход предыдущего слоя и T
представляет учебные цели.
Для проблем семантической сегментации, размерностей T
совпадайте с размерностью Y
, где Y
4-D массив размера H
- W
- K
- N
, где K
количество классов и N
мини-пакетный размер.
Размер Y
зависит от выхода предыдущего слоя. Гарантировать тот Y
одного размера с T
, необходимо включать слой, который выводит правильный размер перед выходным слоем. Например, чтобы гарантировать тот Y
4-D массив музыки прогноза к K
классы, можно включать полносвязный слой размера K
или сверточный слой с K
фильтры сопровождаются softmax слоем перед выходным слоем.
function loss = forwardLoss(layer, Y, T) % loss = forwardLoss(layer, Y, T) returns the Dice loss between % the predictions Y and the training targets T. % Weights by inverse of region size. W = 1 ./ sum(sum(T,1),2).^2; intersection = sum(sum(Y.*T,1),2); union = sum(sum(Y.^2 + T.^2, 1),2); numer = 2*sum(W.*intersection,3) + layer.Epsilon; denom = sum(W.*union,3) + layer.Epsilon; % Compute Dice score. dice = numer./denom; % Return average Dice loss. N = size(Y,4); loss = sum((1-dice))/N; end
Создайте обратную функцию потерь
Создайте обратную функцию потерь, которая возвращает производные потери Dice относительно прогнозов Y
. Синтаксис для backwardLoss
loss = backwardLoss(layer, Y, T)
, где Y
выход предыдущего слоя и T
представляет учебные цели.
Размерности Y
и T
совпадают с входными параметрами в forwardLoss
.
function dLdY = backwardLoss(layer, Y, T) % dLdY = backwardLoss(layer, Y, T) returns the derivatives of % the Dice loss with respect to the predictions Y. % Weights by inverse of region size. W = 1 ./ sum(sum(T,1),2).^2; intersection = sum(sum(Y.*T,1),2); union = sum(sum(Y.^2 + T.^2, 1),2); numer = 2*sum(W.*intersection,3) + layer.Epsilon; denom = sum(W.*union,3) + layer.Epsilon; N = size(Y,4); dLdY = (2*W.*Y.*numer./denom.^2 - 2*W.*T./denom)./N; end
Завершенный слой
Завершенный слой обеспечивается в dicePixelClassificationLayer.m
.
classdef dicePixelClassificationLayer < nnet.layer.ClassificationLayer % This layer implements the generalized Dice loss function for training % semantic segmentation networks. properties(Constant) % Small constant to prevent division by zero. Epsilon = 1e-8; end methods function layer = dicePixelClassificationLayer(name) % layer = dicePixelClassificationLayer(name) creates a Dice % pixel classification layer with the specified name. % Set layer name. layer.Name = name; % Set layer description. layer.Description = 'Dice loss'; end function loss = forwardLoss(layer, Y, T) % loss = forwardLoss(layer, Y, T) returns the Dice loss between % the predictions Y and the training targets T. % Weights by inverse of region size. W = 1 ./ sum(sum(T,1),2).^2; intersection = sum(sum(Y.*T,1),2); union = sum(sum(Y.^2 + T.^2, 1),2); numer = 2*sum(W.*intersection,3) + layer.Epsilon; denom = sum(W.*union,3) + layer.Epsilon; % Compute Dice score. dice = numer./denom; % Return average Dice loss. N = size(Y,4); loss = sum((1-dice))/N; end function dLdY = backwardLoss(layer, Y, T) % dLdY = backwardLoss(layer, Y, T) returns the derivatives of % the Dice loss with respect to the predictions Y. % Weights by inverse of region size. W = 1 ./ sum(sum(T,1),2).^2; intersection = sum(sum(Y.*T,1),2); union = sum(sum(Y.^2 + T.^2, 1),2); numer = 2*sum(W.*intersection,3) + layer.Epsilon; denom = sum(W.*union,3) + layer.Epsilon; N = size(Y,4); dLdY = (2*W.*Y.*numer./denom.^2 - 2*W.*T./denom)./N; end end end
Совместимость графического процессора
Для совместимости графического процессора функции уровня должны поддержать входные параметры и возвратить выходные параметры типа gpuArray
. Любые другие функции, используемые слоем, должны сделать то же самое.
Функции MATLAB используются в forwardLoss
и backwardLoss
в dicePixelClassificationLayer
вся поддержка gpuArray
входные параметры, таким образом, слоем является совместимый графический процессор.
Проверяйте Выходную валидность слоя
Создайте экземпляр слоя.
layer = dicePixelClassificationLayer('dice');
Проверяйте валидность слоя слоя с помощью checkLayer
. Задайте допустимый входной размер, чтобы быть размером одного наблюдения за типичным входом к слою. Слой ожидает H
- W
- K
- N
входные параметры массивов, где K
количество классов и N
количество наблюдений в мини-пакете.
numClasses = 2;
validInputSize = [4 4 numClasses];
checkLayer(layer,validInputSize, 'ObservationDimension',4)
Running nnet.checklayer.OutputLayerTestCase .......... ....... Done nnet.checklayer.OutputLayerTestCase __________ Test Summary: 17 Passed, 0 Failed, 0 Incomplete, 0 Skipped. Time elapsed: 1.6227 seconds.
Тестовые сводные отчеты количество переданных, отказавших, неполные, и пропущенные тесты.
Используйте пользовательский слой в сети Семантической Сегментации
Создайте сеть семантической сегментации, которая использует dicePixelClassificationLayer
.
layers = [ imageInputLayer([32 32 1]) convolution2dLayer(3,64,'Padding',1) reluLayer maxPooling2dLayer(2,'Stride',2) convolution2dLayer(3,64,'Padding',1) reluLayer transposedConv2dLayer(4,64,'Stride',2,'Cropping',1) convolution2dLayer(1,2) softmaxLayer dicePixelClassificationLayer('dice')]
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 output cropping [1 1] 8 '' Convolution 2 1x1 convolutions with stride [1 1] and padding [0 0 0 0] 9 '' Softmax softmax 10 'dice' Classification Output Dice loss
Загрузите обучающие данные для семантической сегментации с помощью imageDatastore
и pixelLabelDatastore
.
dataSetDir = fullfile(toolboxdir('vision'),'visiondata','triangleImages'); imageDir = fullfile(dataSetDir,'trainingImages'); labelDir = fullfile(dataSetDir,'trainingLabels'); imds = imageDatastore(imageDir); classNames = ["triangle" "background"]; labelIDs = [255 0]; pxds = pixelLabelDatastore(labelDir, classNames, labelIDs);
Сопоставьте изображение и данные о пиксельных метках с помощью pixelLabelImageDatastore
.
ds = pixelLabelImageDatastore(imds,pxds);
Установите опции обучения и обучите сеть.
options = trainingOptions('sgdm', ... 'InitialLearnRate',1e-2, ... 'MaxEpochs',100, ... 'LearnRateDropFactor',1e-1, ... 'LearnRateDropPeriod',50, ... 'LearnRateSchedule','piecewise', ... 'MiniBatchSize',128); net = trainNetwork(ds,layers,options);
Training on single GPU. Initializing image normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | Accuracy | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:03 | 27.89% | 0.8346 | 0.0100 | | 50 | 50 | 00:00:34 | 89.67% | 0.6384 | 0.0100 | | 100 | 100 | 00:01:09 | 94.35% | 0.5024 | 0.0010 | |========================================================================================|
Оцените обучивший сеть путем сегментации тестового изображения и отображения результата сегментации.
I = imread('triangleTest.jpg');
[C,scores] = semanticseg(I,net);
B = labeloverlay(I,C);
figure
imshow(imtile({I,B}))
Обучите сеть семантической сегментации использование расширенных сверток.
Семантическая сеть сегментации классифицирует каждый пиксель в изображении, получая к изображение, которое сегментировано по классам. Приложения для семантической сегментации включают дорожную сегментацию для автономного управления автомобилем и сегментацию раковой клетки для медицинского диагностирования. Чтобы узнать больше, смотрите Начало работы С Семантической Сегментацией Используя Глубокое обучение.
Сети семантической сегментации как 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: {200×1 cell} ClassNames: {2×1 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 GPU. Initializing image normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | Accuracy | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:00 | 67.54% | 0.7098 | 0.0010 | | 17 | 50 | 00:00:03 | 84.60% | 0.3851 | 0.0010 | | 34 | 100 | 00:00:06 | 89.85% | 0.2536 | 0.0010 | | 50 | 150 | 00:00:09 | 93.39% | 0.1959 | 0.0010 | | 67 | 200 | 00:00:11 | 95.89% | 0.1559 | 0.0010 | | 84 | 250 | 00:00:14 | 97.29% | 0.1188 | 0.0010 | | 100 | 300 | 00:00:18 | 98.28% | 0.0970 | 0.0010 | |========================================================================================|
Тестирование сети
Загрузите тестовые данные. Создайте imageDatastore
для изображений. Создайте pixelLabelDatastore
для пиксельных меток основной истины.
imageFolderTest = fullfile(dataFolder,'testImages'); imdsTest = imageDatastore(imageFolderTest); labelFolderTest = fullfile(dataFolder,'testLabels'); pxdsTest = pixelLabelDatastore(labelFolderTest,classNames,labels);
Сделайте прогнозы с помощью тестовых данных, и обучил сеть.
pxdsPred = semanticseg(imdsTest,net,'WriteLocation',tempdir);
Running semantic segmentation network ------------------------------------- * Processing 100 images. * Progress: 100.00%
Оцените точность прогноза с помощью evaluateSemanticSegmentation
.
metrics = evaluateSemanticSegmentation(pxdsPred,pxdsTest);
Evaluating semantic segmentation results ---------------------------------------- * Selected metrics: global accuracy, class accuracy, IoU, weighted IoU, BF score. * Processing 100 images... [==================================================] 100% Elapsed time: 00:00:00 Estimated time remaining: 00:00:00 * Finalizing... Done. * Data set metrics: GlobalAccuracy MeanAccuracy MeanIoU WeightedIoU MeanBFScore ______________ ____________ _______ ___________ ___________ 0.98334 0.99107 0.85869 0.97109 0.68197
Для получения дополнительной информации об оценке сетей семантической сегментации смотрите 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 или Ground Truth Labeler, используйте pixelLabelTrainingData
функция.
У вас есть модифицированная версия этого примера. Вы хотите открыть этот пример со своими редактированиями?
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.