В этом примере показано, как определить и создать пользовательский слой классификации пикселей, который использует потери Тверского.
Этот слой может использоваться для обучения сетей семантической сегментации. Дополнительные сведения о создании пользовательских слоев глубокого обучения см. в разделе «Определение пользовательских слоев глубокого обучения» (Deep Learning Toolbox).
Тверская потеря основана на индексе Тверского для измерения перекрытия между двумя сегментированными изображениями [1]. Индекс Тверского между одним изображением и соответствующая основная истина дается
соответствует классу и соответствует отсутствию в классе .
количество элементов по первым двум размерностям .
и являются весовыми факторами, которые контролируют вклад, который ложные срабатывания и ложные срабатывания для каждого класса вносят в потерю.
Потеря по количеству классов дается
Скопируйте шаблон слоя классификации в новый файл в MATLAB ®. Этот шаблон описывает структуру слоя классификации и включает функции, которые определяют поведение слоя. В остальном примере показано, как выполнить tverskyPixelClassificationLayer
.
classdef tverskyPixelClassificationLayer < nnet.layer.ClassificationLayer properties % Optional properties end methods function loss = forwardLoss(layer, Y, T) % Layer forward 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
раздел.
Тверская потеря требует небольшого постоянного значения, чтобы предотвратить деление на нули. Задайте свойство, Epsilon
, чтобы удержать это значение. Это также требует двух свойств переменной A lpha
и Beta
которые контролируют взвешивание ложных срабатываний и ложных срабатываний, соответственно.
classdef tverskyPixelClassificationLayer < nnet.layer.ClassificationLayer properties(Constant) % Small constant to prevent division by zero. Epsilon = 1e-8; end properties % Default weighting coefficients for false positives and false negatives Alpha = 0.5; Beta = 0.5; end ... end
Создайте функцию, которая создает слой и инициализирует свойства слоя. Задайте любые переменные, необходимые для создания слоя в качестве входов для функции конструктора.
Задайте необязательное имя входного параметра для присвоения Name
свойство при создании.
function layer = tverskyPixelClassificationLayer(name, alpha, beta) % layer = tverskyPixelClassificationLayer(name) creates a Tversky % pixel classification layer with the specified name. % Set layer name layer.Name = name; % Set layer properties layer.Alpha = alpha; layer.Beta = beta; % Set layer description layer.Description = 'Tversky loss'; end
Создайте функцию с именем forwardLoss
это возвращает взвешенные потери перекрестной энтропии между предсказаниями, сделанными сетью, и целями обучения. Синтаксис для forwardLoss
является loss = forwardLoss(layer,Y,T)
, где Y
- выход предыдущего слоя и T
представляет цели обучения.
Для семантических задач сегментации, размерности T
соответствовать размерности Y
, где Y
- 4-D массив размера H
-by- W
-by- K
-by- 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 Tversky loss between % the predictions Y and the training targets T. Pcnot = 1-Y; Gcnot = 1-T; TP = sum(sum(Y.*T,1),2); FP = sum(sum(Y.*Gcnot,1),2); FN = sum(sum(Pcnot.*T,1),2); numer = TP + layer.Epsilon; denom = TP + layer.Alpha*FP + layer.Beta*FN + layer.Epsilon; % Compute Tversky index lossTIc = 1 - numer./denom; lossTI = sum(lossTIc,3); % Return average Tversky index loss N = size(Y,4); loss = sum(lossTI)/N; end
Как forwardLoss
функция полностью поддерживает автоматическую дифференциацию, нет необходимости создавать функцию для обратных потерь.
Список функций, поддерживающих автоматическую дифференциацию, см. в Списке функций с поддержкой dlarray (Deep Learning Toolbox).
Завершенный слой обеспечен в tverskyPixelClassificationLayer.m
.
classdef tverskyPixelClassificationLayer < nnet.layer.ClassificationLayer % This layer implements the Tversky loss function for training % semantic segmentation networks. % References % Salehi, Seyed Sadegh Mohseni, Deniz Erdogmus, and Ali Gholipour. % "Tversky loss function for image segmentation using 3D fully % convolutional deep networks." International Workshop on Machine % Learning in Medical Imaging. Springer, Cham, 2017. % ---------- properties(Constant) % Small constant to prevent division by zero. Epsilon = 1e-8; end properties % Default weighting coefficients for False Positives and False % Negatives Alpha = 0.5; Beta = 0.5; end methods function layer = tverskyPixelClassificationLayer(name, alpha, beta) % layer = tverskyPixelClassificationLayer(name, alpha, beta) creates a Tversky % pixel classification layer with the specified name and properties alpha and beta. % Set layer name. layer.Name = name; layer.Alpha = alpha; layer.Beta = beta; % Set layer description. layer.Description = 'Tversky loss'; end function loss = forwardLoss(layer, Y, T) % loss = forwardLoss(layer, Y, T) returns the Tversky loss between % the predictions Y and the training targets T. Pcnot = 1-Y; Gcnot = 1-T; TP = sum(sum(Y.*T,1),2); FP = sum(sum(Y.*Gcnot,1),2); FN = sum(sum(Pcnot.*T,1),2); numer = TP + layer.Epsilon; denom = TP + layer.Alpha*FP + layer.Beta*FN + layer.Epsilon; % Compute tversky index lossTIc = 1 - numer./denom; lossTI = sum(lossTIc,3); % Return average tversky index loss. N = size(Y,4); loss = sum(lossTI)/N; end end end
Функции MATLAB, используемые в forwardLoss
в tverskyPixelClassificationLayer
все gpuArray поддержки
вводит, поэтому слой совместим с графическим процессором.
Создайте образец слоя.
layer = tverskyPixelClassificationLayer('tversky',0.7,0.3);
Проверьте валидность слоя при помощи checkLayer
(Deep Learning Toolbox). Задайте допустимый размер входного сигнала, чтобы быть размером одного наблюдения типового входа для слоя. Слой ожидает H
-by- W
-by- K
-by- N
входы массива, где K
количество классов и N
количество наблюдений в мини-пакете.
numClasses = 2;
validInputSize = [4 4 numClasses];
checkLayer(layer,validInputSize, 'ObservationDimension',4)
Skipping GPU tests. No compatible GPU device found. Skipping code generation compatibility tests. To check validity of the layer for code generation, specify the 'CheckCodegenCompatibility' and 'ObservationDimension' options. Running nnet.checklayer.TestOutputLayerWithoutBackward ........ Done nnet.checklayer.TestOutputLayerWithoutBackward __________ Test Summary: 8 Passed, 0 Failed, 0 Incomplete, 2 Skipped. Time elapsed: 1.083 seconds.
В сводных данных тестов указывается количество пройденных, неудачных, неполных и пропущенных тестов.
Создайте семантическую сеть сегментации, которая использует tverskyPixelClassificationLayer
.
layers = [ imageInputLayer([32 32 1]) convolution2dLayer(3,64,'Padding',1) batchNormalizationLayer reluLayer maxPooling2dLayer(2,'Stride',2) convolution2dLayer(3,64,'Padding',1) reluLayer transposedConv2dLayer(4,64,'Stride',2,'Cropping',1) convolution2dLayer(1,2) softmaxLayer tverskyPixelClassificationLayer('tversky',0.3,0.7)]
layers = 11x1 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 '' Batch Normalization Batch normalization 4 '' ReLU ReLU 5 '' Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 6 '' Convolution 64 3x3 convolutions with stride [1 1] and padding [1 1 1 1] 7 '' ReLU ReLU 8 '' Transposed Convolution 64 4x4 transposed convolutions with stride [2 2] and cropping [1 1 1 1] 9 '' Convolution 2 1x1 convolutions with stride [1 1] and padding [0 0 0 0] 10 '' Softmax softmax 11 'tversky' Classification Output Tversky 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('adam', ... 'InitialLearnRate',1e-3, ... 'MaxEpochs',100, ... 'LearnRateDropFactor',5e-1, ... 'LearnRateDropPeriod',20, ... 'LearnRateSchedule','piecewise', ... 'MiniBatchSize',50); net = trainNetwork(ds,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 | 50.32% | 1.2933 | 0.0010 | | 13 | 50 | 00:00:08 | 98.83% | 0.0988 | 0.0010 | | 25 | 100 | 00:00:15 | 99.33% | 0.0547 | 0.0005 | | 38 | 150 | 00:00:21 | 99.37% | 0.0473 | 0.0005 | | 50 | 200 | 00:00:28 | 99.48% | 0.0400 | 0.0003 | | 63 | 250 | 00:00:36 | 99.48% | 0.0383 | 0.0001 | | 75 | 300 | 00:00:43 | 99.54% | 0.0348 | 0.0001 | | 88 | 350 | 00:00:50 | 99.51% | 0.0353 | 6.2500e-05 | | 100 | 400 | 00:00:57 | 99.56% | 0.0331 | 6.2500e-05 | |========================================================================================|
Оцените обученную сеть, сегментировав тестовое изображение и отобразив результат сегментации.
I = imread('triangleTest.jpg');
[C,scores] = semanticseg(I,net);
B = labeloverlay(I,C);
montage({I,B})
[1] Салехи, Сейед Садег Мохсени, Дениз Эрдогмус и Али Голипур. «Функция потерь Тверского для сегментации изображений 3D используя полностью сверточные глубокие сети». Международный семинар по машинному обучению в медицинской визуализации. Спрингер, Чэм, 2017.