exponenta event banner

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

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

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

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

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

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

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

Загрузка данных обучения

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 - гиперпараметр, контролирующий влияние якобинского термина регуляризации на обучение сети. Если коэффициент слишком велик, то член перекрестной энтропии эффективно не минимизируется и точность классификации сети плохая. Если коэффициент слишком мал, обученная сеть не имеет ожидаемой устойчивости к белому шуму. Например, выберите λ 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)})

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

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

J = [∂ y1  x1   y1  xn   ym  x1   ym  xn]

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

J ‖F2=tr (J J ) =Ev∼N (0, я), v ДЖЕЙ-ДЖЕЙ v≈1mproj ∑k=1mproj vk J 22 =1mproj∑k=1mproj ∇x [vk y] ‖22.

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

JR = 0

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

Для i = 1,..., mproj

  1. Выборка случайного вектора v∼N (0,Im)

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

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

  4. JR = JR + m ∇x (v⊤ y) 22 B мпродж

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

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

loss = перекрестная энтропия + λ 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. Сегеди, Кристиан, Войцех Заремба, Илья Суцкевер, Йоан Бруна, Думитру Эрхан, Иэн Гудфеллоу, и Роб Фергус. «Интригующие свойства нейронных сетей». Препринт, представлен 19 февраля 2014 года. http://arxiv.org/abs/1312.6199.

  3. Ма, Эвери, Фарташ Фагри и Амир-Массуд Фарахманд. «Состязательность через регуляризацию: подход второго порядка». Препринт, подан, 3 апреля 2020 года. http://arxiv.org/abs/2004.01832.

  4. Гудфеллоу, Йен Дж., Джонатон Шленс и Кристиан Сегеди. «Объяснение и использование состязательных примеров». Препринт, представлено, 20 марта 2015 года. http://arxiv.org/abs/1412.6572.

См. также

| | | | | | | |

Связанные темы