Задайте пользовательский слой классификации пикселей с потерей Tversky

В этом примере показано, как задать и создать пользовательский слой классификации пикселей, который использует потерю Tversky.

Этот слой может использоваться, чтобы обучить сети семантической сегментации. Чтобы узнать больше о создании пользовательских слоев глубокого обучения, смотрите, Задают Пользовательские Слои Глубокого обучения (Deep Learning Toolbox).

Потеря Tversky

Потеря Tversky основана на индексе Tversky для измерения перекрытия между двумя сегментированными изображениями [1]. Индекс Tversky TIc между одним изображением Y и соответствующая основная истина T дают

TIc=m=1MYcmTcmm=1MYcmTcm+αm=1MYcmTcm+βm=1MYcmTcm

  • c соответствует классу и cсоответствует тому, чтобы не быть в классе c.

  • M число элементов по первым двум измерениям Y.

  • α и β взвешивают факторы, которые управляют вкладом, который ложные положительные стороны и ложные отрицательные стороны для каждого класса делают к потере.

Потеря Lпо количеству классов C дают

L=c=1C1-TIc

Шаблон слоя классификации

Скопируйте шаблон слоя классификации в новый файл в 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 раздел.

Потеря Tversky требует, чтобы маленькое постоянное значение предотвратило деление на нуль. Задайте свойство, Epsilon, содержать это значение. Также требуется два переменных свойства Alpha и 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- 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 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

Совместимость с GPU

Функции MATLAB используются в forwardLoss в tverskyPixelClassificationLayer вся поддержка gpuArray входные параметры, таким образом, слоем является совместимый графический процессор.

Проверяйте Выходную валидность слоя

Создайте экземпляр слоя.

layer = tverskyPixelClassificationLayer('tversky',0.7,0.3);

Проверяйте валидность слоя при помощи checkLayer. Задайте допустимый входной размер, чтобы быть размером одного наблюдения за типичным входом к слою. Слой ожидает H- W- K- N входные параметры массивов, где K количество классов и N количество наблюдений в мини-пакете.

numClasses = 2;
validInputSize = [4 4 numClasses];
checkLayer(layer,validInputSize, 'ObservationDimension',4)
Skipping GPU tests. No compatible GPU device found.
 
Running nnet.checklayer.TestOutputLayerWithoutBackward
........
Done nnet.checklayer.TestOutputLayerWithoutBackward
__________

Test Summary:
	 8 Passed, 0 Failed, 0 Incomplete, 2 Skipped.
	 Time elapsed: 0.87271 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.82% |       0.0985 |          0.0010 |
|      25 |         100 |       00:00:15 |       99.32% |       0.0545 |          0.0005 |
|      38 |         150 |       00:00:23 |       99.37% |       0.0472 |          0.0005 |
|      50 |         200 |       00:00:30 |       99.48% |       0.0401 |          0.0003 |
|      63 |         250 |       00:00:37 |       99.48% |       0.0379 |          0.0001 |
|      75 |         300 |       00:00:47 |       99.54% |       0.0348 |          0.0001 |
|      88 |         350 |       00:00:55 |       99.51% |       0.0351 |      6.2500e-05 |
|     100 |         400 |       00:01:04 |       99.56% |       0.0330 |      6.2500e-05 |
|========================================================================================|

Оцените обученную сеть, сегментировав тестовое изображение и отобразив результат сегментации.

I = imread('triangleTest.jpg');
[C,scores] = semanticseg(I,net);

B = labeloverlay(I,C);
montage({I,B})

Ссылки

[1] Salehi, Сейед Сэдег Мохсени, Дениз Эрдогмус и Али Голипур. "Функция потерь Tversky для сегментации изображений с помощью 3D полностью сверточных глубоких сетей". Международный семинар на Машинном обучении в Медицинской Обработке изображений. Спрингер, Хан, 2017.