Этот пример показывает, как обучить нейронную сеть, которая устойчива к состязательным примерам, используя якобинскую схему регуляризации [1].
Нейронные сети могут быть восприимчивы к явлению, известному как состязательные примеры [2], где очень небольшие изменения входных данных могут привести к его неправильной классификации. Эти изменения часто незаметны для людей. Показано, что такие методы второго порядка, как якобинская регуляризация, помогают повысить надежность сетей против противников [3].
Рассмотрим, например, приведенный ниже рисунок. Слева - изображение нуля, а справа - то же изображение с белым шумом, добавленным для создания состязательного примера. Сеть, обученная без якобинской регуляризации, правильно классифицирует исходное изображение нуля, но неверно классифицирует пример состязательности. Напротив, сеть, обученная якобинской регуляризации, правильно классифицирует как оригинал, так и шумное изображение.

В этом примере показано, как:
Обучение надежной сети классификации изображений с использованием схемы якобинской регуляризации.
Сравните его прогнозы с сетью, обученной без якобинской регуляризации.
digitTrain4DArrayData функция загружает изображения и их цифровые метки. Создание arrayDatastore объект для изображений и меток, а затем используйте combine для создания единого хранилища данных, содержащего все данные обучения.
[XTrain,YTrain] = digitTrain4DArrayData;
dsXTrain = arrayDatastore(XTrain,'IterationDimension',4);
dsYTrain = arrayDatastore(YTrain);
dsTrain = combine(dsXTrain,dsYTrain);Определите количество занятий в данных обучения.
classes = categories(YTrain); numClasses = numel(classes);
Затем примените шум к обучающим изображениям для создания состязательных примеров. Сравнение изображений из обучающих данных без шума и с шумом, влияющим на 10% пикселей.
Выберите 16 изображений случайным образом.
numImages = size(XTrain,4); randompick = randperm(numImages,16); XOriginal = XTrain(:,:,:,randompick);
Создайте шумные изображения, установив для пропорции пикселов случайное значение в градациях серого.
noiseProp = 0.1; noise = rand(size(XOriginal)); idx = rand(size(XOriginal)) < noiseProp; XNoisy = XOriginal; XNoisy(idx) = noise(idx);
Постройте график исходных изображений рядом с шумными изображениями.
I1 = imtile(XOriginal); I2 = imtile(XNoisy); figure; subplot(1,2,1) imshow(I1) subplot(1,2,2) imshow(I2)

Определите архитектуру сети.
Укажите слой ввода изображения того же размера, что и учебные изображения.
imageInputSize = size(XTrain, 1:3)
imageInputSize = 1×3
28 28 1
layers = [
imageInputLayer(imageInputSize,'Name','input','Mean',mean(XTrain,4))
convolution2dLayer(5,20,'Name','conv1')
batchNormalizationLayer('Name','bn1')
reluLayer('Name','relu1')
convolution2dLayer(3,20,'Padding',1,'Name','conv2')
batchNormalizationLayer('Name','bn2')
reluLayer('Name','relu2')
convolution2dLayer(3,20,'Padding',1,'Name','conv3')
batchNormalizationLayer('Name','bn3')
reluLayer('Name','relu3')
fullyConnectedLayer(10,'Name','fc')
softmaxLayer('Name','softmax')];
lgraph = layerGraph(layers);Создать dlnetwork объект из графа слоев.
dlnet = dlnetwork(lgraph);
Создание функции modelGradients, перечисленных в конце примера, который принимает dlnetwork объект и мини-пакет входных данных с соответствующими метками и возвращает градиенты потерь относительно обучаемых параметров в сети, состояния сети и потерь.
Поезд на 15 эпох с размером мини-партии 32.
numEpochs = 15; miniBatchSize = 32;
Укажите параметры оптимизации SGDM. Укажите скорость обучения 0,01 и импульс 0,9.
learningRate = 0.01; momentum = 0.9;
Якобская регуляризация λ JR - гиперпараметр, контролирующий влияние якобинского термина регуляризации на обучение сети. Если коэффициент слишком велик, то член перекрестной энтропии эффективно не минимизируется и точность классификации сети плохая. Если коэффициент слишком мал, обученная сеть не имеет ожидаемой устойчивости к белому шуму. Например, выберите 1.
jacobianRegularizationCoefficient = 1;
Создать minibatchqueue объект, обрабатывающий и управляющий мини-партиями изображений во время обучения. Для каждой мини-партии:
Использование пользовательской функции предварительной обработки мини-партии preprocessMiniBatch (определяется в конце этого примера) для преобразования меток в однокодированные переменные.
Форматирование данных изображения с метками размеров 'SSCB' (пространственный, пространственный, канальный, пакетный). По умолчанию minibatchqueue объект преобразует данные в dlarray объекты с базовым типом single. Не добавляйте формат к меткам класса.
Обучение на GPU, если он доступен. Если графический процессор доступен, minibatchqueue объект преобразует каждый вывод в gpuArray по умолчанию. Для использования графического процессора требуется Toolbox™ параллельных вычислений и поддерживаемое устройство графического процессора. Сведения о поддерживаемых устройствах см. в разделе Поддержка графического процессора по выпуску (Parallel Computing Toolbox).
mbq = minibatchqueue(dsTrain,... 'MiniBatchSize',miniBatchSize,... 'MiniBatchFcn', @preprocessMiniBatch,... 'PartialMiniBatch',"discard",... 'MiniBatchFormat',{'SSCB',''});
Инициализируйте график хода обучения.
figure; lineLossTrain = animatedline('Color',[0.85 0.325 0.098]); ylim([0 inf]) xlabel("Iteration") ylabel("Loss") grid on
Инициализируйте параметр скорости для решателя SGDM.
velocity = [];
Обучение сети с использованием пользовательского цикла обучения.
Для каждой эпохи тасуйте данные и закольцовывайте мини-пакеты данных. Для каждой мини-партии:
Оцените градиенты модели, состояние и потери с помощью dlfeval и modelGradients и обновить состояние сети.
Обновление параметров сети с помощью sgdmupdate функция.
Просмотрите ход обучения.
iteration = 0; start = tic; % Loop over epochs. for epoch = 1:numEpochs % Reset and shuffle mini-batch queue. shuffle(mbq); while hasdata(mbq) iteration = iteration + 1; % Read mini-batch of data. [dlX, dlY] = next(mbq); % Evaluate the model gradients and the network state using % dlfeval and the modelGradients function listed at the end of the example. [gradTotalLoss, state, totalLoss] = dlfeval(@modelGradients, dlnet, dlX, dlY, ... miniBatchSize, jacobianRegularizationCoefficient); dlnet.State = state; % Update the network parameters. [dlnet, velocity] = sgdmupdate(dlnet,gradTotalLoss,velocity,learningRate,momentum); % Plot the training progress. D = duration(0,0,toc(start),'Format','hh:mm:ss'); addpoints(lineLossTrain,iteration,double(gather(extractdata(totalLoss)))) title("Training with Jacobian regularization" + ", Epoch: " + epoch + ", Elapsed: " + string(D)) drawnow end end

Загрузить опорную сеть, с теми же слоями, но обученную без якобинской регуляризации.
dlnetReference = load("dlnetWithoutJacobian.mat").dlnetReference;Загрузите данные теста для сравнения между сетью, обученной якобинской регуляризации, и опорной сетью.
[XTest, YTest] = digitTest4DArrayData; classes = categories(YTest);
Пройдите через тестовые образы, которые сети не видели ранее. При каждом проходе добавьте шум, затрагивающий от 0% до 50% пикселей с шагом 5%.
% Initialize test parameters and arrays. noiseProps = 0:0.05:0.5; % Prepare arguments for mini-batch queue. dsYTest = arrayDatastore(YTest); miniBatchSize = 5000; for i = 1:numel(noiseProps) % Load the noise proportion. noiseProp = noiseProps(i); fprintf("Testing robustness to noise proportion %1.2g\n", noiseProp) % Set a proportion of the pixels to a random grayscale value. noise = rand(size(XTest)); idx = rand(size(XTest)) < noiseProp; XNoisy = XTest; XNoisy(idx) = noise(idx); % Prepare mini-batch queue with noisy test data. dsXTest = arrayDatastore(XNoisy,'IterationDimension',4); dsTest = combine(dsXTest,dsYTest); mbq = minibatchqueue(dsTest,... 'MiniBatchSize',miniBatchSize,... 'MiniBatchFcn', @preprocessMiniBatch,... 'MiniBatchFormat',{'SSCB',''}); % Loop over batches to find predicted classifications. while hasdata(mbq) [dlXNoisy, dlY] = next(mbq); % Classify noisy data with the robust network. dlYPredNoisy = predict(dlnet, dlXNoisy); % Convert the predictions into labels. YPred = onehotdecode(dlYPredNoisy, classes, 1)'; YTestBatch = onehotdecode(dlY, classes, 1)'; % Evaluate accuracy of predictions. accuracyRobust(i) = mean(YPred == YTestBatch); % Classify noisy data with reference network. dlYPredNoisy = predict(dlnetReference, dlXNoisy); % Convert the predictions into labels. YPred = onehotdecode(dlYPredNoisy, classes, 1)'; % Evaluate accuracy of predictions. accuracyReference(i) = mean(YPred == YTestBatch); end end
Testing robustness to noise proportion 0 Testing robustness to noise proportion 0.05 Testing robustness to noise proportion 0.1 Testing robustness to noise proportion 0.15 Testing robustness to noise proportion 0.2 Testing robustness to noise proportion 0.25 Testing robustness to noise proportion 0.3 Testing robustness to noise proportion 0.35 Testing robustness to noise proportion 0.4 Testing robustness to noise proportion 0.45 Testing robustness to noise proportion 0.5
Постройте график результатов процентной точности обеих сетей по отношению к доле белого шума.
Следует отметить, что сеть, обученная якобинской регуляризации, имеет несколько более низкую точность, когда пропорция шума равна 0, но достигает более высокой точности, чем опорная сеть, когда шум добавляется к изображениям.
x = noiseProps'; figure; plot(x,accuracyRobust*100, '-o', x,accuracyReference*100, '-o') xlabel('Proportion of noise') ylabel('Accuracy (%)') xlim([0,0.5]); ylim([0,100]); title('Image classification accuracy') legend('Jacobian regularization', 'Reference');

Добавьте шум, влияющий на 15% пикселей, к первому тестовому изображению, содержащему число 0. Постройте график как исходного изображения, так и изображения, возмущенного белым шумом. Используйте сеть, обученную якобинской регуляризации, и справочную сеть для классификации изображения.
% Choose test image testchoice = 1; % Add noise, with a proportion of 0.15, to the first image. noise = rand(size(XTest(:,:,:,testchoice))); idx = rand(size(XTest(:,:,:,testchoice))) < 0.15; XNoisy = XTest(:,:,:,testchoice); XNoisy(idx) = noise(idx); % Convert to dlarray. dlXTest = dlarray(XTest(:,:,:,testchoice),'SSCB'); dlXNoisy = dlarray(XNoisy,'SSCB'); % Print true number classification disp("True digit label: " + char(YTest(testchoice)));
True digit label: 0
Классифицируйте исходное изображение с помощью сети, обученной якобинской регуляризации.
dlYPredTestJR = predict(dlnet, dlXTest);
YPredTestJR = onehotdecode(dlYPredTestJR, classes, 1)';
disp("Robust network classification of original image: " + char(YPredTestJR));Robust network classification of original image: 0
Классифицируйте шумное изображение с помощью сети, обученной якобинской регуляризации.
dlYPredNoisyJR = predict(dlnet, dlXNoisy);
YPredNoisyJR = onehotdecode(dlYPredNoisyJR, classes, 1)';
disp("Robust network classification of noisy image: " + char(YPredNoisyJR));Robust network classification of noisy image: 0
Классифицируйте исходное изображение с помощью сети, обученной без якобинской регуляризации.
dlYPredTest = predict(dlnetReference, dlXTest);
YPredTestR = onehotdecode(dlYPredTest, classes, 1)';
disp("Reference network classification of original image: " + char(YPredTestR));Reference network classification of original image: 0
Классифицируйте шумное изображение с помощью сети, обученной без якобинской регуляризации.
dlYPredNoisy = predict(dlnetReference, dlXNoisy);
YPredNoisyR = onehotdecode(dlYPredNoisy, classes, 1)';
disp("Reference network classification of noisy image: " + char(YPredNoisyR));Reference network classification of noisy image: 8
Постройте график оригинальных и шумных изображений и отобразите прогнозы, заданные каждой сетью.
figure; I1 = XTest(:,:,:,testchoice); subplot(1,2,1) imshow(I1) title('Original image') xlabel({"Prediction without"; "Jacobian regularization: " + char(YPredTestR);... "Prediction with"; "Jacobian regularization: " + char(YPredTestJR)}) I2 = XNoisy; subplot(1,2,2) imshow(I2) title('Noisy image') xlabel({"Prediction without"; "Jacobian regularization: " + char(YPredNoisyR);... "Prediction with"; "Jacobian regularization: " + char(YPredNoisyJR)})

Цель якобинской регуляризации состоит в том, чтобы наказать большие изменения прогноза в отношении небольших изменений во входном x. Это делает сеть более надежной для входных данных, загрязненных шумом. Jacobian кодирует изменение предсказания по отношению к входному сигналу путем содержания частных производных по отношению к .
Якобская регуляризация достигается добавлением нормы Фробениуса якобиана к функции потерь, которая впоследствии минимизируется при обучении сети. Однако якобиан может быть дорогостоящим в вычислении, требуя обратных проходов через сеть, где - размер выходного . Поэтому вместо вычисления полного якобиана вычисляется приближение к норме Фробениуса якобиана следующим образом [4]:
∑k=1mproj =1mproj∑k=1mproj ‖22.
где ) является вычетом из стандартного нормального распределения, а Im является матрицей тождества m-на-m. Это может быть реализовано следующим образом :
0
Выберите мини-партию размера
Для mproj
Выборка случайного вектора )
Нормализовать случайный вектор ‖ 2
Вычислите производную )
мпродж
Градиент внутреннего произведения вектора требует одного обратного прохода для вычисления. Таким образом, это приближение требует только обратных проходов для вычисления, и на практике 1.
В этом примере используется перекрестная энтропия между предсказанной классификацией y и истинной классификацией z, что приводит к функции потерь.
λ JR2JR
где - коэффициент регуляризации Якобиана. Аппроксимация нормы Фробениуса якобиана требует принятия градиентов относительно , а фаза тренировки требует принятия градиентов потерь относительно параметров. Эти расчеты требуют поддержки автоматического дифференцирования второго порядка.
modelGradients используется во время обучения сети. В качестве входных данных используется сеть, входные данные. dlX, их соответствующие классификации dlY, размер мини-партии miniBatchSizeи якобианский коэффициент регуляризации jacobianRegularizationCoefficient. Функция возвращает градиент потерь относительно параметров сети gradTotalLoss, состояние сети state, и общий убыток totalLoss. Для вычисления аппроксимации к норме якобиана берется производная векторно-векторного скалярного произведения. Поскольку производная второго порядка необходима для вычисления градиента функции потерь относительно параметров сети, необходимо установить опцию 'EnableHigherDerivatives' комуtrue' при вызове функции dlgradient.
function [gradTotalLoss, state, totalLoss] = modelGradients(net, dlX, dlY, miniBatchSize, jacobianRegularizationCoefficient) % Find prediction and loss. [dlZ,state] = forward(net, dlX); loss = crossentropy(dlZ, dlY); numClasses = size(dlZ,1); numProjections = 1; regularizationTerm = 0; % Compute Jacobian term and its gradient. for i = 1:numProjections % Sample a matrix whose elements are drawn from the standard Normal distribution. rndarray = randn(numClasses, miniBatchSize); % Normalize the columns of the random matrix. rndarray = normc(rndarray); % Compute the vector-vector product. vectorproduct = rndarray(:)' * dlZ(:); % Compute the gradient of the vector-vector product. Since another % derivative will be taken, set EnableHigherDerivatives to true. vectorJacobianTerm = dlgradient(vectorproduct, dlX, 'EnableHigherDerivatives', true); % Multiply by necessary constants to obtain approximation of the % Frobenius norm of the Jacobian. regularizationTerm = regularizationTerm + numClasses*sum(vectorJacobianTerm.^2,'all') /(numProjections*miniBatchSize); end totalLoss = loss + jacobianRegularizationCoefficient/2 * regularizationTerm; % Calculate the gradient of the loss. gradTotalLoss = dlgradient(totalLoss, net.Learnables); end
preprocessMiniBatch функция выполняет предварительную обработку данных с помощью следующих шагов:
Извлеките данные изображения из входящего массива ячеек и объедините их в числовой массив. При конкатенации над четвертым размером к каждому изображению добавляется третий размер, который будет использоваться в качестве размера одиночного канала.
Извлеките данные метки из входящего массива ячеек и объедините их в категориальный массив вдоль второго измерения.
Одноконтурное кодирование категориальных меток в числовые массивы. Кодирование меток в первом измерении создает закодированный массив, который соответствует форме сетевого вывода.
function [X, Y] = preprocessMiniBatch(XCell,YCell) % Extract image data from cell and concatenate X = cat(4,XCell{1:end}); % Extract label data from cell and concatenate Y = cat(2,YCell{1:end}); % One-hot encode labels Y = onehotencode(Y,1); end
Хоффман, Джуди, Дэниел А. Робертс и Шо Яида. «Надежное обучение с якобинской регуляризацией». Препринт, представлен 7 августа 2019 года. https://arxiv.org/abs/1908.02729.
Сегеди, Кристиан, Войцех Заремба, Илья Суцкевер, Йоан Бруна, Думитру Эрхан, Иэн Гудфеллоу, и Роб Фергус. «Интригующие свойства нейронных сетей». Препринт, представлен 19 февраля 2014 года. http://arxiv.org/abs/1312.6199.
Ма, Эвери, Фарташ Фагри и Амир-Массуд Фарахманд. «Состязательность через регуляризацию: подход второго порядка». Препринт, подан, 3 апреля 2020 года. http://arxiv.org/abs/2004.01832.
Гудфеллоу, Йен Дж., Джонатон Шленс и Кристиан Сегеди. «Объяснение и использование состязательных примеров». Препринт, представлено, 20 марта 2015 года. http://arxiv.org/abs/1412.6572.
dlarray | dlfeval | dlgradient | dlnetwork | minibatchqueue | onehotdecode | onehotencode | predict | sgdmupdate