Если Deep Learning Toolbox™ не предоставляет слой, который вам нужен для задачи классификации или регрессии, то можно задать свой собственный пользовательский слой, используя этот пример в качестве руководства. Список встроенных слоев см. в Списке слоев глубокого обучения.
Чтобы создать пользовательский слой, который сам определяет график слоев, можно задать dlnetwork
объект как настраиваемый параметр. Этот способ известен как состав сети. Можно использовать сетевую композицию для:
Создайте один пользовательский слой, который представляет блок обучаемых слоев, например, остаточный блок.
Создайте сеть с потоком управления, например, сеть с участком, который может динамически изменяться в зависимости от входных данных.
Создайте сеть с циклами, например, сеть с секциями, которые подают выход назад в себя.
Для получения дополнительной информации смотрите Нейронную сеть для глубокого обучения Composition.
В этом примере показано, как создать пользовательский слой, представляющий остаточный блок. Пользовательский слой residualBlockLayer
содержит обучаемый блок слоев, состоящий из свертки, нормализации группы, ReLU и слоев сложения, а также включает пропускающее соединение и дополнительный слой свертки и слой нормализации группы в пропускающем соединении. Слой имеет один вход, который используется дважды, в качестве входа для каждой ветви. Эта схема подсвечивает структуру остаточных блоков.
Чтобы определить пользовательский слой глубокого обучения, можно использовать шаблон, представленный в этом примере, который проходит через следующие шаги:
Назовите слой - Дайте слою имя, чтобы вы могли использовать его в MATLAB®.
Объявить свойства слоя - Задать свойства слоя и какие параметры узнаются во время обучения.
Создайте функцию конструктора (необязательно) - задайте, как создать слой и инициализировать его свойства. Если вы не задаете функцию конструктора, то при создании программное обеспечение инициализирует Name
, Description
, и Type
свойства с []
и устанавливает количество входов и выходов слоя равным 1.
Создайте прямые функции - Задайте, как данные проходят вперед через слой (прямое распространение) во время предсказания и во время обучения.
Создайте обратную функцию (необязательно) - Задайте производные потерь относительно входных данных и настраиваемых параметров (обратное распространение). Если вы не задаете обратную функцию, то передние функции должны поддерживать dlarray
объекты.
Скопируйте слой с настраиваемых параметров шаблоном в новый файл в 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
с residualBlockLayer
.
classdef residualBlockLayer < nnet.layer.Layer ... end
Далее переименуйте myLayer
функция конструктора (первая функция в methods
section) так, чтобы оно имело то же имя что и слой.
methods function layer = residualBlockLayer() ... end ... end
Сохраните файл класса слоя в новом файле с именем residualBlockLayer.m
. Имя файла должно совпадать с именем слоя. Чтобы использовать слой, необходимо сохранить файл в текущей папке или в папке на пути MATLAB.
Объявление свойств слоя в properties
и объявить настраиваемые параметры путем их перечисления в properties (Learnable)
раздел.
По умолчанию пользовательские промежуточные слои имеют эти свойства.
Свойство | Описание |
---|---|
Name | Имя слоя, заданное как вектор символов или строковый скаляр. Чтобы включить слой в график слоев, необходимо задать непустое уникальное имя слоя. Если вы обучаете последовательную сеть с слоем и Name установлено в '' затем программа автоматически присваивает слою имя во время обучения. |
Description | Однострочное описание слоя, заданное как вектор символов или строковый скаляр. Это описание появляется, когда слой отображается в |
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
раздел.
Этот пользовательский слой имеет только один настраиваемый параметр, сам остаточный блок задан как dlnetwork
объект. Объявите этот настраиваемый параметр в properties (Learnable)
и вызовите параметр Network
.
properties (Learnable)
% Layer learnable parameters
% Residual block.
Network
end
Создайте функцию, которая создает слой и инициализирует свойства слоя. Задайте любые переменные, необходимые для создания слоя в качестве входов для функции конструктора.
Функция конструктора невязочного блока слоя требует четырёх входных параметров:
Количество сверточных фильтров
Stride (необязательно, с полосой 1 по умолчанию)
Флаг для включения свертки в пропускающее соединение (необязательно, с флагом по умолчанию false
)
Имя слоя (необязательно, с именем по умолчанию ''
)
В функции конструктора residualBlockLayer
, задайте необходимый входной параметр numFilters
и необязательные аргументы в виде пар "имя-значение" с именем NameValueArgs
. Добавьте комментарий к верхней части функции, которая объясняет синтаксис функции.
function layer = residualBlockLayer(numFilters,NameValueArgs) % layer = residualBlockLayer(numFilters) creates a residual % block layer with the specified number of filters. % % layer = residualBlockLayer(numFilters,Name,Value) specifies % additional options using one or more name-value pair % arguments: % % 'Stride' - Stride of convolution operation % (default 1) % % 'IncludeSkipConvolution' - Flag to include convolution in % skip connection % (default false) % % 'Name' - Layer name % (default '') ... end
Проанализируйте входные параметры с помощью arguments
блок. Перечислите аргументы в том же порядке, что и синтаксис функции, и задайте значения по умолчанию. Затем извлеките значения из NameValueArgs
вход.
% Parse input arguments. arguments numFilters NameValueArgs.Stride = 1 NameValueArgs.IncludeSkipConvolution = false NameValueArgs.Name = '' end stride = NameValueArgs.Stride; includeSkipConvolution = NameValueArgs.IncludeSkipConvolution; name = NameValueArgs.Name;
В функции конструктора инициализируйте свойства слоя, включая dlnetwork
объект. Замените комментарий % Layer constructor function goes here
с кодом, который инициализирует свойства слоя.
Установите Name
свойство для входного параметра name
.
% Set layer name.
layer.Name = name;
Дайте слою однострочного описания путем установки Description
свойство слоя. Установите описание, чтобы описать слой и любые дополнительные свойства.
% Set layer description. description = "Residual block with " + numFilters + " filters, stride " + stride; if includeSkipConvolution description = description + ", and skip convolution"; end layer.Description = description;
Укажите тип слоя путем установки Type
свойство. Значение Type
появляется, когда слой отображается в Layer
массив.
% Set layer type. layer.Type = "Residual Block";
Задайте остаточный блок. Можно создать слои остаточных блоков как неинициализированное вложенное dlnetwork
объект без входа слоя и позволяет программному обеспечению автоматически инициализировать обучаемые и параметры состояния во время обучения. Дополнительные сведения см. в разделе Автоматическая инициализация обучаемых объектов сети dlnetwork для обучения.
Сначала создайте массив слоев, содержащий основные слои блока, и преобразуйте его в график слоев.
% Define nested layer graph. layers = [ convolution2dLayer(3,numFilters,'Padding','same','Stride',stride,'Name','conv1') groupNormalizationLayer('all-channels','Name','gn1') reluLayer('Name','relu1') convolution2dLayer(3,numFilters,'Padding','same','Name','conv2') groupNormalizationLayer('channel-wise','Name','gn2') additionLayer(2,'Name','add') reluLayer('Name','relu2')]; lgraph = layerGraph(layers);
Затем добавьте пропущенное соединение. Если на includeSkipConvolution
флаг true
затем также включают слой свертки и слой нормализации группы в пропускном соединении.
% Add skip connection. if includeSkipConvolution layers = [ convolution2dLayer(1,numFilters,'Stride',stride,'Name','convSkip') groupNormalizationLayer('all-channels','Name','gnSkip')]; lgraph = addLayers(lgraph,layers); lgraph = connectLayers(lgraph,'gnSkip','add/in2'); end
Поскольку входного слоя нет, эта сеть имеет два несвязанных входа. Если сеть не имеет пропускающего соединения, вход в 'conv2'
слой и один из входов в 'add'
слой не соединен. Если сеть действительно имеет пропускающее соединение, то несвязанные входы являются входами к 'conv1'
и 'convSkip'
слои.
Наконец, преобразуйте график слоев в dlnetwork
Объекту и установите слой Network
свойство. Создайте неинициализированную dlnetwork
объект. Веса и настраиваемые параметры в dlnetwork
объект инициализируется автоматически при сборке всей сети для обучения.
% Convert to dlnetwork. dlnet = dlnetwork(lgraph,'Initialize',false); % Set Network property. layer.Network = dlnet;
Просмотрите завершенную функцию конструктора.
function layer = residualBlockLayer(numFilters,NameValueArgs)
% layer = residualBlockLayer(numFilters) creates a residual
% block layer with the specified number of filters.
%
% layer = residualBlockLayer(numFilters,Name,Value) specifies
% additional options using one or more name-value pair
% arguments:
%
% 'Stride' - Stride of convolution operation
% (default 1)
%
% 'IncludeSkipConvolution' - Flag to include convolution in
% skip connection
% (default false)
%
% 'Name' - Layer name
% (default '')
% Parse input arguments.
arguments
numFilters
NameValueArgs.Stride = 1
NameValueArgs.IncludeSkipConvolution = false
NameValueArgs.Name = ''
end
stride = NameValueArgs.Stride;
includeSkipConvolution = NameValueArgs.IncludeSkipConvolution;
name = NameValueArgs.Name;
% Set layer name.
layer.Name = name;
% Set layer description.
description = "Residual block with " + numFilters + " filters, stride " + stride;
if includeSkipConvolution
description = description + ", and skip convolution";
end
layer.Description = description;
% Set layer type.
layer.Type = "Residual Block";
% Define nested layer graph.
layers = [
convolution2dLayer(3,numFilters,'Padding','same','Stride',stride,'Name','conv1')
groupNormalizationLayer('all-channels','Name','gn1')
reluLayer('Name','relu1')
convolution2dLayer(3,numFilters,'Padding','same','Name','conv2')
groupNormalizationLayer('channel-wise','Name','gn2')
additionLayer(2,'Name','add')
reluLayer('Name','relu2')];
lgraph = layerGraph(layers);
% Add skip connection.
if includeSkipConvolution
layers = [
convolution2dLayer(1,numFilters,'Stride',stride,'Name','convSkip')
groupNormalizationLayer('all-channels','Name','gnSkip')];
lgraph = addLayers(lgraph,layers);
lgraph = connectLayers(lgraph,'gnSkip','add/in2');
end
% Convert to dlnetwork.
dlnet = dlnetwork(lgraph,'Initialize',false);
% Set Network property.
layer.Network = dlnet;
end
С помощью этой функции конструктора команда residualBlockLayer(64,'Stride',2,'IncludeSkipConvolution',true,'Name','res5')
создает слой остаточных блоков с 64 фильтрами, полосой 2, сверткой в пропускном соединении и с именем 'res5'
. Необходимые размеры весов и параметров определяются при сборке завершенной сети для обучения.
Создайте передовые функции слоя для использования во времени предсказания и времени обучения.
Создайте функцию с именем 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 объекта
функция гарантирует, что программное обеспечение использует правильные операции слоя для предсказания.
Поскольку остаточный блок имеет только один вход и один выход, синтаксис для предсказания для пользовательского слоя Z = predict(layer,X)
.
По умолчанию слой использует predict
как прямая функция во время обучения. Чтобы использовать другую прямую функцию во время обучения или сохранить значение, необходимое для пользовательской обратной функции, необходимо также создать функцию с именем forward
.
Размерности входов зависят от типа данных и выхода связанных слоев.
Вход слоя | Вход сигнала | Размерность наблюдения |
---|---|---|
2-D изображения | h -by- w -by- c -by- N, где h, w и c соответствуют высоте, ширине и количеству каналов изображений, соответственно, а N - количеству наблюдений. | 4 |
3-D изображения | <reservedrangesplaceholder9>-by-<reservedrangesplaceholder8>-by-<reservedrangesplaceholder7>-by-<reservedrangesplaceholder6>-by-<reservedrangesplaceholder5>, где h, w, d, и c соответствуют высоте, ширине, глубине, и количество каналов 3D изображений, соответственно, и N - количество наблюдений. | 5 |
Векторные последовательности | c -by- N -by- S, где c - количество функций последовательностей, N - количество наблюдений, а S - длина последовательности. | 2 |
2-D последовательности изображений | 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 |
Для слоев, которые выводят последовательности, слои могут выводить последовательности любой длины или выводить данные без временной размерности. Обратите внимание, что при обучении сети, которая выводит последовательности, используя trainNetwork
function, длины входа и выхода последовательностей должны совпадать.
Для слоя остаточных блоков передний проход слоя является просто передним проходом dlnetwork
объект. Для передачи входных данных в dlnetwork
объект, необходимо сначала преобразовать его в форматированный dlarray
объект.
Реализуйте эту операцию в пользовательской функции слоя predict
. Выполнение прямого прохода dlnetwork
для предсказания используйте predict
функция для dlnetwork
объекты. В этом случае вход в слой остаточных блоков используется как вход в оба несвязанных входов в dlnetwork
объект, поэтому синтаксис для predict
для dlnetwork
объект Z = predict(dlnet,X,X)
.
Потому что слои в dlnetwork
объект не ведет себя по-разному во время обучения и что слой остаточных блоков не требует памяти или другой прямой функции для обучения, можно удалить forward
функция из файла класса.
Создайте predict
function и добавить комментарий к верхней части функции, который объясняет синтаксисы функции.
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
% Outputs:
% Z - Output of layer forward function
% Convert input data to formatted dlarray.
X = dlarray(X,'SSCB');
% Predict using network.
dlnet = layer.Network;
Z = predict(dlnet,X,X);
% Strip dimension labels.
Z = stripdims(Z);
end
Потому что predict
функция использует только функции, которые поддержка dlarray
объекты, определяющие backward
функция опциональна. Список функций, поддерживающих dlarray
объекты, см. Список функций с поддержкой dlarray.
Просмотрите заполненный файл класса слоя.
classdef residualBlockLayer < nnet.layer.Layer % Example custom residual block layer. properties (Learnable) % Layer learnable parameters % Residual block. Network end methods function layer = residualBlockLayer(numFilters,NameValueArgs) % layer = residualBlockLayer(numFilters) creates a residual % block layer with the specified number of filters. % % layer = residualBlockLayer(numFilters,Name,Value) specifies % additional options using one or more name-value pair % arguments: % % 'Stride' - Stride of convolution operation % (default 1) % % 'IncludeSkipConvolution' - Flag to include convolution in % skip connection % (default false) % % 'Name' - Layer name % (default '') % Parse input arguments. arguments numFilters NameValueArgs.Stride = 1 NameValueArgs.IncludeSkipConvolution = false NameValueArgs.Name = '' end stride = NameValueArgs.Stride; includeSkipConvolution = NameValueArgs.IncludeSkipConvolution; name = NameValueArgs.Name; % Set layer name. layer.Name = name; % Set layer description. description = "Residual block with " + numFilters + " filters, stride " + stride; if includeSkipConvolution description = description + ", and skip convolution"; end layer.Description = description; % Set layer type. layer.Type = "Residual Block"; % Define nested layer graph. layers = [ convolution2dLayer(3,numFilters,'Padding','same','Stride',stride,'Name','conv1') groupNormalizationLayer('all-channels','Name','gn1') reluLayer('Name','relu1') convolution2dLayer(3,numFilters,'Padding','same','Name','conv2') groupNormalizationLayer('channel-wise','Name','gn2') additionLayer(2,'Name','add') reluLayer('Name','relu2')]; lgraph = layerGraph(layers); % Add skip connection. if includeSkipConvolution layers = [ convolution2dLayer(1,numFilters,'Stride',stride,'Name','convSkip') groupNormalizationLayer('all-channels','Name','gnSkip')]; lgraph = addLayers(lgraph,layers); lgraph = connectLayers(lgraph,'gnSkip','add/in2'); end % Convert to dlnetwork. dlnet = dlnetwork(lgraph,'Initialize',false); % Set Network property. layer.Network = dlnet; 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 % Outputs: % Z - Output of layer forward function % Convert input data to formatted dlarray. X = dlarray(X,'SSCB'); % Predict using network. dlnet = layer.Network; Z = predict(dlnet,X,X); % Strip dimension labels. Z = stripdims(Z); end end end
Если функции слоя 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).
В этом примере функции MATLAB, используемые в predict
все dlarray поддержки
объекты, поэтому слой совместим с графическим процессором.
checkLayer
Проверьте валидность слоя пользовательского слоя residualBlockLayer
использование checkLayer
функция.
Создайте образец слоя остаточных блоков. Чтобы получить доступ к этому слою, откройте этот пример как live скрипт.
numFilters = 64; layer = residualBlockLayer(numFilters)
layer = residualBlockLayer with properties: Name: '' Learnable Parameters Network: [1x1 dlnetwork] Show all properties
Проверьте валидность слоя с помощью checkLayer
функция. Слой ожидает 4-D входов массива, где первые три размерности соответствуют высоте, ширине и количеству каналов предыдущего выхода слоя, а четвертая размерность соответствует наблюдениям. Задайте типовой размер входа и установите 'ObservationDimension'
опция 4.
validInputSize = [56 56 64];
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.TestLayerWithoutBackward .......... ... Done nnet.checklayer.TestLayerWithoutBackward __________ Test Summary: 13 Passed, 0 Failed, 0 Incomplete, 9 Skipped. Time elapsed: 5.2727 seconds.
Функция не обнаруживает проблем со слоем.
assembleNetwork
| checkLayer
| getL2Factor
| getLearnRateFactor
| setL2Factor
| setLearnRateFactor