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

Если Deep Learning Toolbox™ не обеспечивает слой, вы требуете для своей классификации или проблемы регрессии, то можно задать собственный слой с помощью этого примера в качестве руководства. Для списка встроенных слоев смотрите Список слоев глубокого обучения.

Чтобы задать пользовательский слой глубокого обучения, можно использовать шаблон, обеспеченный в этом примере, который берет вас через следующие шаги:

  1. Назовите слой – дают слою имя так, чтобы это могло использоваться в MATLAB®.

  2. Объявите, что свойства слоя – задают свойства слоя и какие параметры изучены во время обучения.

  3. Создайте (дополнительную) функцию конструктора – задают, как создать слой и инициализировать его свойства. Если вы не задаете функцию конструктора, то при создании, программное обеспечение инициализирует NameОписание, и Type свойства с [] и определяет номер вводов и выводов слоя к 1.

  4. Создайте прямые функции – задают, как данные передают вперед через слой (прямое распространение) во время прогноза и в учебное время.

  5. Создайте обратную (дополнительную) функцию – задают производные потери относительно входных данных и learnable параметров (обратное распространение). Если вы не задаете обратную функцию, то прямые функции должны поддержать dlarray объекты.

В этом примере показано, как создать взвешенный слой сложения, который является слоем с несколькими входными параметрами и learnable параметром, и используйте его в сверточной нейронной сети. Взвешенный слой сложения масштабирует и добавляет входные параметры из нескольких поэлементных слоев нейронной сети.

Слой с шаблоном параметров Learnable

Скопируйте слой с learnable шаблоном параметров в новый файл в MATLAB. Этот шаблон обрисовывает в общих чертах структуру слоя learnable параметрами и включает функции, которые задают поведение слоя.

classdef myLayer < nnet.layer.Layer

    properties
        % (Optional) Layer properties.

        % Layer properties go here.
    end

    properties (Learnable)
        % (Optional) Layer learnable parameters.

        % Layer learnable parameters go here.
    end
    
    methods
        function layer = myLayer()
            % (Optional) Create a myLayer.
            % This function must have the same name as the class.

            % Layer constructor function goes here.
        end
        
        function [Z1, …, Zm] = predict(layer, X1, …, Xn)
            % Forward input data through the layer at prediction time and
            % output the result.
            %
            % Inputs:
            %         layer       - Layer to forward propagate through
            %         X1, ..., Xn - Input data
            % Outputs:
            %         Z1, ..., Zm - Outputs of layer forward function
            
            % Layer forward function for prediction goes here.
        end

        function [Z1, …, Zm, memory] = forward(layer, X1, …, Xn)
            % (Optional) Forward input data through the layer at training
            % time and output the result and a memory value.
            %
            % Inputs:
            %         layer       - Layer to forward propagate through
            %         X1, ..., Xn - Input data
            % Outputs:
            %         Z1, ..., Zm - Outputs of layer forward function
            %         memory      - Memory value for custom backward propagation

            % Layer forward function for training goes here.
        end

        function [dLdX1, …, dLdXn, dLdW1, …, dLdWk] = ...
                backward(layer, X1, …, Xn, Z1, …, Zm, dLdZ1, …, dLdZm, memory)
            % (Optional) Backward propagate the derivative of the loss  
            % function through the layer.
            %
            % Inputs:
            %         layer             - Layer to backward propagate through
            %         X1, ..., Xn       - Input data
            %         Z1, ..., Zm       - Outputs of layer forward function            
            %         dLdZ1, ..., dLdZm - Gradients propagated from the next layers
            %         memory            - Memory value from forward function
            % Outputs:
            %         dLdX1, ..., dLdXn - Derivatives of the loss with respect to the
            %                             inputs
            %         dLdW1, ..., dLdWk - Derivatives of the loss with respect to each
            %                             learnable parameter
            
            % Layer backward function goes here.
        end
    end
end

Назовите слой

Во-первых, дайте слою имя. В первой линии файла класса замените существующее имя myLayer с weightedAdditionLayer.

classdef weightedAdditionLayer < nnet.layer.Layer
    ...
end

Затем переименуйте myLayer функция конструктора (первая функция в methods разделите) так, чтобы это имело то же имя как слой.

    methods
        function layer = weightedAdditionLayer()           
            ...
        end

        ...
     end

Сохраните слой

Сохраните файл класса слоя в новом файле с именем weightedAdditionLayer.m. Имя файла должно совпадать с именем слоя. Чтобы использовать слой, необходимо сохранить файл в текущей папке или в папке на пути MATLAB.

Объявите свойства и параметры Learnable

Объявите свойства слоя в properties разделите и объявите learnable параметры путем листинга их в properties (Learnable) раздел.

По умолчанию пользовательские промежуточные слои имеют эти свойства:

СвойствоОписание
Name Имя слоя, заданное как вектор символов или скаляр строки. Чтобы включать слой в график слоя, необходимо задать непустое уникальное имя слоя. Если вы обучаете серийную сеть со слоем и Name установлен в '', затем программное обеспечение автоматически присваивает имя к слою в учебное время.
Description

Короткое описание слоя, заданного как вектор символов или скаляр строки. Это описание появляется, когда слой отображен в Layer массив. Если вы не задаете описание слоя, то программное обеспечение отображает имя класса слоя.

TypeТип слоя, заданного как вектор символов или скаляр строки. Значение Type появляется, когда слой отображен в Layer массив. Если вы не задаете тип слоя, то программное обеспечение отображает имя класса слоя.
NumInputsКоличество входных параметров слоя, заданного как положительное целое число. Если вы не задаете это значение, то программное обеспечение автоматически устанавливает NumInputs к количеству имен в InputNames. Значение по умолчанию равняется 1.
InputNamesВходные имена слоя, заданного как массив ячеек из символьных векторов. Если вы не задаете это значение и NumInputs больше 1, затем программное обеспечение автоматически устанавливает InputNames к {'in1',...,'inN'}, где N равно NumInputs. Значением по умолчанию является {'in'}.
NumOutputsКоличество выходных параметров слоя, заданного как положительное целое число. Если вы не задаете это значение, то программное обеспечение автоматически устанавливает NumOutputs к количеству имен в OutputNames. Значение по умолчанию равняется 1.
OutputNamesВыходные имена слоя, заданного как массив ячеек из символьных векторов. Если вы не задаете это значение и NumOutputs больше 1, затем программное обеспечение автоматически устанавливает OutputNames к {'out1',...,'outM'}, где M равно NumOutputs. Значением по умолчанию является {'out'}.

Если слой не имеет никаких других свойств, то можно не использовать properties раздел.

Совет

Если вы создаете слой с несколькими входными параметрами, то необходимо установить любого NumInputs или InputNames в конструкторе слоя. Если вы создаете слой с несколькими выходными параметрами, то необходимо установить любого NumOutputs или OutputNames в конструкторе слоя.

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

Взвешенный слой сложения имеет только один learnable параметр, веса. Объявите этот learnable параметр в properties (Learnable) разделите и вызовите параметр Weights.

    properties (Learnable)
        % Layer learnable parameters
            
        % Scaling coefficients
        Weights
    end

Создайте функцию конструктора

Создайте функцию, которая создает слой и инициализирует свойства слоя. Задайте любые переменные, требуемые создать слой как входные параметры к функции конструктора.

Взвешенная функция конструктора слоя сложения требует двух входных параметров: количество входных параметров к слою и имени слоя. Это количество входных параметров к слою задает размер learnable параметра Weights. Задайте два входных параметра под названием numInputs и name в weightedAdditionLayer функция. Добавьте комментарий в верхнюю часть функции, которая объясняет синтаксис функции.

        function layer = weightedAdditionLayer(numInputs,name)
            % layer = weightedAdditionLayer(numInputs,name) creates a
            % weighted addition layer and specifies the number of inputs
            % and the layer name.
            
            ...
        end

Инициализируйте свойства слоя

Инициализируйте свойства слоя, включая learnable параметры, в функции конструктора. Замените комментарий % Layer constructor function goes here с кодом, который инициализирует свойства слоя.

Установите NumInputs свойство к входному параметру numInputs.

            % Set number of inputs.
            layer.NumInputs = numInputs;

Установите Name свойство к входному параметру name.

            % Set layer name.
            layer.Name = name;

Дайте слою короткое описание путем установки Description свойство слоя. Установите описание описывать тип слоя и его размера.

            % Set layer description.
            layer.Description = "Weighted addition of " + numInputs + ...
                " inputs";

Взвешенный слой сложения умножает каждый вход слоя на соответствующий коэффициент в Weights и добавляет получившиеся значения вместе. Инициализируйте learnable параметр Weights быть случайным вектором размера 1 numInputs. Weights свойство расположенного на слое объекта, таким образом, необходимо присвоить вектор layer.Weights.

            % Initialize layer weights
            layer.Weights = rand(1,numInputs);

Просмотрите завершенную функцию конструктора.

        function layer = weightedAdditionLayer(numInputs,name) 
            % layer = weightedAdditionLayer(numInputs,name) creates a
            % weighted addition layer and specifies the number of inputs
            % and the layer name.

            % Set number of inputs.
            layer.NumInputs = numInputs;

            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "Weighted addition of " + numInputs +  ... 
                " inputs";
        
            % Initialize layer weights.
            layer.Weights = rand(1,numInputs); 
        end

С этой функцией конструктора, команда weightedAdditionLayer(3,'add') создает взвешенный слой сложения с тремя входными параметрами и именем 'add'.

Создайте прямые функции

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

Создайте функцию с именем predict это распространяет данные вперед через слой во время прогноза и выводит результат.

Синтаксис для predict

[Z1,…,Zm] = predict(layer,X1,…,Xn)
где X1,…,Xn n входные параметры слоя и Z1,…,Zm m слой выходные параметры. Значения n и m должен соответствовать NumInputs и NumOutputs свойства слоя.

Совет

Если количество входных параметров к predict может варьироваться, затем использовать varargin вместо X1,…,Xn. В этом случае, varargin массив ячеек входных параметров, где varargin{i} соответствует Xi. Если количество выходных параметров может варьироваться, то используйте varargout вместо Z1,…,Zm. В этом случае, varargout массив ячеек выходных параметров, где varargout{j} соответствует Zj.

Поскольку взвешенный слой сложения имеет только один выход и переменное количество входных параметров, синтаксиса для predict для взвешенного сложения слоем является Z = predict(layer,varargin), где varargin{i} соответствует Xi для положительных целых чисел i меньше чем или равный NumInputs.

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

Размерности входных параметров зависят от типа данных и выхода связанных слоев:

Вход слояВведите размерРазмерность наблюдения
2D изображенияh-by-w-by-c-by-N, где h, w и c соответствуют высоте, ширине, и количеству каналов изображений соответственно и N, является количеством наблюдений.4
3-D изображенияh-by-w-by-D-by-c-by-N, где h, w, D и c соответствуют высоте, ширине, глубине, и количеству каналов 3-D изображений соответственно и N, является количеством наблюдений.5
Векторные последовательностиc-by-N-by-S, где c является количеством функций последовательностей, N, является количеством наблюдений, и S является длиной последовательности.2
2D последовательности изображенийh-by-w-by-c-by-N-by-S, где h, w и c соответствуют высоте, ширине и количеству каналов изображений соответственно, N, является количеством наблюдений, и S является длиной последовательности.4
3-D последовательности изображенийh-by-w-by-d-by-c-by-N-by-S, где h, w, d и c соответствуют высоте, ширине, глубине и количеству каналов 3-D изображений соответственно, N, является количеством наблюдений, и S является длиной последовательности.5

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

Синтаксис для forward

[Z1,…,Zm,memory] = forward(layer,X1,…,Xn)
где X1,…,Xn n входные параметры слоя, Z1,…,Zm m слой выходные параметры и memory память о слое.

Совет

Если количество входных параметров к forward может варьироваться, затем использовать varargin вместо X1,…,Xn. В этом случае, varargin массив ячеек входных параметров, где varargin{i} соответствует Xi. Если количество выходных параметров может варьироваться, то используйте varargout вместо Z1,…,Zm. В этом случае, varargout массив ячеек выходных параметров, где varargout{j} соответствует Zj для j=1, …, NumOutputs и varargout{NumOutputs+1} соответствует memory.

Прямая функция взвешенного слоя сложения

f(X(1),,X(n))=i=1nWiX(i)

где X(1), …, X(n) соответствует входным параметрам слоя и W1, …, Wn веса слоя.

Реализуйте прямую функцию в predict. В predict, выход Z соответствует f(X(1),,X(n)). Взвешенный слой сложения не требует памяти или различной прямой функции для обучения, таким образом, можно удалить forward функция из файла класса. Добавьте комментарий в верхнюю часть функции, которая объясняет синтаксисы функции.

Совет

Если вы предварительно выделяете массивы с помощью функций как zeros, затем необходимо гарантировать, что типы данных этих массивов сопоставимы с входными параметрами функции уровня. Чтобы создать массив нулей совпадающего типа данных другого массива, используйте 'like' опция zeros. Например, чтобы инициализировать массив нулей размера sz с совпадающим типом данных как массив X, используйте Z = zeros(sz,'like',X).

        function Z = predict(layer, varargin)
            % Z = predict(layer, X1, ..., Xn) forwards the input data X1,
            % ..., Xn through the layer and outputs the result Z.
            
            X = varargin;
            W = layer.Weights;
            
            % Initialize output
            X1 = X{1};
            sz = size(X1);
            Z = zeros(sz,'like',X1);
            
            % Weighted addition
            for i = 1:layer.NumInputs
                Z = Z + W(i)*X{i};
            end
        end

Поскольку predict функционируйте только использует функции та поддержка dlarray объекты, задавая backward функция является дополнительной. Для списка функций та поддержка dlarray объекты, см. Список Функций с Поддержкой dlarray.

Завершенный слой

Просмотрите завершенный файл класса слоя.

classdef weightedAdditionLayer < nnet.layer.Layer
    % Example custom weighted addition layer.

    properties (Learnable)
        % Layer learnable parameters
            
        % Scaling coefficients
        Weights
    end
    
    methods
        function layer = weightedAdditionLayer(numInputs,name) 
            % layer = weightedAdditionLayer(numInputs,name) creates a
            % weighted addition layer and specifies the number of inputs
            % and the layer name.

            % Set number of inputs.
            layer.NumInputs = numInputs;

            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "Weighted addition of " + numInputs +  ... 
                " inputs";
        
            % Initialize layer weights.
            layer.Weights = rand(1,numInputs); 
        end
        
        function Z = predict(layer, varargin)
            % Z = predict(layer, X1, ..., Xn) forwards the input data X1,
            % ..., Xn through the layer and outputs the result Z.
            
            X = varargin;
            W = layer.Weights;
            
            % Initialize output
            X1 = X{1};
            sz = size(X1);
            Z = zeros(sz,'like',X1);
            
            % Weighted addition
            for i = 1:layer.NumInputs
                Z = Z + W(i)*X{i};
            end
        end
    end
end

Совместимость графического процессора

Если слой вперед функции полностью поддерживает dlarray объекты, затем слоем является совместимый графический процессор. В противном случае, чтобы быть совместимым графическим процессором, функции уровня должны поддержать входные параметры и возвратить выходные параметры типа gpuArray.

Много встроенных функций MATLAB поддерживают gpuArray и dlarray входные параметры. Для списка функций та поддержка dlarray объекты, см. Список Функций с Поддержкой dlarray. Для списка функций, которые выполняются на графическом процессоре, смотрите функции MATLAB Запуска на графическом процессоре (Parallel Computing Toolbox). Чтобы использовать графический процессор в глубоком обучении, у вас должен также быть CUDA®, включенный NVIDIA®, графический процессор с вычисляет возможность 3.0 или выше. Для получения дополнительной информации о работе с графическими процессорами в MATLAB смотрите, что графический процессор Вычисляет в MATLAB (Parallel Computing Toolbox).

В этом примере функции MATLAB используются в predict вся поддержка dlarray объекты, таким образом, слоем является совместимый графический процессор.

Проверяйте валидность слоя с несколькими входными параметрами

Проверяйте валидность слоя пользовательского слоя weightedAdditionLayer.

Задайте пользовательский взвешенный слой сложения. Чтобы создать этот слой, сохраните файл weightedAdditionLayer.m в текущей папке.

Создайте экземпляр слоя и проверяйте его валидность с помощью checkLayer. Задайте допустимые входные размеры, чтобы быть типичными размерами одного наблюдения для каждого входа к слою. Слой ожидает 4-D входные параметры массивов, где первые три измерения соответствуют высоте, ширине и количеству каналов предыдущего слоя выход, и четвертая размерность соответствует наблюдениям.

Задайте типичный размер входа наблюдения и установите 'ObservationDimension' к 4.

layer = weightedAdditionLayer(2,'add');
validInputSize = {[24 24 20],[24 24 20]};
checkLayer(layer,validInputSize,'ObservationDimension',4)
Running nnet.checklayer.TestLayerWithoutBackward
.......... .......
Done nnet.checklayer.TestLayerWithoutBackward
__________

Test Summary:
	 17 Passed, 0 Failed, 0 Incomplete, 0 Skipped.
	 Time elapsed: 0.53299 seconds.

Здесь, функция не обнаруживает проблем со слоем.

Используйте пользовательский взвешенный слой сложения в сети

Можно использовать пользовательский слой таким же образом в качестве любого другого слоя в Deep Learning Toolbox. Этот раздел показывает, как создать и обучить сеть для классификации цифр с помощью взвешенного слоя сложения, который вы создали ранее.

Загрузите обучающие данные в качестве примера.

[XTrain,YTrain] = digitTrain4DArrayData;

Задайте пользовательский взвешенный слой сложения. Чтобы создать этот слой, сохраните файл weightedAdditionLayer.m в текущей папке.

Создайте график слоя включая пользовательский слой weightedAdditionLayer.

layers = [
    imageInputLayer([28 28 1],'Name','in')
    convolution2dLayer(5,20,'Name','conv1')
    reluLayer('Name','relu1')
    convolution2dLayer(3,20,'Padding',1,'Name','conv2')
    reluLayer('Name','relu2')
    convolution2dLayer(3,20,'Padding',1,'Name','conv3')
    reluLayer('Name','relu3')
    weightedAdditionLayer(2,'add')
    fullyConnectedLayer(10,'Name','fc')
    softmaxLayer('Name','softmax')
    classificationLayer('Name','classoutput')];

lgraph = layerGraph(layers);
lgraph = connectLayers(lgraph, 'relu1', 'add/in2');

Установите опции обучения и обучите сеть.

options = trainingOptions('adam','MaxEpochs',10);
net = trainNetwork(XTrain,YTrain,lgraph,options);
Training on single GPU.
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 |       14.84% |       2.3049 |          0.0010 |
|       2 |          50 |       00:00:01 |       63.28% |       1.1073 |          0.0010 |
|       3 |         100 |       00:00:03 |       90.63% |       0.3221 |          0.0010 |
|       4 |         150 |       00:00:04 |       98.44% |       0.1049 |          0.0010 |
|       6 |         200 |       00:00:06 |       98.44% |       0.0698 |          0.0010 |
|       7 |         250 |       00:00:07 |       99.22% |       0.0204 |          0.0010 |
|       8 |         300 |       00:00:09 |      100.00% |       0.0105 |          0.0010 |
|       9 |         350 |       00:00:11 |       99.22% |       0.0279 |          0.0010 |
|      10 |         390 |       00:00:12 |      100.00% |       0.0152 |          0.0010 |
|========================================================================================|

Просмотрите веса, изученные взвешенным слоем сложения.

net.Layers(8).Weights
ans = 1×2 single row vector

    0.9037    0.8831

Оцените производительность сети путем предсказания на новых данных и вычисления точности.

[XTest,YTest] = digitTest4DArrayData;
YPred = classify(net,XTest);
accuracy = sum(YTest==YPred)/numel(YTest)
accuracy = 0.9842

Смотрите также

| |

Похожие темы