В этом примере показано, как обучить увеличенную нейронную сеть обыкновенного дифференциального уравнения (ODE).
Нейронное ОДУ [1] является операцией глубокого обучения, которая возвращает решение ОДУ. В частности, учитывая вход, нейронная операция ODE выводит числовое решение ОДУ в течение периода времени и начальное условие , где и обозначьте входные параметры функции ОДУ и набор настраиваемых параметров. Как правило, начальное условие или сетевой вход или, как в случае этого примера, выхода другой операции глубокого обучения.
Увеличенная нейронная операция ODE [2] улучшает стандартное нейронное ОДУ путем увеличения входных данных с дополнительными каналами и затем отбрасывания увеличения после нейронной операции ODE. Опытным путем увеличенные нейронные ОДУ более устойчивы, делают вывод лучше и имеют более низкую вычислительную стоимость, чем нейронные ОДУ.
Этот пример обучает простую сверточную нейронную сеть с увеличенной нейронной операцией ODE.
Функция ОДУ может быть набором операций глубокого обучения. В этом примере модель использует блок свертки-tanh в качестве функции ОДУ:
Пример показывает, как обучить нейронную сеть, чтобы классифицировать изображения цифр с помощью увеличенной нейронной операции ODE.
Загрузите учебные изображения и метки с помощью digitTrain4DArrayData
функция.
[XTrain,TTrain] = digitTrain4DArrayData;
Просмотрите количество классов обучающих данных.
classNames = categories(TTrain); numClasses = numel(classNames)
numClasses = 10
Просмотрите некоторые изображения от обучающих данных.
numObservations = size(XTrain,4); idx = randperm(numObservations,64); I = imtile(XTrain(:,:,:,idx)); figure imshow(I)
Задайте следующую сеть, которая классифицирует изображения.
Блок свертки-ReLU с 8 3х3 фильтрами шагом 2
Шаг увеличения, который конкатенирует массив нулей к входу, таким образом, что количество каналов удвоено
Нейронная операция ODE с функцией ОДУ, содержащей свертку-tanh, блокируется с 16 3х3 фильтрами
Для классификации выход, полностью операция connect размера 10 (количество классов) и softmax операция
Нейронная операция ODE выводит решение заданной функции ОДУ. В данном примере задайте блок свертки-tanh как функцию ОДУ.
Таким образом, задайте функцию ОДУ, данную , где обозначает операцию свертки-tanh, входные данные, и содержит настраиваемые параметры для операции свертки. В этом случае, переменная не использовано.
Задайте настраиваемые параметры для каждой из операций и включайте их в структуру. Используйте формат parameters.OperationName.ParameterName
, где parameters
структура, OperationName
имя операции (например, "conv1"), и ParameterName
имя параметра (например, "Веса"). Инициализируйте learnable веса слоя и смещения с помощью initializeGlorot
и initializeZeros
функции, взятые в качестве примера, соответственно. Функции, взятые в качестве примера, инициализации присоединены к этому примеру как к вспомогательным файлам. Чтобы получить доступ к этим функциям, откройте этот пример как live скрипт. Для получения дополнительной информации об инициализации настраиваемых параметров для функций модели, смотрите, Инициализируют Настраиваемые параметры для Функции Модели.
Инициализируйте структуру параметров.
parameters = struct;
Инициализируйте параметры для первого сверточного слоя. Задайте 8 3х3 фильтров. Если вы изменяете эти размерности, то необходимо вручную вычислить входной размер полностью операция connect для ее инициализации весов Glorot.
filterSize = [3 3]; numFilters = 8; numChannels = size(XTrain,3); sz = [filterSize numChannels numFilters]; numOut = prod(filterSize) * numFilters; numIn = prod(filterSize) * numFilters; parameters.conv1.Weights = initializeGlorot(sz,numOut,numIn); parameters.conv1.Bias = initializeZeros([numFilters 1]);
Инициализируйте параметры для операции свертки, используемой в нейронной функции ОДУ. Поскольку шаг увеличения увеличивает входные данные с массивом нулей, количество входных каналов дано numFilters + numExtraChannels
, где numExtraChannels
количество каналов в увеличении. Точно так же, потому что модель отбрасывает каналы выхода нейронной операции ODE, соответствующей увеличению, операция свертки в нейронном ОДУ должна иметь (numChannels + numExtraChannels
) фильтры, где numChannels
желаемое количество выходных каналов.
Задайте то же количество фильтров как первый слой свертки и соответствующий размер увеличения.
numChannels = numFilters; numExtraChannels = numFilters; numFiltersAugmented = numChannels + numExtraChannels; sz = [filterSize numFiltersAugmented numFiltersAugmented]; numOut = prod(filterSize) * numFiltersAugmented; numIn = prod(filterSize) * numFiltersAugmented; parameters.neuralode.Weights = initializeGlorot(sz,numOut,numIn); parameters.neuralode.Bias = initializeZeros([numFiltersAugmented 1]);
Инициализируйте параметры для полностью операция connect. Чтобы инициализировать веса полностью операция connect с помощью инициализатора Glorot, сначала вычислите количество входных элементов к операции.
Для каждой операции в модели, которая изменяет размер данных, текущих через, рассмотрите выходные размеры, когда вы передаете 28 28 изображения через модель:
Первая свертка имеет 8 фильтров с "same"
дополнение и шаг 2. Эта операция выходные параметры 14 14 отображает с 8 каналами.
Модель затем увеличивает данные с массивом с 8 каналами нулей. Эта операция выходные параметры 14 14 отображает с 16 каналами.
Нейронная операция ODE начинает операцию свертки с 16 фильтрами и "same"
дополнение. Эта операция выходные параметры 14 14 отображает с 16 каналами.
Модель затем отбрасывает каналы, соответствующие увеличению. Эта операция выходные параметры 14 14 отображает с 8 каналами.
Это означает, что количество входных элементов к полностью операции connect .
sz = [14 14]; inputSize = prod(sz)*numChannels; outputSize = numClasses; sz = [outputSize inputSize]; numOut = outputSize; numIn = inputSize; parameters.fc1.Weights = initializeGlorot(sz,numOut,numIn); parameters.fc1.Bias = initializeZeros([outputSize 1]);
Просмотрите структуру параметров.
parameters
parameters = struct with fields:
conv1: [1×1 struct]
neuralode: [1×1 struct]
fc1: [1×1 struct]
Просмотрите параметры для нейронной операции ODE.
parameters.neuralode
ans = struct with fields:
Weights: [3×3×16×16 dlarray]
Bias: [16×1 dlarray]
Задайте гиперпараметры для операций и включайте их в структуру. Используйте формат hyperparameters.OperationName.ParameterName
где hyperparameters
структура, OperationName
имя операции (например, "neuralode") и ParameterName
имя гиперпараметра (например, "tspan").
Инициализируйте структуру гиперпараметров.
hyperparameters = struct;
Для нейронного ОДУ задайте интервал интегрирования [0 0.1].
hyperparameters.neuralode.tspan = [0 0.1];
Создайте функциональный odeModel
, перечисленный в разделе ODE Function примера, который берет в качестве входа, который время ввело (неиспользованный), начальные условия и параметры функции ОДУ. Функция применяет операцию свертки, сопровождаемую tanh операцией к входным данным с помощью весов, и смещает данный параметрами.
Создайте функциональный model
, перечисленный в разделе Model Function примера, который вычисляет выходные параметры модели глубокого обучения. Функциональный model
берет в качестве входа параметры модели и входные данные. Функциональные выходные параметры предсказания для меток.
Создайте функциональный modelGradients
, перечисленный в разделе Model Gradients примера, который берет в качестве входа параметры модели и мини-пакет входных данных с соответствующими целями, содержащими метки, и возвращает градиенты потери относительно настраиваемых параметров и соответствующей потери.
Задайте опции обучения. Обучайтесь с мини-пакетным размером 64 в течение 30 эпох.
miniBatchSize = 64; numEpochs = 30;
Обучите модель с помощью пользовательского учебного цикла.
Создайте minibatchqueue
возразите, что процессы и управляют мини-пакетами изображений во время обучения. Создать minibatchqueue
объект, сначала создайте datastore, который возвращает изображения и метки путем создания хранилищ данных массивов и затем объединения их.
dsXTrain = arrayDatastore(XTrain,IterationDimension=4); dsTTrain = arrayDatastore(TTrain); dsTrain = combine(dsXTrain,dsTTrain);
Создайте мини-пакетную очередь. Для каждого мини-пакета:
Используйте пользовательский мини-пакет, предварительно обрабатывающий функциональный preprocessMiniBatch
, заданный в разделе Mini-Batch Preprocessing Function примера, чтобы преобразовать метки в одногорячие закодированные переменные.
Отформатируйте данные изображения с метками размерности "SSCB"
(пространственный, пространственный, канал, пакет). По умолчанию, minibatchqueue
объект преобразует данные в dlarray
объекты с базовым типом single
.
Отбросьте частичные мини-пакеты.
Обучайтесь на графическом процессоре, если вы доступны. По умолчанию, minibatchqueue
объект преобразует каждый выход в gpuArray
если графический процессор доступен. Используя графический процессор требует Parallel Computing Toolbox™ и поддерживаемого устройства графического процессора. Для получения информации о поддерживаемых устройствах смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox).
mbq = minibatchqueue(dsTrain, ... MiniBatchSize=miniBatchSize, ... MiniBatchFcn=@preprocessMiniBatch, ... MiniBatchFormat=["SSCB" "CB"]);
Инициализируйте скользящее среднее значение градиентов параметра и поэлементные квадраты градиентов, используемых оптимизатором Адама.
trailingAvg = []; trailingAvgSq = [];
Инициализируйте учебный график.
figure C = colororder; lineLossTrain = animatedline(Color=C(2,:)); ylim([0 inf]) xlabel("Iteration") ylabel("Loss") grid on
Обучите модель с помощью пользовательского учебного цикла. В течение каждой эпохи переставьте данные. Для каждого мини-пакета:
Оцените градиенты модели с помощью dlfeval
и modelGradients
функции.
Обновите сетевые параметры с помощью adamupdate
функция.
Обновите график процесса обучения.
iteration = 0; start = tic; % Loop over epochs. for epoch = 1:numEpochs % Shuffle data. shuffle(mbq) % Loop over mini-batches. while hasdata(mbq) iteration = iteration + 1; [dlX,dlT] = next(mbq); % Evaluate the model gradients, state, and loss using dlfeval and the % modelGradients function. [gradients,loss] = dlfeval(@modelGradients, parameters, dlX, dlT, hyperparameters); % Update the network parameters using the Adam optimizer. [parameters,trailingAvg,trailingAvgSq] = adamupdate(parameters,gradients, ... trailingAvg,trailingAvgSq,iteration); % Display the training progress. D = duration(0,0,toc(start),Format="hh:mm:ss"); loss = double(gather(extractdata(loss))); addpoints(lineLossTrain,iteration,loss) title("Epoch: " + epoch + ", Elapsed: " + string(D)) drawnow end end
Протестируйте точность классификации модели путем сравнения предсказаний на протянутом наборе тестов с истинными метками.
Загрузите тестовые данные.
[XTest,TTest] = digitTest4DArrayData;
После обучения создание предсказаний на новых данных не требует меток. Создайте minibatchqueue
объект, содержащий только предикторы тестовых данных:
Определите номер выходных параметров мини-пакетной очереди к 1.
Задайте тот же мини-пакетный размер, используемый для обучения.
Предварительно обработайте предикторы с помощью preprocessPredictors
функция, перечисленная в разделе Mini-Batch Predictors Preprocessing Function примера.
Для одного выхода datastore задайте мини-пакетный формат "SSCB"
(пространственный, пространственный, канал, пакет).
dsTest = arrayDatastore(XTest,IterationDimension=4); mbqTest = minibatchqueue(dsTest,1, ... MiniBatchSize=miniBatchSize, ... MiniBatchFormat="SSCB", ... MiniBatchFcn=@preprocessPredictors);
Цикл по мини-пакетам и классифицирует последовательности с помощью modelPredictions
функция, перечисленная в разделе Model Predictions Function примера.
YPred = modelPredictions(parameters,hyperparameters,mbqTest,classNames);
Визуализируйте предсказания в матрице беспорядка.
figure confusionchart(TTest,YPred)
Функциональный model
берет в качестве входа параметры модели, входные данные dlX
, гиперпараметры модели и выходные параметры предсказания для меток.
Эта схема обрисовывает в общих чертах структуру модели.
Для нейронной операции ODE используйте dlode45
функционируйте и задайте odeModel
функция, перечисленная в разделе ODE Function примера. Увеличьте абсолютную и относительную погрешность с помощью AbsoluteTolerance
и RelativeTolerance
аргументы name-value, соответственно. Чтобы вычислить градиенты путем решения связанной примыкающей системы ОДУ, установите GradientMode
опция к "adjoint"
.
function dlY = model(parameters,dlX,hyperparameters) % Convolution, ReLU. weights = parameters.conv1.Weights; bias = parameters.conv1.Bias; dlY = dlconv(dlX,weights,bias,Padding="same",Stride=2); dlY = relu(dlY); % Augment. weights = parameters.neuralode.Weights; numChannels = size(dlY,3); szAugmented = size(dlY); szAugmented(3) = size(weights,3) - numChannels; dlY0 = cat(3, dlY, zeros(szAugmented,"like",dlY)); % Neural ODE. tspan = hyperparameters.neuralode.tspan; dlY = dlode45(@odeModel,tspan,dlY0,parameters.neuralode, ... GradientMode="adjoint", ... AbsoluteTolerance=1e-3, ... RelativeTolerance=1e-4); % Discard augmentation. dlY(:,:,numChannels+1:end,:) = []; % Fully connect, softmax. weights = parameters.fc1.Weights; bias = parameters.fc1.Bias; dlY = fullyconnect(dlY,weights,bias); dlY = softmax(dlY); end
Нейронная операция ODE состоит из операции свертки, сопровождаемой tanh операцией.
Функция ОДУ odeModel
берет в качестве входа входные параметры функции t
(неиспользованный) и y
и параметры функции ОДУ p
содержание весов свертки и смещений, и возвращает выходной параметр блочной операции свертки-tanh.
function z = odeModel(t,y,p) weights = p.Weights; bias = p.Bias; z = dlconv(y,weights,bias,Padding="same"); z = tanh(z); end
modelGradients
функционируйте берет в качестве входа параметры модели, мини-пакет входных данных dlX
с соответствующими целями dlT
, и гиперпараметры модели, и возвращают градиенты потери относительно настраиваемых параметров и соответствующей потери. Чтобы вычислить градиенты с помощью автоматического дифференцирования, используйте dlgradient
функция.
function [gradients,loss] = modelGradients(parameters,dlX,dlT,hyperparameters) dlY = model(parameters,dlX,hyperparameters); loss = crossentropy(dlY,dlT); gradients = dlgradient(loss,parameters); end
modelPredictions
функционируйте берет в качестве входа параметры модели, гиперпараметры модели, minibatchqueue
из входных данных mbq
, и сетевые классы, и вычисляют предсказания модели путем итерации по всем данным в minibatchqueue
объект. Функция использует onehotdecode
функционируйте, чтобы найти предсказанные классы с самым высоким счетом.
function predictions = modelPredictions(parameters,hyperparameters,mbq,classNames) predictions = []; while hasdata(mbq) dlX = next(mbq); dlYPred = model(parameters,dlX,hyperparameters); YPred = onehotdecode(dlYPred,classNames,1)'; predictions = [predictions; YPred]; end end
preprocessMiniBatch
функция предварительно обрабатывает мини-пакет предикторов и меток с помощью следующих шагов:
Предварительно обработайте изображения с помощью preprocessPredictors
функция.
Извлеките данные о метке из массива входящей ячейки и конкатенируйте в категориальный массив вдоль второго измерения.
Одногорячий кодируют категориальные метки в числовые массивы. Кодирование в первую размерность производит закодированный массив, который совпадает с формой сетевого выхода.
function [X,Y] = preprocessMiniBatch(XCell,YCell) % Preprocess predictors. X = preprocessPredictors(XCell); % Extract label data from cell and concatenate. Y = cat(2,YCell{:}); % One-hot encode labels. Y = onehotencode(Y,1); end
preprocessPredictors
функция предварительно обрабатывает мини-пакет предикторов путем извлечения данных изображения из входного массива ячеек и конкатенации данных в числовой массив. Для полутонового входа, конкатенирующего по четвертой размерности, добавляет третью размерность в каждое изображение, чтобы использовать в качестве одноэлементной размерности канала.
function X = preprocessPredictors(XCell) X = cat(4,XCell{:}); end
Чен, Рики Т. К., Юлия Рубанова, Джесси Бетанкур и Давид Дювено. “Нейронные Обыкновенные дифференциальные уравнения”. Предварительно распечатайте, представленный 19 июня 2018. https://arxiv.org/abs/1806.07366.
Дюпон, Emilien, Арно Дусэ и Ии Вай Тех. “Увеличенные Нейронные ОДУ”. Предварительно распечатайте, представленный 26 октября 2019. https://arxiv.org/abs/1904.01681.
dlode45
| dlarray
| dlgradient
| dlfeval
| adamupdate