Задайте пользовательскую функцию слоя назад

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

Пример Define Custom Deep Learning Layer with Настраиваемые Параметры показывает, как создать пользовательский слой PreLU, и проходит следующие шаги:

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

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

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

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

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

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

Создание пользовательского слоя

Пример Define Custom Deep Learning Layer with Настраиваемые Параметры показывает, как создать слой PReLU. Слой PReLU выполняет пороговую операцию, где для каждого канала любое входное значение, меньше нуля, умножается на скаляр, выученный во время обучения. [1] Для значений меньше нуля слой PReLU применяет коэффициенты масштабирования αi в каждый канал входа. Эти коэффициенты образуют настраиваемый параметр, который слой учит во время обучения.

Операция PReLU определяется

f(xi)={xiесли xi>0αixiесли xi0

где xi является входом нелинейной f активации на канале i, и αi - коэффициент, контролирующий наклон отрицательной детали. Индекс i в αi указывает, что нелинейная активация может варьироваться в разных каналах.

Просмотрите слой, созданный в примере Define Custom Deep Learning Layer with Настраиваемые Параметры. Этот слой не имеет backward функция.

classdef preluLayer < nnet.layer.Layer
    % Example custom PReLU layer.

    properties (Learnable)
        % Layer learnable parameters
            
        % Scaling coefficient
        Alpha
    end
    
    methods
        function layer = preluLayer(numChannels, name) 
            % layer = preluLayer(numChannels, name) creates a PReLU layer
            % for 2-D image input with numChannels channels and specifies 
            % the layer name.

            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "PReLU with " + numChannels + " channels";
        
            % Initialize scaling coefficient.
            layer.Alpha = rand([1 1 numChannels]); 
        end
        
        function Z = predict(layer, X)
            % Z = predict(layer, X) forwards the input data X through the
            % layer and outputs the result Z.
            
            Z = max(X,0) + layer.Alpha .* min(0,X);
        end
    end
end

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

Реализуйте backward функция, которая возвращает производные потерь относительно входных данных и настраиваемых параметров.

Синтаксис для backward является [dLdX1,…,dLdXn,dLdW1,…,dLdWk] = backward(layer,X1,…,Xn,Z1,…,Zm,dLdZ1,…,dLdZm,memory), где:

  • X1,…,Xn являются ли n входы слоя

  • Z1,…,Zm являются ли m выходы передних функций слоя

  • dLdZ1,…,dLdZm являются ли градиенты назад распространены от следующего слоя

  • memory - выход памяти forward если forward определяется, в противном случае memory является [].

Для выходов dLdX1,…,dLdXn являются производными от потерь относительно входов слоя и dLdW1,…,dLdWk являются производными от потерь по отношению к k настраиваемые параметры. Чтобы уменьшить использование памяти путем предотвращения сохранения неиспользованных переменных между прямым и обратным проходом, замените соответствующие входные параметры на ~.

Совет

Если количество входов в backward может варьироваться, затем использовать varargin вместо входных параметров после layer. В этом случае varargin - массив ячеек входных входов, где varargin{i} соответствует Xi для i=1, …, NumInputs, varargin{NumInputs+j} и varargin{NumInputs+NumOutputs+j} соответствуют Zj и dLdZj, соответственно, для j=1, …, NumOutputs, и varargin{end} соответствует memory.

Если количество выходов может варьироваться, используйте varargout вместо выходных аргументов. В этом случае varargout - массив ячеек выходов, где varargout{i} соответствует dLdXi для i=1, …, NumInputs и varargout{NumInputs+t} соответствует dLdWt для t=1, …, k, где k количество настраиваемых параметров.

Поскольку слой PReLU имеет только один вход, один выход, один настраиваемый параметр и не требует выходов прямой функции слоя или значения памяти, синтаксис для backward для слоя PReLU [dLdX,dLdAlpha] = backward(layer,X,~,dLdZ,~). Размерности X являются такими же, как и в прямой функции. Размерности dLdZ совпадают с размерностями выхода Z прямой функции. Размерности и тип данных dLdX совпадают с размерностями и типом данных X. Размерность и тип данных dLdAlpha совпадает с размерностью и типом данных настраиваемого параметра Alpha.

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

Чтобы включить пользовательский слой в сеть, передние функции слоя должны принимать выходы предыдущего слоя и передавать массивы с размером, ожидаемым следующим слоем. Точно так же, когда backward задан, backward функция должна принимать входы с таким же размером, как и соответствующий выход прямой функции, и назад распространять производные с таким же размером.

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

Lxi=Lf(xi)f(xi)xi

где L/f(xi) - градиент, распространенный из следующего слоя, и производная активации,

f(xi)xi={1если xi0αiif xi<0.

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

Lαi=jLf(xij)f(xij)αi

где i индексирует каналы, j индексирует элементы по высоте, ширине и наблюдениям, и градиент активации,

f(xi)αi={0если xi0xiесли xi<0.

Создайте обратную функцию, которая возвращает эти производные.

        function [dLdX, dLdAlpha] = backward(layer, X, ~, dLdZ, ~)
            % [dLdX, dLdAlpha] = backward(layer, X, ~, dLdZ, ~)
            % backward propagates the derivative of the loss function
            % through the layer.
            % Inputs:
            %         layer    - Layer to backward propagate through
            %         X        - Input data
            %         dLdZ     - Gradient propagated from the deeper layer
            % Outputs:
            %         dLdX     - Derivative of the loss with respect to the
            %                    input data
            %         dLdAlpha - Derivative of the loss with respect to the
            %                    learnable parameter Alpha
            
            dLdX = layer.Alpha .* dLdZ;
            dLdX(X>0) = dLdZ(X>0);
            dLdAlpha = min(0,X) .* dLdZ;
            dLdAlpha = sum(dLdAlpha,[1 2]);
    
            % Sum over all observations in mini-batch.
            dLdAlpha = sum(dLdAlpha,4);
        end

Полный слой

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

classdef preluLayer < nnet.layer.Layer
    % Example custom PReLU layer.

    properties (Learnable)
        % Layer learnable parameters
            
        % Scaling coefficient
        Alpha
    end
    
    methods
        function layer = preluLayer(numChannels, name) 
            % layer = preluLayer(numChannels, name) creates a PReLU layer
            % for 2-D image input with numChannels channels and specifies 
            % the layer name.

            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "PReLU with " + numChannels + " channels";
        
            % Initialize scaling coefficient.
            layer.Alpha = rand([1 1 numChannels]); 
        end
        
        function Z = predict(layer, X)
            % Z = predict(layer, X) forwards the input data X through the
            % layer and outputs the result Z.
            
            Z = max(X,0) + layer.Alpha .* min(0,X);
        end
        
        function [dLdX, dLdAlpha] = backward(layer, X, ~, dLdZ, ~)
            % [dLdX, dLdAlpha] = backward(layer, X, ~, dLdZ, ~)
            % backward propagates the derivative of the loss function
            % through the layer.
            % Inputs:
            %         layer    - Layer to backward propagate through
            %         X        - Input data
            %         dLdZ     - Gradient propagated from the deeper layer
            % Outputs:
            %         dLdX     - Derivative of the loss with respect to the
            %                    input data
            %         dLdAlpha - Derivative of the loss with respect to the
            %                    learnable parameter Alpha
            
            dLdX = layer.Alpha .* dLdZ;
            dLdX(X>0) = dLdZ(X>0);
            dLdAlpha = min(0,X) .* dLdZ;
            dLdAlpha = sum(dLdAlpha,[1 2]);
    
            % Sum over all observations in mini-batch.
            dLdAlpha = sum(dLdAlpha,4);
        end
    end
end

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

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

Многие встроенные функции MATLAB поддерживают gpuArray (Parallel Computing Toolbox) и dlarray входные параметры. Список функций, поддерживающих dlarray объекты, см. Список функций с поддержкой dlarray. Список функций, которые выполняются на графическом процессоре, см. в разделе Запуск функций MATLAB на графическом процессоре (Parallel Computing Toolbox). Для использования графический процессор для глубокого обучения необходимо иметь также поддерживаемое графический процессор. Для получения информации о поддерживаемых устройствах смотрите Поддержку GPU by Release (Parallel Computing Toolbox). Для получения дополнительной информации о работе с графическими процессорами в MATLAB, смотрите GPU Computing в MATLAB (Parallel Computing Toolbox).

Ссылки

[1] «Углубление выпрямителей: превышение эффективности на уровне человека при классификации ImageNet». В 2015 году IEEE International Conference on Компьютерное Зрение (ICCV), 1026-34. Сантьяго, Чили: IEEE, 2015. https://doi.org/10.1109/ICCV.2015.123.

См. также

|

Похожие темы