В этом примере показано, как обновить сетевое состояние в сети, заданной как функция.
Операция нормализации партии. нормирует каждый входной канал через мини-пакет. Чтобы ускорить обучение сверточных нейронных сетей и уменьшать чувствительность к сетевой инициализации, используйте операции нормализации партии. между свертками и нелинейностью, такой как слои ReLU.
Во время обучения операции нормализации партии. сначала нормируют активации каждого канала путем вычитания мини-среднего значения партии и деления на мини-пакетное стандартное отклонение. Затем операция переключает вход learnable смещением β и масштабирует его learnable масштабным коэффициентом γ.
Когда вы используете обучивший сеть, чтобы сделать предсказания на новых данных, операции нормализации партии. используют обученное среднее значение набора данных и отклонение вместо мини-среднего значения партии и отклонение, чтобы нормировать активации.
Чтобы вычислить статистику набора данных, необходимо отслеживать мини-пакетную статистику при помощи постоянно обновляющегося состояния.
Если вы используете операции нормализации партии. в функции модели, то необходимо задать поведение и для обучения и для предсказания. Например, можно задать булев параметр 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
digitTrain4DArrayData
функционируйте загружает изображения, их метки цифры и их углы вращения от вертикали.
[XTrain,YTrain,anglesTrain] = digitTrain4DArrayData; classNames = categories(YTrain); numClasses = numel(classNames); numObservations = numel(YTrain);
Просмотрите некоторые изображения от обучающих данных.
idx = randperm(numObservations,64); I = imtile(XTrain(:,:,:,idx)); figure imshow(I)
Задайте следующую сеть, которая предсказывает и метки и углы вращения.
Блок свертки, нормализации партии., операций ReLU с 16 фильтрами 5 на 5
Ветвь двух блоков свертки и операций нормализации партии., каждого с 32 3х3 фильтрами и разделенный операцией ReLU
Связь пропуска с блоком свертки и операций нормализации партии. с 32 свертками 1 на 1
Объедините обе ветви с помощью операции сложения, сопровождаемой операцией ReLU
Для регрессии выход, ветвь с полностью операцией connect размера 1 (количество ответов)
Для классификации выход, ветвь с полностью операцией connect размера 10 (количество классов) и softmax операцией
Задайте параметры для каждой из операций и включайте их в struct. Используйте формат parameters.OperationName.ParameterName
где parameters
struct, OperationName
имя операции (например, conv_1
), и ParameterName
имя параметра (например, Weights
).
Создайте struct parameters
содержа параметры модели. Инициализируйте learnable веса слоя с помощью функции, взятой в качестве примера, initializeGaussian
, перечисленный в конце примера. Инициализируйте learnable смещения слоя нулями. Инициализируйте смещение нормализации партии. и масштабные коэффициенты с нулями и единицами, соответственно.
Чтобы выполнить обучение и вывод с помощью слоев нормализации партии., необходимо также управлять сетевым состоянием. Перед предсказанием необходимо задать среднее значение набора данных и отклонение, выведенное из обучающих данных. Создайте struct state
содержа параметры состояния. Инициализируйте нормализацию партии. обученное среднее значение и обученные состояния отклонения с нулями и единицами, соответственно.
parameters.conv1.Weights = dlarray(initializeGaussian([5,5,1,16])); parameters.conv1.Bias = dlarray(zeros(16,1,'single')); parameters.batchnorm1.Offset = dlarray(zeros(16,1,'single')); parameters.batchnorm1.Scale = dlarray(ones(16,1,'single')); state.batchnorm1.TrainedMean = zeros(16,1,'single'); state.batchnorm1.TrainedVariance = ones(16,1,'single'); parameters.convSkip.Weights = dlarray(initializeGaussian([1,1,16,32])); parameters.convSkip.Bias = dlarray(zeros(32,1,'single')); parameters.batchnormSkip.Offset = dlarray(zeros(32,1,'single')); parameters.batchnormSkip.Scale = dlarray(ones(32,1,'single')); state.batchnormSkip.TrainedMean = zeros(32,1,'single'); state.batchnormSkip.TrainedVariance = ones(32,1,'single'); parameters.conv2.Weights = dlarray(initializeGaussian([3,3,16,32])); parameters.conv2.Bias = dlarray(zeros(32,1,'single')); parameters.batchnorm2.Offset = dlarray(zeros(32,1,'single')); parameters.batchnorm2.Scale = dlarray(ones(32,1,'single')); state.batchnorm2.TrainedMean = zeros(32,1,'single'); state.batchnorm2.TrainedVariance = ones(32,1,'single'); parameters.conv3.Weights = dlarray(initializeGaussian([3,3,32,32])); parameters.conv3.Bias = dlarray(zeros(32,1,'single')); parameters.batchnorm3.Offset = dlarray(zeros(32,1,'single')); parameters.batchnorm3.Scale = dlarray(ones(32,1,'single')); state.batchnorm3.TrainedMean = zeros(32,1,'single'); state.batchnorm3.TrainedVariance = ones(32,1,'single'); parameters.fc2.Weights = dlarray(initializeGaussian([numClasses,6272])); parameters.fc2.Bias = dlarray(zeros(numClasses,1,'single')); parameters.fc1.Weights = dlarray(initializeGaussian([1,6272])); parameters.fc1.Bias = dlarray(zeros(1,1,'single'));
Просмотрите struct состояния.
state
state = struct with fields:
batchnorm1: [1×1 struct]
batchnormSkip: [1×1 struct]
batchnorm2: [1×1 struct]
batchnorm3: [1×1 struct]
Просмотрите параметры состояния для batchnorm1
операция.
state.batchnorm1
ans = struct with fields:
TrainedMean: [16×1 single]
TrainedVariance: [16×1 single]
Создайте функциональный model
, перечисленный в конце примера, который вычисляет выходные параметры модели глубокого обучения, описанной ранее.
Функциональный model
берет в качестве входа входные данные dlX
, параметры модели parameters
, флаг doTraining
, который задает, возвращает ли модель выходные параметры для обучения или предсказания и сетевого state
состояния. Сетевые выходные параметры предсказания для меток, предсказания для углов и обновленное сетевое состояние.
Создайте функциональный modelGradients
, перечисленный в конце примера, который берет в качестве входа мини-пакет входных данных dlX
с соответствующими целями T1
и T2
содержание меток и углов, соответственно, и возвращает градиенты потери относительно настраиваемых параметров, обновленного сетевого состояния и соответствующей потери.
Задайте опции обучения.
numEpochs = 20;
miniBatchSize = 128;
plots = "training-progress";
numIterationsPerEpoch = floor(numObservations./miniBatchSize);
Обучайтесь на графическом процессоре, если вы доступны. Используя графический процессор требует Parallel Computing Toolbox™, и CUDA® включил NVIDIA®, графический процессор с вычисляет возможность 3.0 или выше.
executionEnvironment = "auto";
Обучите модель с помощью пользовательского учебного цикла.
В течение каждой эпохи переставьте данные и цикл по мини-пакетам данных. В конце каждой эпохи отобразите прогресс обучения.
Для каждого мини-пакета:
Преобразуйте метки в фиктивные переменные.
Преобразуйте данные в dlarray
объекты с базовым одним типом и указывают, что размерность маркирует 'SSCB'
(пространственный, пространственный, канал, пакет).
Для обучения графического процессора преобразуйте данные в gpuArray
объекты.
Оцените градиенты модели и потерю с помощью dlfeval
и modelGradients
функция.
Обновите сетевые параметры с помощью adamupdate
функция.
Инициализируйте график процесса обучения.
if plots == "training-progress" figure lineLossTrain = animatedline('Color',[0.85 0.325 0.098]); ylim([0 inf]) xlabel("Iteration") ylabel("Loss") grid on end
Инициализируйте параметры для решателя Адама.
trailingAvg = []; trailingAvgSq = [];
Обучите модель.
iteration = 0; start = tic; % Loop over epochs. for epoch = 1:numEpochs % Shuffle data. idx = randperm(numObservations); XTrain = XTrain(:,:,:,idx); YTrain = YTrain(idx); anglesTrain = anglesTrain(idx); % Loop over mini-batches for i = 1:numIterationsPerEpoch iteration = iteration + 1; idx = (i-1)*miniBatchSize+1:i*miniBatchSize; % Read mini-batch of data and convert the labels to dummy % variables. X = XTrain(:,:,:,idx); Y1 = zeros(numClasses, miniBatchSize, 'single'); for c = 1:numClasses Y1(c,YTrain(idx)==classNames(c)) = 1; end Y2 = anglesTrain(idx)'; Y2 = single(Y2); % Convert mini-batch of data to dlarray. dlX = dlarray(X,'SSCB'); % If training on a GPU, then convert data to gpuArray. if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu" dlX = gpuArray(dlX); end % Evaluate the model gradients, state, and loss using dlfeval and the % modelGradients function. [gradients,state,loss] = dlfeval(@modelGradients, dlX, Y1, Y2, parameters, 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
Протестируйте точность классификации модели путем сравнения предсказаний на наборе тестов с истинными метками и углами.
[XTest,YTest,anglesTest] = digitTest4DArrayData;
Преобразуйте данные в dlarray
объект с форматом размерности 'SSCB'
. Для предсказания графического процессора также преобразуйте данные в gpuArray
.
dlXTest = dlarray(XTest,'SSCB'); if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu" dlXTest = gpuArray(dlXTest); end
Чтобы предсказать метки и углы данных о валидации, используйте modelPredictions
функция, перечисленная в конце примера.
[dlYPred,anglesPred] = modelPredictions(parameters,state,dlXTest,miniBatchSize);
Оцените точность классификации.
[~,idx] = max(extractdata(dlYPred),[],1); labelsPred = classNames(idx); accuracy = mean(labelsPred==YTest)
accuracy = 0.9912
Оцените точность регрессии.
angleRMSE = sqrt(mean((extractdata(anglesPred) - anglesTest').^2))
angleRMSE = 6.1576
Просмотрите некоторые изображения с их предсказаниями. Отобразите предсказанные углы красного цвета и правильные метки зеленого цвета.
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 = extractdata(anglesPred(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(labelsPred(idx(i))); title("Label: " + label) end
Функциональный model
берет в качестве входа входные данные dlX
, параметры модели parameters
, флаг doTraining
, который задает, возвращает ли модель выходные параметры для обучения или предсказания и сетевого state
состояния. Функция возвращает предсказания для меток, предсказания для углов и обновленное сетевое состояние.
function [dlY1,dlY2,state] = model(dlX,parameters,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 (angles) weights = parameters.fc1.Weights; bias = parameters.fc1.Bias; dlY2 = fullyconnect(dlY,weights,bias); % Fully connect, softmax (labels) weights = parameters.fc2.Weights; bias = parameters.fc2.Bias; dlY1 = fullyconnect(dlY,weights,bias); dlY1 = softmax(dlY1); end
modelGradients
функционируйте берет в качестве входа мини-пакет входных данных dlX
с соответствующими целями T1
и T2
содержание меток и углов, соответственно, и возвращает градиенты потери относительно настраиваемых параметров, обновленного сетевого состояния и соответствующей потери.
function [gradients,state,loss] = modelGradients(dlX,T1,T2,parameters,state) doTraining = true; [dlY1,dlY2,state] = model(dlX,parameters,doTraining,state); lossLabels = crossentropy(dlY1,T1); lossAngles = mse(dlY2,T2); loss = lossLabels + 0.1*lossAngles; gradients = dlgradient(loss,parameters); end
modelPredictions
функционируйте берет параметры модели, сетевое состояние, массив входных данных dlX
, и мини-пакетный размер, и возвращает предсказания модели путем итерации по мини-пакетам заданного размера с помощью model
функция с doTraining
набор опции к false
.
function [dlYPred,anglesPred] = modelPredictions(parameters,state,dlX,miniBatchSize) doTraining = false; numObservations = size(dlX,4); numIterations = ceil(numObservations / miniBatchSize); numClasses = size(parameters.fc2.Weights,1); dlYPred = zeros(numClasses,numObservations,'like',dlX); anglesPred = zeros(1,numObservations,'like',dlX); for i = 1:numIterations idx = (i-1)*miniBatchSize+1:min(i*miniBatchSize,numObservations); [dlYPred(:,idx),anglesPred(idx)] = model(dlX(:,:,:,idx), parameters,doTraining,state); end end
initializeGaussian
функциональные демонстрационные веса от Распределения Гаусса со средним значением 0 и стандартным отклонением 0.01.
function parameter = initializeGaussian(sz) parameter = randn(sz,'single').*0.01; end
batchnorm
| crossentropy
| dlarray
| dlconv
| dlfeval
| dlgradient
| fullyconnect
| relu
| sgdmupdate
| softmax