Если Deep Learning Toolbox™ не обеспечивает слой, вы требуете для своей классификации или проблемы регрессии, то можно задать собственный слой с помощью этого примера в качестве руководства. Для списка встроенных слоев смотрите Список слоев глубокого обучения.
Чтобы задать пользовательский слой глубокого обучения, можно использовать шаблон, обеспеченный в этом примере, который берет вас через следующие шаги:
Назовите слой – дают слою имя так, чтобы это могло использоваться в MATLAB®.
Объявите, что свойства слоя – задают свойства слоя и какие параметры изучены во время обучения.
Создайте (дополнительную) функцию конструктора – задают, как создать слой и инициализировать его свойства. Если вы не задаете функцию конструктора, то при создании, программное обеспечение инициализирует Name
Описание
, и Type
свойства с []
и определяет номер вводов и выводов слоя к 1.
Создайте прямые функции – задают, как данные передают вперед через слой (прямое распространение) во время прогноза и в учебное время.
Создайте обратную (дополнительную) функцию – задают производные потери относительно входных данных и learnable параметров (обратное распространение). Если вы не задаете обратную функцию, то прямые функции должны поддержать dlarray
объекты.
В этом примере показано, как создать слой PReLU, который является слоем learnable параметром, и используйте его в сверточной нейронной сети. Слой PReLU выполняет пороговую операцию, где для каждого канала, любое входное значение меньше, чем нуль умножаются на скаляр, изученный в учебное время. [1] Для значений меньше, чем нуль, слой PReLU применяет масштабные коэффициенты к каждому каналу входа. Эти коэффициенты формируют learnable параметр, который слой изучает во время обучения.
Этот рисунок от [1] сравнивает функции уровня ReLU и PReLU.
Скопируйте слой с 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
с preluLayer
.
classdef preluLayer < nnet.layer.Layer ... end
Затем переименуйте myLayer
функция конструктора (первая функция в methods
разделите) так, чтобы это имело то же имя как слой.
methods function layer = preluLayer() ... end ... end
Сохраните файл класса слоя в новом файле с именем preluLayer.m
. Имя файла должно совпадать с именем слоя. Чтобы использовать слой, необходимо сохранить файл в текущей папке или в папке на пути MATLAB.
Объявите свойства слоя в properties
разделите и объявите learnable параметры путем листинга их в 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
в конструкторе слоя. Для примера смотрите, Задают Пользовательский Слой Глубокого обучения с Несколькими Входными параметрами.
Слой PReLU не требует никаких дополнительных свойств, таким образом, можно удалить properties
раздел.
Слой PReLU имеет только один learnable параметр, масштабирующийся коэффициент a. Объявите этот learnable параметр в properties (Learnable)
разделите и вызовите параметр Alpha
.
properties (Learnable)
% Layer learnable parameters
% Scaling coefficient
Alpha
end
Создайте функцию, которая создает слой и инициализирует свойства слоя. Задайте любые переменные, требуемые создать слой как входные параметры к функции конструктора.
Функция конструктора слоя PReLU требует двух входных аргументов: количество каналов ожидаемых входных данных и имени слоя. Количество каналов задает размер learnable параметра Alpha
. Задайте два входных параметра под названием numChannels
и name
в preluLayer
функция. Добавьте комментарий в верхнюю часть функции, которая объясняет синтаксис функции.
function layer = preluLayer(numChannels, name) % layer = preluLayer(numChannels) creates a PReLU layer with % numChannels channels and specifies the layer name. ... end
Инициализируйте свойства слоя, включая learnable параметры в функции конструктора. Замените комментарий % Layer constructor function goes here
с кодом, который инициализирует свойства слоя.
Установите Name
свойство к входному параметру name
.
% Set layer name.
layer.Name = name;
Дайте слою короткое описание путем установки Description
свойство слоя. Установите описание описывать тип слоя и его размера.
% Set layer description. layer.Description = "PReLU with " + numChannels + " channels";
Для слоя PReLU, когда входные значения отрицательны, слой умножает каждый канал входа соответствующим каналом Alpha
. Инициализируйте learnable параметр Alpha
быть случайным вектором размера 1 1 numChannels
. С третьей размерностью, заданной как размер numChannels
, слой может использовать поэлементное умножение входа в прямой функции. Alpha
свойство расположенного на слое объекта, таким образом, необходимо присвоить вектор layer.Alpha
.
% Initialize scaling coefficient.
layer.Alpha = rand([1 1 numChannels]);
Просмотрите завершенную функцию конструктора.
function layer = preluLayer(numChannels, name)
% layer = preluLayer(numChannels, name) creates a PReLU layer
% 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
С этой функцией конструктора, команда preluLayer(3,'prelu')
создает слой PReLU с тремя каналами и именем 'prelu'
.
Создайте слой вперед функции, чтобы использовать во время прогноза и учебное время.
Создайте функцию с именем 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
.
Поскольку слой PReLU имеет только один вход и один выход, синтаксис для predict
для PReLU слоем является Z = predict(layer,X)
.
По умолчанию слой использует 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
.
Операцией PReLU дают
где вход нелинейной активации f на канале i, и коэффициент, управляющий наклоном отрицательной части. Нижний i в указывает, что нелинейная активация может варьироваться на различных каналах.
Реализуйте эту операцию в predict
. В predict
, вход X
соответствует x в уравнении. Выход Z
соответствует . Слой PReLU не требует памяти или различной прямой функции для обучения, таким образом, можно удалить forward
функция из файла класса. Добавьте комментарий в верхнюю часть функции, которая объясняет синтаксисы функции.
Если вы предварительно выделяете массивы с помощью функций как zeros
, затем необходимо гарантировать, что типы данных этих массивов сопоставимы с входными параметрами функции уровня. Чтобы создать массив нулей совпадающего типа данных другого массива, используйте 'like'
опция zeros
. Например, чтобы инициализировать массив нулей размера sz
с совпадающим типом данных как массив X
, используйте Z = zeros(sz,'like',X)
.
function Z = predict(layer, X)
% Z = predict(layer, X) forwards the input data X through the
% layer and outputs the result Z.
Z = max(0, X) + layer.Alpha .* min(0, X);
end
Поскольку predict
функционируйте только использует функции та поддержка dlarray
объекты, задавая backward
функция является дополнительной. Для списка функций та поддержка dlarray
объекты, см. Список Функций с Поддержкой dlarray.
Просмотрите завершенный файл класса слоя.
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 % 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(0, X) + layer.Alpha .* min(0, X); 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
объекты, таким образом, слоем является совместимый графический процессор.
checkLayer
Проверяйте валидность слоя пользовательского слоя preluLayer
.
Задайте пользовательский слой PReLU. Чтобы создать этот слой, сохраните файл preluLayer.m
в текущей папке.
Создайте экземпляр слоя и проверяйте его валидность с помощью checkLayer
. Задайте допустимый входной размер, чтобы быть размером одного наблюдения за типичным входом к слою. Слой ожидает 4-D входные параметры массивов, где первые три измерения соответствуют высоте, ширине и количеству каналов предыдущего слоя выход, и четвертая размерность соответствует наблюдениям.
Задайте типичный размер входа наблюдения и установите 'ObservationDimension'
к 4.
layer = preluLayer(20,'prelu'); validInputSize = [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.68621 seconds.
Здесь, функция не обнаруживает проблем со слоем.
Можно использовать пользовательский слой таким же образом в качестве любого другого слоя в Deep Learning Toolbox. Этот раздел показывает, как создать и обучить сеть для классификации цифр с помощью слоя PReLU, который вы создали ранее.
Загрузите обучающие данные в качестве примера.
[XTrain,YTrain] = digitTrain4DArrayData;
Задайте пользовательский слой PReLU. Чтобы создать этот слой, сохраните файл preluLayer.m
в текущей папке. Создайте массив слоя включая пользовательский слой preluLayer
.
layers = [
imageInputLayer([28 28 1])
convolution2dLayer(5,20)
batchNormalizationLayer
preluLayer(20,'prelu')
fullyConnectedLayer(10)
softmaxLayer
classificationLayer];
Установите опции обучения и обучите сеть.
options = trainingOptions('adam','MaxEpochs',10); net = trainNetwork(XTrain,YTrain,layers,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 | 7.81% | 2.7135 | 0.0010 | | 2 | 50 | 00:00:01 | 79.69% | 0.6783 | 0.0010 | | 3 | 100 | 00:00:03 | 91.41% | 0.3581 | 0.0010 | | 4 | 150 | 00:00:04 | 96.09% | 0.1905 | 0.0010 | | 6 | 200 | 00:00:06 | 99.22% | 0.0987 | 0.0010 | | 7 | 250 | 00:00:08 | 100.00% | 0.0616 | 0.0010 | | 8 | 300 | 00:00:09 | 99.22% | 0.0510 | 0.0010 | | 9 | 350 | 00:00:11 | 100.00% | 0.0324 | 0.0010 | | 10 | 390 | 00:00:12 | 100.00% | 0.0170 | 0.0010 | |========================================================================================|
Оцените производительность сети путем предсказания на новых данных и вычисления точности.
[XTest,YTest] = digitTest4DArrayData; YPred = classify(net,XTest); accuracy = sum(YTest==YPred)/numel(YTest)
accuracy = 0.9662
[1] Он, Kaiming, Сянюй Чжан, Шаоцин Жэнь и Цзянь Сунь. "Копаясь глубоко в выпрямителях: Превосходная производительность человеческого уровня на классификации ImageNet". В Продолжениях международной конференции IEEE по вопросам компьютерного зрения, стр 1026-1034. 2015.