Обучите устойчивую нейронную сеть для глубокого обучения с якобиевской регуляризацией

В этом примере показано, как обучить нейронную сеть, которая устойчива к соперничающим примерам с помощью якобиевской схемы [1] регуляризации.

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

Например, рассмотрите рисунок ниже. Слева изображение нуля, и справа то же изображение с белым шумом, добавленным, чтобы создать соперничающий пример. Сеть, обученная без якобиевской регуляризации, классифицирует оригинальное изображение нуля правильно, но неправильно классифицирует соперничающий пример. В отличие от этого сеть, обученная с якобиевской регуляризацией, классифицирует и оригинал и шумное изображение правильно.

В этом примере показано, как к:

  1. Обучите устойчивую сеть классификации изображений использование якобиевской схемы регуляризации.

  2. Сравните его предсказания с сетью, обученной без якобиевской регуляризации.

Загрузите обучающие данные

digitTrain4DArrayData функционируйте загружает изображения и их метки цифры. Создайте arrayDatastore объект для изображений и меток, и затем использует combine функция, чтобы сделать один datastore, который содержит все обучающие данные.

[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)

Сеть Define

Задайте архитектуру сети.

Задайте входной слой изображений одного размера с учебными изображениями.

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);

Функция градиентов модели Define

Создайте функциональный modelGradients, перечисленный в конце примера, который берет dlnetwork объект и мини-пакет входных данных с соответствующими метками, и возвращают градиенты потери относительно настраиваемых параметров в сети, состоянии сети и потере.

Задайте опции обучения

Обучайтесь в течение 15 эпох с мини-пакетным размером 32.

numEpochs = 15;
miniBatchSize = 32;

Задайте опции для оптимизации SGDM. Задайте скорость обучения 0,01 и импульс 0,9.

learningRate = 0.01;
momentum = 0.9;

Якобиевская регуляризация λJRгиперпараметр, который управляет эффектом якобиевского термина регуляризации на обучении сети. Если коэффициент является слишком большим, то перекрестный энтропийный термин эффективно не минимизирован, и точность сетевой классификации плоха. Если коэффициент слишком мал, обучивший сеть не имеет ожидаемой робастности к белому шуму. Например, выбрать λJR=1.

jacobianRegularizationCoefficient = 1;

Обучите модель

Создайте minibatchqueue возразите, что процессы и управляют мини-пакетами изображений во время обучения. Для каждого мини-пакета:

  • Используйте пользовательский мини-пакет, предварительно обрабатывающий функциональный preprocessMiniBatch (заданный в конце этого примера), чтобы преобразовать метки в одногорячие закодированные переменные.

  • Формат данные изображения с размерностью маркирует 'SSCB' (пространственный, пространственный, канал, пакет). По умолчанию, minibatchqueue объект преобразует данные в dlarray объекты с базовым типом single. Не добавляйте формат в метки класса.

  • Обучайтесь на графическом процессоре, если вы доступны. Если графический процессор доступен, minibatchqueue объект преобразует каждый выход в gpuArray по умолчанию. Используя графический процессор требует Parallel Computing 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)})

Функция градиентов модели

Цель якобиевской регуляризации состоит в том, чтобы оштрафовать большие изменения предсказания y относительно небольших изменений во входе x. Выполнение так делает сеть более устойчивой к входным данным загрязненный шумом. Якобиан J кодирует изменение предсказания относительно входа, содержа частные производные y относительно x.

J=[y1x1y1xnymx1ymxn]

Якобиевская регуляризация достигается путем добавления нормы Фробениуса якобиана к функции потерь, которая впоследствии минимизирована, когда вы обучаете сеть. Однако якобиан может быть дорогим, чтобы вычислить, требуя m обратные проходы через сеть, где m размер выхода y. Поэтому вместо того, чтобы вычислить полный якобиан, приближение к норме Фробениуса якобиана (JR) вычисляется можно следующим образом [4]:

JF2=tr(JJ)=EvN(0,Im)vJJv1mprojk=1mprojvkJ22=1mprojk=1mprojx[vky]22.

где vkN(0,Im) ничья от стандартного Нормального распределения и Im m-by-m единичная матрица. Это может быть реализовано можно следующим образом:

JR=0

Выберите мини-пакетный размер B

Для i=1,,mproj

  1. Произведите случайный вектор vN(0,Im)

  2. Нормируйте случайный вектор v=vv2

  3. Вычислите производную x(vy)

  4. JR=JR+mx(vy)22Bmproj

Градиент векторного скалярного произведения требует, чтобы один обратный проход вычислил. Так, это приближение требует только mproj обратные проходы, чтобы вычислить, и на практике, mproj=1.

В этом примере, перекрестной энтропии между предсказанной классификацией y и истинная классификация z используется, приводя к функции потерь

loss=crossentropy+λJR2JR

где λJR якобиевский коэффициент регуляризации. Приближение нормы Фробениуса якобиана требует градиентов взятия относительно x, и учебная фаза требует градиентов взятия потери относительно параметров. Эти вычисления требуют поддержки автоматического дифференцирования второго порядка.

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 функция предварительно обрабатывает данные с помощью следующих шагов:

  1. Извлеките данные изображения из массива входящей ячейки и конкатенируйте в числовой массив. Конкатенация по четвертой размерности добавляет третью размерность в каждое изображение, чтобы использоваться в качестве одноэлементной размерности канала.

  2. Извлеките данные о метке из массива входящей ячейки и конкатенируйте данные в категориальный массив вдоль второго измерения.

  3. Одногорячий кодируют категориальные метки в числовые массивы. Кодирование меток в первую размерность производит закодированный массив, который совпадает с формой сетевого выхода.

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

Ссылки

  1. Хоффман, Джуди, Дэниел А. Робертс и Шо Яида. “Устойчивое Изучение с якобиевской Регуляризацией”. Предварительно распечатайте, представленный 7 августа 2019. https://arxiv.org/abs/1908.02729.

  2. Szegedy, христианин, Войцех Зэремба, Илья Сутскевер, Джоан Бруна, Думитру Эрхэн, Иэн Гудфеллоу и Роб Фергус. “Заинтриговывая Свойства Нейронных сетей”. Предварительно распечатайте, представленный 19 февраля 2014. http://arxiv.org/abs/1312.6199.

  3. Мама, Эйвери, Fartash Faghri и эмир-Massoud Фарахмэнд. “Соперничающая Робастность посредством Регуляризации: Подход Второго порядка”. Предварительно распечатайте, представленный, 3 апреля 2020. http://arxiv.org/abs/2004.01832.

  4. Весельчак, Иэн Дж., Джонатон Шленс и Кристиан Сзеджеди. “Объясняя и Используя Соперничающие Примеры”. Предварительно распечатайте, представленный, 20 марта 2015. http://arxiv.org/abs/1412.6572.

Смотрите также

| | | | | | | |

Похожие темы