В этом примере показано, как обновить состояние сети в сети, определенной как функция.
Операция нормализации партии . нормализует каждый входной канал через мини-пакет. Чтобы ускорить обучение сверточных нейронных сетей и уменьшить чувствительность к инициализации сети, используйте нормализацию партии . операции между свертками и нелинейностями, такими как слои ReLU.
Во время обучения операции нормализации партии . сначала нормализуют активации каждого канала путем вычитания мини-среднего значения партии и деления на стандартное отклонение мини-пакета. Затем операция сдвигает вход на усвояемое смещение β и масштабирует его на усвояемый масштабный коэффициент β.
При использовании обученной сети для предсказаний новых данных в операциях нормализации партии . используются среднее значение обученного набора данных и дисперсия вместо мини-среднего значения партии и отклонения для нормализации активаций.
Чтобы вычислить статистику набора данных, необходимо отслеживать статистику мини-пакета, используя постоянно обновляющееся состояние.
Если вы используете операции нормализации партии . в функции модели, то вы должны задать поведение и для обучения, и для предсказания. Например, можно задать логическую опцию doTraining чтобы контролировать, использует ли модель мини-пакетную статистику для обучения или статистику набора данных для предсказания.
Этот пример кода из функции модели показывает, как применить операцию нормализации партии . и обновить только статистику набора данных во время обучения.
if doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); % Update state state.batchnorm1.TrainedMean = trainedMean; state.batchnorm1.TrainedVariance = trainedVariance; else dlY = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); end
The digitTrain4DArrayData функция загружает изображения, их метки цифр и углы поворота от вертикали. Создайте arrayDatastore объект для изображений, меток и углов, а затем используйте combine функция, чтобы создать один datastore, который содержит все обучающие данные. Извлеките имена классов и количество недискретных ответов.
[XTrain,YTrain,anglesTrain] = digitTrain4DArrayData;
dsXTrain = arrayDatastore(XTrain,'IterationDimension',4);
dsYTrain = arrayDatastore(YTrain);
dsAnglesTrain = arrayDatastore(anglesTrain);
dsTrain = combine(dsXTrain,dsYTrain,dsAnglesTrain);
classNames = categories(YTrain);
numClasses = numel(classNames);
numResponses = size(anglesTrain,2);
numObservations = numel(YTrain);Просмотрите некоторые изображения из обучающих данных.
idx = randperm(numObservations,64); I = imtile(XTrain(:,:,:,idx)); figure imshow(I)

Задайте следующую сеть, которая предсказывает и метки, и углы поворота.
Блок свертки-batchnorm-ReLU с 16 фильтрами 5 на 5.
Ветвь из двух блоков свертки-batchnorm каждый с 32 фильтрами 3 на 3 с операцией ReLU между
Пропускное соединение с блоком свертки-batchnorm с 32 свертками 1 на 1.
Объедините обе ветви с помощью сложения и последующей операции ReLU
Для вывода регрессии выход ветвь с полностью связанной операцией размера 1 (количество откликов).
Для вывода классификации выход ветвь с полностью связанной операцией размера 10 (количество классов) и операцией softmax.

Определите параметры для каждой из операций и включите их в struct. Используйте формат parameters.OperationName.ParameterName где parameters - struct, O perationName - имя операции (для примера «conv1») и ParameterName - имя параметра (для примера - «Веса»).
Создайте struct parameters содержащие параметры модели. Инициализируйте обучаемые веса и смещения слоев с помощью initializeGlorot и initializeZeros функции , взятые в качестве примера,, соответственно. Инициализируйте параметры смещения и шкалы нормализации партии . с помощью initializeZeros и initializeOnes функции , взятые в качестве примера,, соответственно.
Чтобы выполнить обучение и вывод с использованием слоев нормализации партии ., необходимо также управлять состоянием сети. Перед предсказанием необходимо задать среднее значение набора данных и отклонения, выведенные из обучающих данных. Создайте struct state содержит параметры состояния. Статистика нормализации партии . не должна быть dlarray объекты. Инициализируйте нормализацию партии ., обученную средним и обученным состояниям отклонения, используя zeros и ones функций, соответственно.
Функции , взятые в качестве примера, инициализации присоединены к этому примеру как вспомогательные файлы.
Инициализируйте параметры для первого сверточного слоя.
filterSize = [5 5]; numChannels = 1; numFilters = 16; 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]);
Инициализируйте параметры и состояние для первого слоя нормализации партии ..
parameters.batchnorm1.Offset = initializeZeros([numFilters 1]); parameters.batchnorm1.Scale = initializeOnes([numFilters 1]); state.batchnorm1.TrainedMean = zeros(numFilters,1,'single'); state.batchnorm1.TrainedVariance = ones(numFilters,1,'single');
Инициализируйте параметры для второго сверточного слоя.
filterSize = [3 3]; numChannels = 16; numFilters = 32; sz = [filterSize numChannels numFilters]; numOut = prod(filterSize) * numFilters; numIn = prod(filterSize) * numFilters; parameters.conv2.Weights = initializeGlorot(sz,numOut,numIn); parameters.conv2.Bias = initializeZeros([numFilters 1]);
Инициализируйте параметры и состояние для второго слоя нормализации партии ..
parameters.batchnorm2.Offset = initializeZeros([numFilters 1]); parameters.batchnorm2.Scale = initializeOnes([numFilters 1]); state.batchnorm2.TrainedMean = zeros(numFilters,1,'single'); state.batchnorm2.TrainedVariance = ones(numFilters,1,'single');
Инициализируйте параметры для третьего сверточного слоя.
filterSize = [3 3]; numChannels = 32; numFilters = 32; sz = [filterSize numChannels numFilters]; numOut = prod(filterSize) * numFilters; numIn = prod(filterSize) * numFilters; parameters.conv3.Weights = initializeGlorot(sz,numOut,numIn); parameters.conv3.Bias = initializeZeros([numFilters 1]);
Инициализируйте параметры и состояние для третьего слоя нормализации партии ..
parameters.batchnorm3.Offset = initializeZeros([numFilters 1]); parameters.batchnorm3.Scale = initializeOnes([numFilters 1]); state.batchnorm3.TrainedMean = zeros(numFilters,1,'single'); state.batchnorm3.TrainedVariance = ones(numFilters,1,'single');
Инициализируйте параметры для сверточного слоя в пропускающем соединении.
filterSize = [1 1]; numChannels = 16; numFilters = 32; sz = [filterSize numChannels numFilters]; numOut = prod(filterSize) * numFilters; numIn = prod(filterSize) * numFilters; parameters.convSkip.Weights = initializeGlorot(sz,numOut,numIn); parameters.convSkip.Bias = initializeZeros([numFilters 1]);
Инициализируйте параметры и состояние для слоя нормализации партии . в пропускающем соединении.
parameters.batchnormSkip.Offset = initializeZeros([numFilters 1]); parameters.batchnormSkip.Scale = initializeOnes([numFilters 1]); state.batchnormSkip.TrainedMean = zeros([numFilters 1],'single'); state.batchnormSkip.TrainedVariance = ones([numFilters 1],'single');
Инициализируйте параметры для полносвязного слоя, соответствующего выходу классификации.
sz = [numClasses 6272]; numOut = numClasses; numIn = 6272; parameters.fc1.Weights = initializeGlorot(sz,numOut,numIn); parameters.fc1.Bias = initializeZeros([numClasses 1]);
Инициализируйте параметры для полносвязного слоя, соответствующего выходу регрессии.
sz = [numResponses 6272]; numOut = numResponses; numIn = 6272; parameters.fc2.Weights = initializeGlorot(sz,numOut,numIn); parameters.fc2.Bias = initializeZeros([numResponses 1]);
Просмотрите struct состояния.
state
state = struct with fields:
batchnorm1: [1×1 struct]
batchnorm2: [1×1 struct]
batchnorm3: [1×1 struct]
batchnormSkip: [1×1 struct]
Просмотр параметров состояния для batchnorm1 операция.
state.batchnorm1
ans = struct with fields:
TrainedMean: [16×1 single]
TrainedVariance: [16×1 single]
Создайте функцию model, перечисленный в конце примера, который вычисляет выходы модели глубокого обучения, описанной ранее.
Функция model принимает за вход параметры модели parameters, входные данные dlX, флаг doTraining, который определяет, возвращает ли модель выходы для обучения или предсказания, и состояние сети state. Сеть выводит предсказания для меток, предсказания для углов и обновленное состояние сети.
Создайте функцию modelGradients, перечисленный в конце примера, который принимает за вход мини-пакет входных данных dlX с соответствующими целями T1 и T2 содержит метки и углы, соответственно, и возвращает градиенты потерь относительно настраиваемых параметров, обновленного состояния сети и соответствующих потерь.
Задайте опции обучения.
numEpochs = 20;
miniBatchSize = 128;
plots = "training-progress";Обучите модель с помощью пользовательского цикла обучения. Использование minibatchqueue для обработки и управления мини-пакетами изображений. Для каждого мини-пакета:
Используйте пользовательскую функцию мини-пакетной предварительной обработки preprocessMiniBatch (определено в конце этого примера), чтобы закодировать метки классов с одним «горячим» кодом.
Форматируйте данные изображения с помощью меток размерностей 'SSCB' (пространственный, пространственный, канальный, пакетный). По умолчанию в minibatchqueue объект преобразует данные в dlarray объекты с базовым типом single. Не добавляйте формат к меткам классов или углам.
Обучите на графическом процессоре, если он доступен. По умолчанию в minibatchqueue объект преобразует каждый выход в gpuArray при наличии графический процессор. Для использования графический процессор требуется Parallel Computing Toolbox™ и поддерживаемый графический процессор. Для получения информации о поддерживаемых устройствах смотрите Поддержку GPU by Release (Parallel Computing Toolbox).
mbq = minibatchqueue(dsTrain,... 'MiniBatchSize',miniBatchSize,... 'MiniBatchFcn', @preprocessMiniBatch,... 'MiniBatchFormat',{'SSCB','',''});
Для каждой эпохи перетасуйте данные и закольцовывайте по мини-пакетам данных. В конце каждой эпохи отобразите процесс обучения. Для каждого мини-пакета:
Оцените градиенты модели и потери с помощью dlfeval и modelGradients функция.
Обновляйте параметры сети с помощью adamupdate функция.
Инициализируйте параметры для решателя Адама.
trailingAvg = []; trailingAvgSq = [];
Инициализируйте график процесса обучения.
if plots == "training-progress" figure lineLossTrain = animatedline('Color',[0.85 0.325 0.098]); ylim([0 inf]) xlabel("Iteration") ylabel("Loss") grid on end
Обучите модель.
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,dlY1,dlY2] = next(mbq); % Evaluate the model gradients, state, and loss using dlfeval and the % modelGradients function. [gradients,state,loss] = dlfeval(@modelGradients, parameters, dlX, dlY1, dlY2, state); % Update the network parameters using the Adam optimizer. [parameters,trailingAvg,trailingAvgSq] = adamupdate(parameters,gradients, ... trailingAvg,trailingAvgSq,iteration); % Display the training progress. if plots == "training-progress" D = duration(0,0,toc(start),'Format','hh:mm:ss'); addpoints(lineLossTrain,iteration,double(gather(extractdata(loss)))) title("Epoch: " + epoch + ", Elapsed: " + string(D)) drawnow end end end

Протестируйте классификационную точность модели путем сравнения предсказаний на тестовом наборе с истинными метками и углами. Управление набором тестовых данных с помощью minibatchqueue объект с той же настройкой, что и обучающие данные.
[XTest,Y1Test,anglesTest] = digitTest4DArrayData; dsXTest = arrayDatastore(XTest,'IterationDimension',4); dsYTest = arrayDatastore(Y1Test); dsAnglesTest = arrayDatastore(anglesTest); dsTest = combine(dsXTest,dsYTest,dsAnglesTest); mbqTest = minibatchqueue(dsTest,... 'MiniBatchSize',miniBatchSize,... 'MiniBatchFcn', @preprocessMiniBatch,... 'MiniBatchFormat',{'SSCB','',''});
Чтобы предсказать метки и углы данных валидации, используйте modelPredictions функции, перечисленной в конце примера. Функция возвращает предсказанные классы и углы, а также сравнение с истинными значениями.
[classesPredictions,anglesPredictions,classCorr,angleDiff] = modelPredictions(parameters,state,mbqTest,classNames);
Оцените точность классификации.
accuracy = mean(classCorr)
accuracy = 0.9840
Оцените точность регрессии.
angleRMSE = sqrt(mean(angleDiff.^2))
angleRMSE = single
6.3669
Просмотрите некоторые изображения с их предсказаниями. Отобразите предсказанные углы красного цвета и правильные углы зеленого цвета.
idx = randperm(size(XTest,4),9); figure for i = 1:9 subplot(3,3,i) I = XTest(:,:,:,idx(i)); imshow(I) hold on sz = size(I,1); offset = sz/2; thetaPred = anglesPredictions(idx(i)); plot(offset*[1-tand(thetaPred) 1+tand(thetaPred)],[sz 0],'r--') thetaValidation = anglesTest(idx(i)); plot(offset*[1-tand(thetaValidation) 1+tand(thetaValidation)],[sz 0],'g--') hold off label = string(classesPredictions(idx(i))); title("Label: " + label) end

Функция model принимает за вход параметры модели parameters, входные данные dlX, флаг doTraining, который определяет, возвращает ли модель выходы для обучения или предсказания, и состояние сети state. Функция возвращает предсказания для меток, предсказания для углов и обновленное состояние сети.
function [dlY1,dlY2,state] = model(parameters,dlX,doTraining,state) % Convolution weights = parameters.conv1.Weights; bias = parameters.conv1.Bias; dlY = dlconv(dlX,weights,bias,'Padding',2); % Batch normalization, ReLU offset = parameters.batchnorm1.Offset; scale = parameters.batchnorm1.Scale; trainedMean = state.batchnorm1.TrainedMean; trainedVariance = state.batchnorm1.TrainedVariance; if doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); % Update state state.batchnorm1.TrainedMean = trainedMean; state.batchnorm1.TrainedVariance = trainedVariance; else dlY = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); end dlY = relu(dlY); % Convolution, batch normalization (skip connection) weights = parameters.convSkip.Weights; bias = parameters.convSkip.Bias; dlYSkip = dlconv(dlY,weights,bias,'Stride',2); offset = parameters.batchnormSkip.Offset; scale = parameters.batchnormSkip.Scale; trainedMean = state.batchnormSkip.TrainedMean; trainedVariance = state.batchnormSkip.TrainedVariance; if doTraining [dlYSkip,trainedMean,trainedVariance] = batchnorm(dlYSkip,offset,scale,trainedMean,trainedVariance); % Update state state.batchnormSkip.TrainedMean = trainedMean; state.batchnormSkip.TrainedVariance = trainedVariance; else dlYSkip = batchnorm(dlYSkip,offset,scale,trainedMean,trainedVariance); end % Convolution weights = parameters.conv2.Weights; bias = parameters.conv2.Bias; dlY = dlconv(dlY,weights,bias,'Padding',1,'Stride',2); % Batch normalization, ReLU offset = parameters.batchnorm2.Offset; scale = parameters.batchnorm2.Scale; trainedMean = state.batchnorm2.TrainedMean; trainedVariance = state.batchnorm2.TrainedVariance; if doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); % Update state state.batchnorm2.TrainedMean = trainedMean; state.batchnorm2.TrainedVariance = trainedVariance; else dlY = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); end dlY = relu(dlY); % Convolution weights = parameters.conv3.Weights; bias = parameters.conv3.Bias; dlY = dlconv(dlY,weights,bias,'Padding',1); % Batch normalization offset = parameters.batchnorm3.Offset; scale = parameters.batchnorm3.Scale; trainedMean = state.batchnorm3.TrainedMean; trainedVariance = state.batchnorm3.TrainedVariance; if doTraining [dlY,trainedMean,trainedVariance] = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); % Update state state.batchnorm3.TrainedMean = trainedMean; state.batchnorm3.TrainedVariance = trainedVariance; else dlY = batchnorm(dlY,offset,scale,trainedMean,trainedVariance); end % Addition, ReLU dlY = dlYSkip + dlY; dlY = relu(dlY); % Fully connect, softmax (labels) weights = parameters.fc1.Weights; bias = parameters.fc1.Bias; dlY1 = fullyconnect(dlY,weights,bias); dlY1 = softmax(dlY1); % Fully connect (angles) weights = parameters.fc2.Weights; bias = parameters.fc2.Bias; dlY2 = fullyconnect(dlY,weights,bias); end
The modelGradients функция принимает за вход параметры модели, мини-пакет входных данных dlX с соответствующими целями T1 и T2 содержит метки и углы, соответственно, и возвращает градиенты потерь относительно настраиваемых параметров, обновленного состояния сети и соответствующих потерь.
function [gradients,state,loss] = modelGradients(parameters,dlX,T1,T2,state) doTraining = true; [dlY1,dlY2,state] = model(parameters,dlX,doTraining,state); lossLabels = crossentropy(dlY1,T1); lossAngles = mse(dlY2,T2); loss = lossLabels + 0.1*lossAngles; gradients = dlgradient(loss,parameters); end
The modelPredictions функция принимает параметры модели, состояние сети, minibatchqueue входных данных mbq, и сетевых классов, и возвращает предсказания модели путем итерации по всем данным в minibatchqueue использование model функция со doTraining значение опции установлено в false. Функция возвращает предсказанные классы и углы, а также сравнение с истинными значениями. Для классов сравнение является вектором таковых и нулей, который представляет правильные и неправильные предсказания. Для углов сравнение является различием между предсказанным углом и истинным значением.
function [classesPredictions,anglesPredictions,classCorr,angleDiff] = modelPredictions(parameters,state,mbq,classes) doTraining = false; classesPredictions = []; anglesPredictions = []; classCorr = []; angleDiff = []; while hasdata(mbq) [dlX,dlY1,dlY2] = next(mbq); % Make predictions using the model function. [dlY1Pred,dlY2Pred] = model(parameters,dlX,doTraining,state); % Determine predicted classes. Y1PredBatch = onehotdecode(dlY1Pred,classes,1); classesPredictions = [classesPredictions Y1PredBatch]; % Dermine predicted angles Y2PredBatch = extractdata(dlY2Pred); anglesPredictions = [anglesPredictions Y2PredBatch]; % Compare predicted and true classes Y1 = onehotdecode(dlY1,classes,1); classCorr = [classCorr Y1PredBatch == Y1]; % Compare predicted and true angles angleDiffBatch = Y2PredBatch - dlY2; angleDiff = [angleDiff extractdata(gather(angleDiffBatch))]; end end
The preprocessMiniBatch функция предварительно обрабатывает данные с помощью следующих шагов:
Извлеките данные изображения из входящего массива ячеек и соедините в числовой массив. Конкатенация данных изображения по четвертому измерению добавляет третье измерение к каждому изображению, которое используется в качестве размерности одинарного канала.
Извлеките данные о метках и углах из входящих массивов ячеек и сгруппируйте в категориальный массив и числовой массив, соответственно.
Однократное кодирование категориальных меток в числовые массивы. Кодирование в первую размерность создает закодированный массив, который совпадает с формой выходного сигнала сети.
function [X,Y,angle] = preprocessMiniBatch(XCell,YCell,angleCell) % Extract image data from cell and concatenate X = cat(4,XCell{:}); % Extract label data from cell and concatenate Y = cat(2,YCell{:}); % Extract angle data from cell and concatenate angle = cat(2,angleCell{:}); % One-hot encode labels Y = onehotencode(Y,1); end
batchnorm | crossentropy | dlarray | dlconv | dlfeval | dlgradient | fullyconnect | minibatchqueue | onehotdecode | onehotencode | relu | sgdmupdate | softmax