exponenta event banner

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

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

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

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

  2. Объявить свойства слоя (Declare the layer properties) - укажите свойства слоя и параметры, которые будут изучены во время обучения.

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

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

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

Определение обратной функции является необязательным при поддержке прямых функций dlarray объекты в качестве входных данных. Используя dlarray объекты упрощают работу с высокоразмерными данными, позволяя маркировать размеры. Например, можно пометить, какие измерения соответствуют пространственным, временным, канальным и пакетным измерениям, используя 'S', 'T', 'C', и 'B' соответственно. Для неуказанных и других размеров используйте 'U' этикетка. Для dlarray функции объекта, которые работают над определенными размерами, можно указать метки размеров, отформатировав dlarray непосредственно или с помощью 'DataFormat' вариант.

Использование форматированного dlarray объекты в пользовательских слоях также позволяют определять слои, в которых входные и выходные данные имеют различные форматы, например слои, которые переставляют, добавляют или удаляют размеры. Например, можно определить слой, принимающий в качестве входных данных мини-пакет изображений с форматом 'SSCB' (пространственный, пространственный, канальный, пакетный) и вывод мини-пакета последовательностей с форматом 'CBT' (канал, партия, время).

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

В этом примере показано, как создать слой проекта и изменения формы, который является слоем, обычно используемым в генеративных состязательных сетях (GAN), который принимает массив шума с форматом 'CB' (канал, пакет) и проецирует и переформатирует его в мини-пакет изображений с форматом 'SSCB' (пространственные, пространственные, канальные, пакетные) с использованием операций полного соединения, изменения формы и повторной маркировки.

Пример обучения GAN с помощью уровня проекта и изменения формы см. в разделе Генеративная состязательная сеть поезда (GAN).

Слой с шаблоном обучаемых параметров

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

classdef myLayer < nnet.layer.Layer % & nnet.layer.Formattable (Optional) 

    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 с projectAndReshapeLayer. Затем укажите наследование от обоих nnet.layer.Layer и nnet.layer.Formattable суперклассы.

classdef projectAndRehapeLayer < nnet.layer.Layer & nnet.layer.Formattable
    ...
end

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

    methods
        function layer = projectAndReshapeLayer()           
            ...
        end

        ...
     end

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

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

Объявление свойств и обучаемых параметров

Объявление свойств слоя в properties и объявить обучаемые параметры, перечислив их в 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 свойства в конструкторе слоев. Пример см. в разделе Определение пользовательского слоя глубокого обучения с несколькими входами.

Для слоя проекта и изменения формы требуется дополнительное свойство, сохраняющее размер вывода слоя. Укажите одно свойство с именем OutputSize в properties раздел.

    properties
        % Output size
        OutputSize
    end

Слой проекта и изменения формы имеет два обучаемых параметра: веса и смещения операции полного соединения. Объявить эти обучаемые параметры в properties (Learnable) раздел и вызовите параметры Weights и Biasсоответственно.


    properties (Learnable)
    % Layer learnable parameters
    % Fully connect weights Weights % Fully
        connect biases Bias end

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

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

Для функции конструктора слоя проекта и изменения формы требуется два входных аргумента:

  • Размер выходного слоя

  • Количество каналов

  • Имя слоя (необязательно, имя по умолчанию '')

В функции конструктора projectAndReshapeLayer, укажите два обязательных входных аргумента с именем outputSize и numChannelsи необязательные аргументы как пары имя-значение с именем NameValueArgs. Добавьте комментарий в верхней части функции, объясняющий синтаксис функции.

        function layer = projectAndReshapeLayer(outputSize,numChannels,NameValueArgs)
            % layer = projectAndReshapeLayer(outputSize,numChannels)
            % creates a projectAndReshapeLayer object that projects and
            % reshapes the input to the specified output size using and
            % specifies the number of input channels.
            %
            % layer = projectAndReshapeLayer(outputSize,numChannels,'Name',name)
            % also specifies the layer name.
            
            ...
        end

Анализ входных аргументов

Разбор входных аргументов с помощью arguments блок. Перечислите аргументы в том же порядке, что и синтаксис функции, и укажите значения по умолчанию. Затем извлеките значения из NameValueArgs вход.

            % Parse input arguments.
            arguments
                outputSize
                numChannels
                NameValueArgs.Name = ''
            end
            
            name = NameValueArgs.Name;

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

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

Установите Name свойство для входного аргумента name.

            % Set layer name.
            layer.Name = name;

Присвойте слою однострочное описание, установив значение Description свойство слоя. Задайте описание для описания типа слоя и его размера.

            % Set layer description.
            layer.Description = "Project and reshape layer with output size " + join(string(outputSize));

Укажите тип слоя, задав значение Type собственность. Значение Type появляется, когда слой отображается в Layer массив.

            % Set layer type.
            layer.Type = "Project and Reshape";

Задание свойства слоя OutputSize к указанному входному значению.

            % Set output size.
            layer.OutputSize = outputSize;

Слой проекта и изменения формы применяет операцию полного соединения для проецирования входных данных на пакет изображений. Инициализируйте веса с помощью инициализатора Glorot и инициализируйте смещение с помощью массива нулей. Функции initializeGlorot и initializeZeros присоединены к примеру Train Generative Adversarial Network (GAN) в качестве вспомогательных файлов. Чтобы получить доступ к этим функциям, откройте этот пример как живой сценарий. Дополнительные сведения о инициализации обучаемых параметров для операций глубокого обучения см. в разделе Инициализация обучаемых параметров для функции модели.

            % Initialize fully connect weights and bias.
            sz = [prod(outputSize) numChannels];
            numOut = prod(outputSize);
            numIn = numChannels;
            layer.Weights = initializeGlorot(sz,numOut,numIn);
            layer.Bias = initializeZeros([prod(outputSize) 1]);

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

        function layer = projectAndReshapeLayer(outputSize,numChannels,NameValueArgs)
            % layer = projectAndReshapeLayer(outputSize,numChannels)
            % creates a projectAndReshapeLayer object that projects and
            % reshapes the input to the specified output size using and
            % specifies the number of input channels.
            %
            % layer = projectAndReshapeLayer(outputSize,numChannels,'Name',name)
            % also specifies the layer name.
                                  
            % Parse input arguments.
            arguments
                outputSize
                numChannels
                NameValueArgs.Name = '';
            end
            
            name = NameValueArgs.Name;
            
            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "Project and reshape layer with output size " + join(string(outputSize));
            
            % Set layer type.
            layer.Type = "Project and Reshape";
            
            % Set output size.
            layer.OutputSize = outputSize;
            
            % Initialize fully connect weights and bias.
            sz = [prod(outputSize) numChannels];
            numOut = prod(outputSize);
            numIn = numChannels;
            layer.Weights = initializeGlorot(sz,numOut,numIn);
            layer.Bias = initializeZeros([prod(outputSize) 1]);
        end

С помощью этой функции конструктора команда projectAndReshapeLayer([4 4 512],100,'Name','proj'); создание слоя проекта и изменение формы с именем 'proj' который проецирует входные массивы размером 100 на пакет из 512 изображений 4 на 4.

Создание функций пересылки

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

Создание функции с именем 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.

Совет

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

Поскольку слой проекта и изменения формы имеет только один вход и один выход, синтаксис для predict для проекта и слоя изменения формы Z = predict(layer,X).

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

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

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

Для слоев, выводящих последовательности, слои могут выводить последовательности любой длины или выходные данные без измерения времени. Обратите внимание, что при обучении сеть, которая выводит последовательности с использованием trainNetwork , длины входных и выходных последовательностей должны совпадать.

Поскольку пользовательский слой наследует от nnet.layer.Formattable класс, слой получает форматированный dlarray объекты с метками, соответствующими выводу предыдущего слоя.

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.

Совет

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

Операция проекта и изменения формы состоит из трех операций:

  • Примените операции полного соединения с учитываемыми весами и отклонениями.

  • Измените форму вывода на указанный размер.

  • Повторно пометить размеры так, чтобы выходные данные имели формат 'SSCB' (пространственный, пространственный, канальный, пакетный)

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

        function Z = predict(layer, X)
            % Forward input data through the layer at prediction time and
            % output the result.
            % 
            % Inputs:
            %         layer - Layer to forward propagate through
            %         X     - Input data, specified as a formatted dlarray
            %                 with a 'C' and optionally a 'B' dimension.
            % Outputs:
            %         Z     - Output of layer forward function returned as 
            %                 a formatted dlarray with format 'SSCB'.

            % Fully connect.
            weights = layer.Weights;
            bias = layer.Bias;
            X = fullyconnect(X,weights,bias);
            
            % Reshape.
            outputSize = layer.OutputSize;
            Z = reshape(X, outputSize(1), outputSize(2), outputSize(3), []);
            
            % Relabel.
            Z = dlarray(Z,'SSCB');
        end

Совет

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

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

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

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

classdef projectAndReshapeLayer < nnet.layer.Layer & nnet.layer.Formattable
    % Example project and reshape layer.

    properties
        % Output size
        OutputSize
    end


    properties (Learnable)
    % Layer learnable parameters
    % Fully connect weights Weights % Fully
        connect biases Bias end
    
    methods
        function layer = projectAndReshapeLayer(outputSize,numChannels,NameValueArgs)
            % layer = projectAndReshapeLayer(outputSize,numChannels)
            % creates a projectAndReshapeLayer object that projects and
            % reshapes the input to the specified output size using and
            % specifies the number of input channels.
            %
            % layer = projectAndReshapeLayer(outputSize,numChannels,'Name',name)
            % also specifies the layer name.
                                  
            % Parse input arguments.
            arguments
                outputSize
                numChannels
                NameValueArgs.Name = '';
            end
            
            name = NameValueArgs.Name;
            
            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "Project and reshape layer with output size " + join(string(outputSize));
            
            % Set layer type.
            layer.Type = "Project and Reshape";
            
            % Set output size.
            layer.OutputSize = outputSize;
            
            % Initialize fully connect weights and bias.
            sz = [prod(outputSize) numChannels];
            numOut = prod(outputSize);
            numIn = numChannels;
            layer.Weights = initializeGlorot(sz,numOut,numIn);
            layer.Bias = initializeZeros([prod(outputSize) 1]);
        end
        
        function Z = predict(layer, X)
            % Forward input data through the layer at prediction time and
            % output the result.
            % 
            % Inputs:
            %         layer - Layer to forward propagate through
            %         X     - Input data, specified as a formatted dlarray
            %                 with a 'C' and optionally a 'B' dimension.
            % Outputs:
            %         Z     - Output of layer forward function returned as 
            %                 a formatted dlarray with format 'SSCB'.

            % Fully connect.
            weights = layer.Weights;
            bias = layer.Bias;
            X = fullyconnect(X,weights,bias);
            
            % Reshape.
            outputSize = layer.OutputSize;
            Z = reshape(X, outputSize(1), outputSize(2), outputSize(3), []);
            
            % Relabel.
            Z = dlarray(Z,'SSCB');
        end
    end
end

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

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

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

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

Включить пользовательский слой в сеть

Определите следующую архитектуру сети генератора для GAN, который производит изображения от множеств случайных ценностей 1 на 1 на 100:

Эта сеть:

  • Преобразовывает случайные векторы размера 100 ко множествам 7 на 7 на 128, используя проект, и измените слой.

  • Масштабирует результирующие массивы до массивов 64 на 3, используя ряд транспонированных слоев свертки и слоев ReLU.

Определите эту сетевую архитектуру как график уровня и укажите следующие свойства сети.

  • Для транспонированных слоев свертки укажите фильтры 5 на 5 с уменьшающимся числом фильтров для каждого слоя, шагом 2 и обрезкой выходных данных на каждом ребре.

  • Для конечного транспонированного слоя свертки укажите три фильтра 5 на 5, соответствующих трем каналам RGB генерируемых изображений, и размер вывода предыдущего слоя.

  • В конце сети включите уровень tanh.

Для проецирования и изменения формы входного шума используйте пользовательский слой projectAndReshapeLayer.

filterSize = 5;
numFilters = 64;
numLatentInputs = 100;

projectionSize = [4 4 512];

layersG = [
    featureInputLayer(numLatentInputs,'Normalization','none','Name','in')
    projectAndReshapeLayer(projectionSize,numLatentInputs,'Name','proj');
    transposedConv2dLayer(filterSize,4*numFilters,'Name','tconv1')
    reluLayer('Name','relu1')
    transposedConv2dLayer(filterSize,2*numFilters,'Stride',2,'Cropping','same','Name','tconv2')
    reluLayer('Name','relu2')
    transposedConv2dLayer(filterSize,numFilters,'Stride',2,'Cropping','same','Name','tconv3')
    reluLayer('Name','relu3')
    transposedConv2dLayer(filterSize,3,'Stride',2,'Cropping','same','Name','tconv4')
    tanhLayer('Name','tanh')];

lgraphG = layerGraph(layersG);

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

dlnetG = dlnetwork(lgraphG);

См. также

|

Связанные темы