Используйте байесовую оптимизацию в пользовательских учебных экспериментах

В этом примере показано, как использовать Байесовую оптимизацию, чтобы найти, что оптимальные гиперзначения параметров для пользовательского обучения экспериментируют в Experiment Manager. Байесова оптимизация предоставляет альтернативную стратегию широким гиперпараметрам в эксперименте. Вы указываете диапазон значений для каждого гиперпараметра и выбираете метрику, чтобы оптимизировать, и Experiment Manager ищет комбинацию гиперпараметров, которая оптимизирует вашу выбранную метрику. Байесова оптимизация требует Statistics and Machine Learning Toolbox™.

В этом примере вы обучаете сеть, чтобы классифицировать изображения рукописных цифр с помощью пользовательского расписания скорости обучения. Эксперимент использует Байесовую оптимизацию, чтобы найти тип расписания и комбинацию гиперпараметров, которая максимизирует точность валидации. Для получения дополнительной информации об использовании пользовательского расписания скорости обучения смотрите, Обучат сеть Используя Пользовательский Учебный Цикл, и Кусочный Изучают Расписание Уровня.

В качестве альтернативы можно найти оптимальные гиперзначения параметров программно путем вызова bayesopt функция. Для получения дополнительной информации смотрите, что Глубокое обучение Использует Байесовую Оптимизацию.

Открытый эксперимент

Во-первых, откройте пример. Experiment Manager загружает проект с предварительно сконфигурированным экспериментом, который можно смотреть и запустить. Чтобы открыть эксперимент, в панели Браузера Эксперимента, дважды кликают имя эксперимента (BayesOptExperiment).

Пользовательские учебные эксперименты состоят из описания, таблицы гиперпараметров и учебной функции. Эксперименты, которые используют Байесовую оптимизацию, включают дополнительные опции ограничить длительность эксперимента. Для получения дополнительной информации смотрите, Конфигурируют Пользовательский Учебный Эксперимент.

Поле Description содержит текстовое описание эксперимента. В данном примере описание:

Classification of digits, using two custom learning rate schedules:
* decay - Use the learning rate p(t) = p(0)/(1+kt), where t is the iteration number and k is DecayRate.
* piecewise - Multiply the learning rate by DropFactor every 100 iterations.

Раздел Hyperparameters задает стратегию (Bayesian Optimization) и опции гиперпараметра, чтобы использовать для эксперимента. Для каждого гиперпараметра задайте эти опции:

  • Область значений — Вводит двухэлементный вектор, который дает нижнюю границу и верхнюю границу действительного - или гиперпараметр с целочисленным знаком, или массив строк или массив ячеек, который перечисляет возможные значения категориального гиперпараметра.

  • Введите — выбирают real (гиперпараметр с действительным знаком), integer (гиперпараметр с целочисленным знаком), или categorical (категориальный гиперпараметр).

  • Преобразуйте — выбирают none (никакое преобразование) или log (логарифмическое преобразование). Для log, гиперпараметром должен быть real или integer и положительный. При использовании этой опции гиперпараметр ищется и моделируется на логарифмическом масштабе.

Когда вы запускаете эксперимент, Experiment Manager ищет лучшую комбинацию гиперпараметров. Каждое испытание в эксперименте использует новую комбинацию гиперзначений параметров на основе результатов предыдущих испытаний. Этот пример использует гиперпараметры Schedule, InitialLearnRate, DecayRate, и DropFactor задавать пользовательское расписание скорости обучения, используемое для обучения. Опции для Schedule :

  • decay — Для каждой итерации используйте основанную на времени скорость обучения$\rho_t = \frac{\rho_0}{1+kt}$, где$t$ номер итерации,$\rho_0$ начальная скорость обучения, задан InitialLearnRate, и$k$ уровень затухания, заданный DecayRate. Эта опция игнорирует значение гиперпараметра DropFactor.

  • piecewise — Начните с начальной скорости обучения, заданной InitialLearnRate и периодически пропускайте скорость обучения путем умножения фактором отбрасывания, заданным DropFactor. В этом примере скорость обучения пропускает каждые 100 итераций. Эта опция игнорирует значение гиперпараметра DecayRate.

Модели InitialLearnRate эксперимента и DecayRate на логарифмическом масштабе, потому что область значений значений для этих гиперпараметров (0.001 к 0.1) промежутки несколько порядков величины. В отличие от этого значения для DropFactor лежите в диапазоне от 0.1 к 0.9, так модели DropFactor эксперимента в линейной шкале.

В соответствии с Байесовыми Опциями Оптимизации, можно задать длительность эксперимента путем ввода максимального времени (в секундах) и максимальное количество испытаний, чтобы запуститься. Чтобы лучше всего использовать степень Байесовой оптимизации, выполните по крайней мере 30 оценок целевой функции.

Учебная Функция задает обучающие данные, сетевую архитектуру, опции обучения и метод обучения, используемый экспериментом. Вход к учебной функции является структурой с полями от гипертаблицы параметров и experiments.Monitor возразите, что можно использовать, чтобы отследить прогресс обучения, значения записи метрик, используемых обучением, и произвести учебные графики. Учебная функция возвращает структуру, которая содержит обучивший сеть, учебную потерю, точность валидации и среду выполнения, используемую для обучения. Experiment Manager сохраняет этот выход, таким образом, можно экспортировать его в рабочее пространство MATLAB, когда обучение завершено. Учебная функция имеет пять разделов.

  • Инициализируйте Выход, устанавливает начальное значение сети, потери и точности к пустым массивам, чтобы указать, что обучение не запустилось. Эксперимент устанавливает среду выполнения на "auto", таким образом, это обучает сеть на графическом процессоре, если вы доступны. Используя графический процессор требует Parallel Computing Toolbox™ и поддерживаемого устройства графического процессора. Для получения дополнительной информации смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox).

output.trainedNet = [];
output.trainingInfo.loss = [];
output.trainingInfo.accuracy = [];
output.executionEnvironment = "auto";
  • Обучающие данные загрузки задают данные об обучении и валидации для эксперимента как увеличенные хранилища данных изображений с помощью набора данных Цифр. Для каждого изображения в наборе обучающих данных эксперимент применяет случайный перевод до 5 пикселей на горизонтальных и вертикальных осях. Для получения дополнительной информации об этом наборе данных смотрите Наборы Данных изображения.

dataFolder = fullfile(toolboxdir("nnet"), ...
    "nndemos","nndatasets","DigitDataset");
imds = imageDatastore(dataFolder, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");
[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9,'randomize');
inputSize = [28 28 1];
pixelRange = [-5 5];
imageAugmenter = imageDataAugmenter( ...
    RandXTranslation = pixelRange, ...
    RandYTranslation = pixelRange);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
    DataAugmentation = imageAugmenter);
augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);
classes = categories(imdsTrain.Labels);
numClasses = numel(classes);
  • Архитектура Сети Define задает архитектуру для сети классификации изображений. Чтобы обучить сеть с пользовательским учебным циклом и включить автоматическое дифференцирование, учебная функция преобразует график слоев в dlnetwork объект.

layers = [
    imageInputLayer(inputSize,Normalization="none",Name="input")
    convolution2dLayer(5,20,Name ="conv1")
    batchNormalizationLayer(Name="bn1")
    reluLayer(Name="relu1")
    convolution2dLayer(3,20,Padding="same",Name="conv2")
    batchNormalizationLayer(Name="bn2")
    reluLayer(Name="relu2")
    convolution2dLayer(3,20,Padding="same",Name="conv3")
    batchNormalizationLayer(Name="bn3")
    reluLayer(Name="relu3")
    fullyConnectedLayer(numClasses,Name="fc")
    softmaxLayer(Name="softmax")];
lgraph = layerGraph(layers);
dlnet = dlnetwork(lgraph);
  • Укажите, что Опции обучения задают опции обучения, используемые экспериментом. В этом примере Experiment Manager обучает сети с мини-пакетным размером 128 в течение 10 эпох с помощью пользовательского расписания скорости обучения, заданного гиперпараметрами.

numEpochs = 10;
miniBatchSize = 128;
momentum = 0.9;
learnRateSchedule = params.Schedule;
initialLearnRate = params.InitialLearnRate;
learnRateDecay = params.DecayRate;
learnRateDropFactor = params.DropFactor;
learnRateDropPeriod = 100;
learnRate = initialLearnRate;
  • Обучайтесь Модель задает пользовательский учебный цикл, используемый экспериментом. Пользовательский учебный цикл использует minibatchqueue обработать и управлять мини-пакетами изображений. Для каждого мини-пакета, minibatchqueue объект преобразует метки в одногорячие закодированные переменные и форматирует данные изображения с размерностью, маркирует 'SSCB' (пространственный, пространственный, канал, пакет). По умолчанию, minibatchqueue объект преобразует данные в dlarray объекты с базовым типом single. Если вы обучаетесь на графическом процессоре, данные преобразованы в gpuArray (Parallel Computing Toolbox) объекты. В течение каждой эпохи пользовательский учебный цикл переставляет datastore, циклы по мини-пакетам данных, и оценивает градиенты модели, состояние и потерю. Затем учебная функция определяет скорость обучения для выбранного расписания и обновляет сетевые параметры. После каждой итерации пользовательского учебного цикла учебная функция вычисляет точность валидации, сохраняет обучивший сеть, и обновляет процесс обучения.

monitor.Metrics = ["LearnRate" "TrainingLoss" "ValidationAccuracy"];
monitor.XLabel = "Iteration";
mbq = minibatchqueue(augimdsTrain,...
    MiniBatchSize=miniBatchSize,...
    MiniBatchFcn=@preprocessMiniBatch,...
    MiniBatchFormat={'SSCB',''},...
    OutputEnvironment=output.executionEnvironment);
iteration = 0;
velocity = [];
for epoch = 1:numEpochs
    shuffle(mbq);
    while hasdata(mbq)
        iteration = iteration + 1;
        [dlX, dlY] = next(mbq);
        [gradients,state,loss] = dlfeval(@modelGradients,dlnet,dlX,dlY);
        dlnet.State = state;
        switch learnRateSchedule
            case "decay"
                learnRate = initialLearnRate/(1 + learnRateDecay*iteration);
            case "piecewise"
                if mod(iteration,learnRateDropPeriod) == 0
                    learnRate = learnRate*learnRateDropFactor;
                end
        end
        recordMetrics(monitor,iteration, ...
            LearnRate=learnRate, ...
            TrainingLoss=loss);
        output.trainingInfo.loss = [output.trainingInfo.loss; iteration loss];
        [dlnet,velocity] = sgdmupdate(dlnet,gradients,velocity,learnRate,momentum);
        if monitor.Stop
            return;
        end
    end
    numOutputs = 1;
    mbqTest = minibatchqueue(augimdsValidation,numOutputs, ...
        MiniBatchSize=miniBatchSize, ...
        MiniBatchFcn=@preprocessMiniBatchPredictors, ...
        MiniBatchFormat="SSCB");
    predictions = modelPredictions(dlnet,mbqTest,classes);
    YTest = imdsValidation.Labels;
    accuracy = mean(predictions == YTest)*100.0;
    output.trainedNet = dlnet;
    monitor.Progress = (epoch*100.0)/numEpochs;
    recordMetrics(monitor,iteration, ...
        ValidationAccuracy=accuracy);
    output.trainingInfo.accuracy = [output.trainingInfo.accuracy; iteration accuracy];
end

Чтобы смотреть учебную функцию, под Учебной Функцией, нажимают Edit. Учебная функция открывается в Редакторе MATLAB®. Кроме того, код для учебной функции появляется в Приложении 1 в конце этого примера.

В разделе Metrics поля Optimize и Direction указывают на метрику, которую Байесов алгоритм оптимизации использует в качестве целевой функции. Для этого эксперимента Experiment Manager стремится максимизировать значение точности валидации.

Запустите эксперимент

Когда вы запускаете эксперимент, Experiment Manager обучает сеть, заданную учебной функцией многократно. Каждое испытание использует различную комбинацию гиперзначений параметров. По умолчанию Experiment Manager запускает одно испытание за один раз. Если у вас есть Parallel Computing Toolbox, можно запустить несколько испытаний одновременно. Для лучших результатов, прежде чем вы запустите свой эксперимент, начинают параллельный пул со стольких же рабочих сколько графические процессоры. Для получения дополнительной информации смотрите Использование Experiment Manager, чтобы Обучить нейронные сети параллельно.

  • Чтобы запустить один суд над экспериментом за один раз, на панели инструментов Experiment Manager, нажимают Run.

  • Чтобы запустить несколько испытаний одновременно, нажмите Use Parallel и затем Запуск. Если нет никакого текущего параллельного пула, Experiment Manager запускает тот с помощью кластерного профиля по умолчанию. Experiment Manager затем выполняет несколько одновременных испытаний, в зависимости от количества параллельных доступных рабочих.

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

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

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

Оцените результаты

Чтобы протестировать лучшее испытание в вашем эксперименте, постройте матрицу беспорядка.

  1. В таблице результатов выберите испытание с самой высокой точностью валидации.

  2. На панели инструментов Experiment Manager нажмите Export.

  3. В диалоговом окне введите имя переменной рабочей области для экспортируемого учебного выхода. Именем по умолчанию является trainingOutput.

  4. Создайте матрицу беспорядка путем вызова drawConfusionMatrix функция, которая перечислена в Приложении 3 в конце этого примера. Как вход к функции, используйте экспортируемый учебный выход и часть набора данных Цифр, чтобы использовать в качестве набора тестов. Например, в командном окне MATLAB, введите:

drawConfusionMatrix(trainingOutput,0.5)

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

Чтобы записать наблюдения о результатах вашего эксперимента, добавьте аннотацию.

  1. В таблице результатов щелкните правой кнопкой по ячейке ValidationAccuracy для лучшего испытания.

  2. Выберите Add Annotation.

  3. В панели Аннотаций введите свои наблюдения в текстовое поле.

Для получения дополнительной информации смотрите сортировку, Фильтр, и Аннотируйте Результаты Эксперимента.

Закройте эксперимент

В панели Браузера Эксперимента щелкните правой кнопкой по имени проекта и выберите Close Project. Experiment Manager закрывает все эксперименты и результаты, содержавшиеся в проекте.

Приложение 1: учебная функция

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

Входной параметр

  • params структура с полями от гипертаблицы параметров Experiment Manager.

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

Вывод

  • output структура, которая содержит обучивший сеть, значения учебной потери и точности валидации и среды выполнения, используемой для обучения. Experiment Manager сохраняет этот выход, таким образом, можно экспортировать его в рабочее пространство MATLAB, когда обучение завершено.

function output = BayesOptExperiment_training(params,monitor)

output.trainedNet = [];
output.trainingInfo.loss = [];
output.trainingInfo.accuracy = [];
output.executionEnvironment = "auto";

dataFolder = fullfile(toolboxdir("nnet"), ...
    "nndemos","nndatasets","DigitDataset");
imds = imageDatastore(dataFolder, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");
[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9,'randomize');
inputSize = [28 28 1];
pixelRange = [-5 5];
imageAugmenter = imageDataAugmenter( ...
    RandXTranslation = pixelRange, ...
    RandYTranslation = pixelRange);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
    DataAugmentation = imageAugmenter);
augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);
classes = categories(imdsTrain.Labels);
numClasses = numel(classes);

layers = [
    imageInputLayer(inputSize,Normalization="none",Name="input")
    convolution2dLayer(5,20,Name ="conv1")
    batchNormalizationLayer(Name="bn1")
    reluLayer(Name="relu1")
    convolution2dLayer(3,20,Padding="same",Name="conv2")
    batchNormalizationLayer(Name="bn2")
    reluLayer(Name="relu2")
    convolution2dLayer(3,20,Padding="same",Name="conv3")
    batchNormalizationLayer(Name="bn3")
    reluLayer(Name="relu3")
    fullyConnectedLayer(numClasses,Name="fc")
    softmaxLayer(Name="softmax")];
lgraph = layerGraph(layers);
dlnet = dlnetwork(lgraph);

numEpochs = 10;
miniBatchSize = 128;
momentum = 0.9;

learnRateSchedule = params.Schedule;
initialLearnRate = params.InitialLearnRate;
learnRateDecay = params.DecayRate;
learnRateDropFactor = params.DropFactor;
learnRateDropPeriod = 100;
learnRate = initialLearnRate;

monitor.Metrics = ["LearnRate" "TrainingLoss" "ValidationAccuracy"];
monitor.XLabel = "Iteration";

mbq = minibatchqueue(augimdsTrain,...
    MiniBatchSize=miniBatchSize,...
    MiniBatchFcn=@preprocessMiniBatch,...
    MiniBatchFormat={'SSCB',''},...
    OutputEnvironment=output.executionEnvironment);

iteration = 0;
velocity = [];
for epoch = 1:numEpochs
    shuffle(mbq);

    while hasdata(mbq)
        iteration = iteration + 1;

        [dlX, dlY] = next(mbq);
        
        [gradients,state,loss] = dlfeval(@modelGradients,dlnet,dlX,dlY);
        dlnet.State = state;
        
        switch learnRateSchedule
            case "decay"
                learnRate = initialLearnRate/(1 + learnRateDecay*iteration);
            case "piecewise"
                if mod(iteration,learnRateDropPeriod) == 0
                    learnRate = learnRate*learnRateDropFactor;
                end
        end
        
        recordMetrics(monitor,iteration, ...
            LearnRate=learnRate, ...
            TrainingLoss=loss);
        output.trainingInfo.loss = [output.trainingInfo.loss; iteration loss];
        
        [dlnet,velocity] = sgdmupdate(dlnet,gradients,velocity,learnRate,momentum);
        
        if monitor.Stop
            return;
        end
    end

    numOutputs = 1;
    mbqTest = minibatchqueue(augimdsValidation,numOutputs, ...
        MiniBatchSize=miniBatchSize, ...
        MiniBatchFcn=@preprocessMiniBatchPredictors, ...
        MiniBatchFormat="SSCB");
    predictions = modelPredictions(dlnet,mbqTest,classes);
    YTest = imdsValidation.Labels;
    accuracy = mean(predictions == YTest)*100.0;
    
    output.trainedNet = dlnet;
    monitor.Progress = (epoch*100.0)/numEpochs;
    recordMetrics(monitor,iteration, ...
        ValidationAccuracy=accuracy);
    output.trainingInfo.accuracy = [output.trainingInfo.accuracy; iteration accuracy];
end
end

Приложение 2: пользовательские учебные функции помощника

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

function [gradients,state,loss] = modelGradients(dlnet,dlX,Y)
[dlYPred,state] = forward(dlnet,dlX);
loss = crossentropy(dlYPred,Y);
gradients = dlgradient(loss,dlnet.Learnables);
loss = double(gather(extractdata(loss)));
end

modelPredictions функционируйте берет в качестве входа dlnetwork объект dlnet, minibatchqueue из входных данных mbq, и сетевые классы, и вычисляют предсказания модели путем итерации по всем данным в minibatchqueue объект. Функция использует onehotdecode функционируйте, чтобы найти предсказанный класс с самым высоким счетом.

function predictions = modelPredictions(dlnet,mbq,classes)
predictions = [];
while hasdata(mbq)
    dlXTest = next(mbq);
    dlYPred = predict(dlnet,dlXTest);
    YPred = onehotdecode(dlYPred,classes,1)';
    predictions = [predictions; YPred];
end
end

preprocessMiniBatch функция предварительно обрабатывает мини-пакет предикторов и меток с помощью этих шагов:

  1. Предварительно обработайте изображения с помощью preprocessMiniBatchPredictors функция.

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

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

function [X,Y] = preprocessMiniBatch(XCell,YCell)
X = preprocessMiniBatchPredictors(XCell);
Y = cat(2,YCell{1:end});
Y = onehotencode(Y,1);
end

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

function X = preprocessMiniBatchPredictors(XCell)
X = cat(4,XCell{1:end});
end

Приложение 3: создайте матрицу беспорядка

Эта функция берет в качестве входа обучивший сеть и часть набора данных Цифр, чтобы использовать в качестве набора тестов и создает матричный график беспорядка. Эта функция использует функции помощника modelPredictions и preprocessMiniBatchPredictors, которые перечислены в Приложении 2.

function drawConfusionMatrix(trainingOutput,testSize)

dataFolder = fullfile(toolboxdir("nnet"), ...
    "nndemos","nndatasets","DigitDataset");
imds = imageDatastore(dataFolder, ...
    IncludeSubfolders=true, ....
    LabelSource="foldernames");
imdsTest = splitEachLabel(imds,testSize,"randomize");
inputSize = [28 28 1];
imageAugmenter = imageDataAugmenter(RandRotation=[-15 15]);
augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest, ...
    DataAugmentation=imageAugmenter);
classes = categories(imdsTest.Labels);

trainedNet = trainingOutput.trainedNet;
numOutputs = 1;
miniBatchSize = 128;
mbqTest = minibatchqueue(augimdsTest,numOutputs, ...
    MiniBatchSize=miniBatchSize, ...
    MiniBatchFcn=@preprocessMiniBatchPredictors, ...
    MiniBatchFormat="SSCB");
predictedLabels = modelPredictions(trainedNet,mbqTest,classes);
trueLabels = imdsTest.Labels;

figure
confusionchart(trueLabels,predictedLabels, ...
    ColumnSummary="column-normalized", ...
    RowSummary="row-normalized", ...
    Title="Confusion Matrix for Digits Data Set");
cm = gcf;
cm.Position(3) = cm.Position(3)*1.5;

end

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

Приложения

Объекты

Похожие темы