Сравнение слоев активации

В этом примере показано, как сравнить точность обучения сетей со слоями активации ReLU, утечки ReLU, ELU и swish.

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

Этот пример показывает, как сравнить точность валидации настройки нейронной сети SqueezeNet при использовании слоев активации ReLU, утечки ReLU, ELU и swish, и сравнивает точность, заданную набором изображений валидации.

Загрузка данных

Загрузите набор данных Flowers.

url = 'http://download.tensorflow.org/example_images/flower_photos.tgz';
downloadFolder = tempdir;
filename = fullfile(downloadFolder,'flower_dataset.tgz');

dataFolder = fullfile(downloadFolder,'flower_photos');
if ~exist(dataFolder,'dir')
    fprintf("Downloading Flowers data set (218 MB)... ")
    websave(filename,url);
    untar(filename,downloadFolder)
    fprintf("Done.\n")
end

Подготовка данных к обучению

Загрузите данные как datastore изображений с помощью imageDatastore и укажите папку, содержащую данные изображения.

imds = imageDatastore(dataFolder, ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

Просмотрите количество классов обучающих данных.

numClasses = numel(categories(imds.Labels))
numClasses = 5

Разделите datastore так, чтобы в каждой категории набора обучающих данных было 80% изображений, а в наборе валидации - оставшиеся изображения от каждой метки.

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.80,'randomize');

Задайте опции увеличения и создайте хранилище данных дополненных изображений, содержащее обучающие изображения.

  • Случайным образом отражайте изображения в горизонтальной оси.

  • Случайным образом масштабируйте изображения до 20%.

  • Случайным образом поверните изображения до 45 дегрессов.

  • Случайным образом переведите изображения до 3 пикселей.

  • Измените размер изображений на вход размер сети (227 на 227)

imageAugmenter = imageDataAugmenter( ...
    'RandXReflection',true, ...
    'RandScale',[0.8 1.2], ...
    'RandRotation',[-45,45], ...
    'RandXTranslation',[-3 3], ...
    'RandYTranslation',[-3 3]);

augimdsTrain = augmentedImageDatastore([227 227],imdsTrain,'DataAugmentation',imageAugmenter);

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

augimdsValidation = augmentedImageDatastore([227 227],imdsValidation);

Создайте пользовательскую функцию построения графика

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

Создайте функцию, которая принимает информационный struct, предоставленную обучающим процессом, и обновляет анимированный линейный график. The updatePlot функция, перечисленная в Функцию построения графика разделе примера, принимает за вход информационную структуру и обновляет указанные анимированные линии.

Настройка опций обучения

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

  • Обучите с использованием мини-партии размером 128 на 60 эпох.

  • Перетасовывайте данные каждую эпоху.

  • Проверяйте нейронную сеть один раз в эпоху, используя удерживаемый набор валидации.

miniBatchSize = 128;
numObservationsTrain = numel(imdsTrain.Files);
numIterationsPerEpoch = floor(numObservationsTrain / miniBatchSize);

options = trainingOptions('adam', ...
    'MiniBatchSize',miniBatchSize, ...
    'MaxEpochs',60, ...
    'Shuffle','every-epoch', ...
    'ValidationData',augimdsValidation, ...
    'ValidationFrequency',numIterationsPerEpoch, ...
    'Verbose',false);

Обучите нейронные сети

Для каждого из типов слоев активации ReLU, утечки ReLU, ELU и swish обучите сеть SqueezeNet.

Задайте типы слоев активации.

activationLayerTypes = ["relu" "leaky-relu" "elu" "swish"];

Инициализируйте настроенный график процесса обучения путем создания анимированных линий с цветами, заданными colororder функция.

figure

colors = colororder;

for i = 1:numel(activationLayerTypes)
    line(i) = animatedline('Color',colors(i,:));
end

ylim([0 100])

legend(activationLayerTypes,'Location','southeast');

xlabel("Iteration")
ylabel("Accuracy")
title("Validation Accuracy")
grid on

Цикл по каждому из типов слоев активации и train нейронной сети. Для каждого типа слоя активации:

  • Создайте указатель на функцию activationLayer который создает слой активации.

  • Создайте новую сеть SqueezeNet без весов и замените слои активации (слои ReLU) слоями типа слоя активации с помощью указателя на функцию activationLayer.

  • Замените конечный слой свертки нейронной сети на слой, задающий количество классов входных данных.

  • Обновите график точности валидации путем установки OutputFcn свойство объекта опций обучения указателю на функцию, представляющему updatePlot функция с анимированной линией, соответствующей типу слоя активации.

  • Train и время работы сети с помощью trainNetwork функция.

for i = 1:numel(activationLayerTypes)
    activationLayerType = activationLayerTypes(i);
    
    % Determine activation layer type.
    switch activationLayerType
        case "relu"
            activationLayer = @reluLayer;
        case "leaky-relu"
            activationLayer = @leakyReluLayer;
        case "elu"
            activationLayer = @eluLayer;
        case "swish"
            activationLayer = @swishLayer;
    end
    
    % Create SqueezeNet layer graph.
    lgraph = squeezenet('Weights','none');
    
    % Replace activation layers.
    if activationLayerType ~= "relu"
        layers = lgraph.Layers;
        for j = 1:numel(layers)
            if isa(layers(j),'nnet.cnn.layer.ReLULayer')
                layerName = layers(j).Name;
                layer = activationLayer('Name',activationLayerType+"_new_"+j);
                lgraph = replaceLayer(lgraph,layerName,layer);
            end
        end
    end
    
    % Specify number of classes in final convolution layer.
    layer = convolution2dLayer([1 1],numClasses,'Name','conv10');
    lgraph = replaceLayer(lgraph,'conv10',layer);
    
    % Specify custom plot function.
    options.OutputFcn = @(info) updatePlot(info,line(i));
    
    % Train the network.
    start = tic;
    [net{i},info{i}] = trainNetwork(augimdsTrain,lgraph,options);
    elapsed(i) = toc(start);
end

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

figure
bar(categorical(activationLayerTypes),elapsed)
title("Training Time")
ylabel("Time (seconds)")

В этом случае использование различных слоев активации дает одинаковые конечные точности валидации с утечками ReLU и качающимися слоями, имеющими несколько более высокие значения. Использование слоев активации качания сходится в меньшем количестве итераций. По сравнению с другими слоями activaiton, использование слоев ELU заставляет точность валидации сходиться в большем количестве итераций и требует большего времени расчетов.

Функция построения графика

The updatePlot функция принимает за вход информационную структуру info и обновляет график валидации, заданный анимированной линией line.

function updatePlot(info,line)

if ~isempty(info.ValidationAccuracy)
    addpoints(line,info.Iteration,info.ValidationAccuracy);
    drawnow limitrate
end

end

См. также

| | | |

Похожие темы