Попробуйте несколько предварительно обученных сетей за передачу обучения

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

Существует много предварительно обученных сетей, доступных в Deep Learning Toolbox™. Эти предварительно обученные сети имеют различные характеристики, которые имеют значение при выборе сети, чтобы примениться проблеме. Самые важные характеристики являются сетевой точностью, скоростью и размером. Выбор сети обычно является компромиссом между этими характеристиками. Чтобы сравнить эффективность различных предварительно обученных сетей для вашей задачи, отредактируйте этот эксперимент и задайте который предварительно обученные сети использовать.

Этот эксперимент требует Модели Deep Learning Toolbox для пакета Сетевой поддержки GoogLeNet и Модели Deep Learning Toolbox для пакета Сетевой поддержки ResNet-18. Прежде чем вы запустите эксперимент, установите эти пакеты поддержки путем вызова googlenet и resnet18 функции и нажатие на ссылки на загрузку. Для получения дополнительной информации о других предварительно обученных сетях, которые можно загрузить с Add-On Explorer, смотрите Предварительно обученные Глубокие нейронные сети.

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

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

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

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

Perform transfer learning by replacing layers in a pretrained network.

Раздел Hyperparameters задает стратегию (Exhaustive Sweep) и гиперзначения параметров, чтобы использовать для эксперимента. Когда вы запускаете эксперимент, Experiment Manager обучает сеть с помощью каждой комбинации гиперзначений параметров, заданных в гипертаблице параметров. В этом примере, гиперпараметр NetworkName задает сеть, чтобы обучаться и значение опции обучения 'miniBatchSize'.

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

  • Загружает предварительно обученную сеть, соответствующую гиперпараметру NetworkName.

networkName = params.NetworkName;
switch networkName
    case "squeezenet"
        net = squeezenet;
        miniBatchSize = 128;
    case "googlenet"
        net = googlenet;
        miniBatchSize = 128;
    case "resnet18"
        net = resnet18;
        miniBatchSize = 128;
    case "mobilenetv2"
        net = mobilenetv2;
        miniBatchSize = 128;
    case "resnet50"
        net = resnet50;
        miniBatchSize = 128;
    case "resnet101"
        net = resnet101;
        miniBatchSize = 64;
    case "inceptionv3"
        net = inceptionv3;
        miniBatchSize = 64;
    case "inceptionresnetv2"
        net = inceptionresnetv2;
        miniBatchSize = 64;
    otherwise
        error("Undefined network selection.");
end
  • Загрузки и извлечения Цветочный набор данных, который составляет приблизительно 218 Мбайт. Для получения дополнительной информации об этом наборе данных смотрите Наборы Данных изображения.

url = "http://download.tensorflow.org/example_images/flower_photos.tgz";
downloadFolder = tempdir;
filename = fullfile(downloadFolder,"flower_dataset.tgz");
imageFolder = fullfile(downloadFolder,"flower_photos");
if ~exist(imageFolder,"dir")
    disp("Downloading Flower Dataset (218 MB)...")
    websave(filename,url);
    untar(filename,downloadFolder)
end
imds = imageDatastore(imageFolder, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");
[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9);
inputSize = net.Layers(1).InputSize;
augimdsTrain = augmentedImageDatastore(inputSize,imdsTrain);
augimdsValidation = augmentedImageDatastore(inputSize,imdsValidation);
  • Заменяет learnable слои предварительно обученной сети, чтобы использовать обучение с переносом. Функция помощника findLayersToReplace, то, которое перечислено в Приложении 2 в конце этого примера, определяет слои в сетевой архитектуре, чтобы заменить для передачи обучения. Для получения дополнительной информации о доступных предварительно обученных сетях смотрите Предварительно обученные Глубокие нейронные сети.

lgraph = layerGraph(net);
[learnableLayer,classLayer] = findLayersToReplace(lgraph);
numClasses = numel(categories(imdsTrain.Labels));
if isa(learnableLayer,"nnet.cnn.layer.FullyConnectedLayer")
    newLearnableLayer = fullyConnectedLayer(numClasses, ...
        Name="new_fc", ...
        WeightLearnRateFactor=10, ...
        BiasLearnRateFactor=10);
elseif isa(learnableLayer,"nnet.cnn.layer.Convolution2DLayer")
    newLearnableLayer = convolution2dLayer(1,numClasses, ...
        Name="new_conv", ...
        WeightLearnRateFactor=10, ...
        BiasLearnRateFactor=10);
end
lgraph = replaceLayer(lgraph,learnableLayer.Name,newLearnableLayer);
newClassLayer = classificationLayer(Name="new_classoutput");
lgraph = replaceLayer(lgraph,classLayer.Name,newClassLayer);
  • Задает trainingOptions объект для эксперимента. Пример обучает сеть в течение 10 эпох, с помощью начальной скорости обучения 0,0003 и проверяя сеть каждые 5 эпох.

validationFrequencyEpochs = 5;
numObservations = augimdsTrain.NumObservations;
numIterationsPerEpoch = floor(numObservations/miniBatchSize);
validationFrequency = validationFrequencyEpochs * numIterationsPerEpoch;
options = trainingOptions("sgdm", ...
    MaxEpochs=10, ...
    MiniBatchSize=miniBatchSize, ...
    InitialLearnRate=3e-4, ...
    Shuffle="every-epoch", ...
    ValidationData=augimdsValidation, ...
    ValidationFrequency=validationFrequency, ...
    Verbose=false);

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

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

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

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

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

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

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

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

Чтобы проверить производительность отдельного испытания, экспортируйте обучивший сеть или учебную информацию для испытания. На панели инструментов Experiment Manager выберите Export> Trained Network или Export> Training Information, соответственно. Для получения дополнительной информации смотрите сеть и информацию.

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

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

Приложение 1: функция Setup

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

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

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

Вывод

  • augimdsTrain увеличенный datastore изображений для обучающих данных.

  • lgraph график слоев, который задает архитектуру нейронной сети.

  • options trainingOptions объект.

function [augimdsTrain,lgraph,options] = TransferLearningExperiment_setup1(params)

networkName = params.NetworkName;

switch networkName
    case "squeezenet"
        net = squeezenet;
        miniBatchSize = 128;
    case "googlenet"
        net = googlenet;
        miniBatchSize = 128;
    case "resnet18"
        net = resnet18;
        miniBatchSize = 128;
    case "mobilenetv2"
        net = mobilenetv2;
        miniBatchSize = 128;
    case "resnet50"
        net = resnet50;
        miniBatchSize = 128;
    case "resnet101"
        net = resnet101;
        miniBatchSize = 64;
    case "inceptionv3"
        net = inceptionv3;
        miniBatchSize = 64;
    case "inceptionresnetv2"
        net = inceptionresnetv2;
        miniBatchSize = 64;
    otherwise
        error("Undefined network selection.");
end

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

imageFolder = fullfile(downloadFolder,"flower_photos");
if ~exist(imageFolder,"dir")
    disp("Downloading Flower Dataset (218 MB)...")
    websave(filename,url);
    untar(filename,downloadFolder)
end

imds = imageDatastore(imageFolder, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9);
inputSize = net.Layers(1).InputSize;
augimdsTrain = augmentedImageDatastore(inputSize,imdsTrain);
augimdsValidation = augmentedImageDatastore(inputSize,imdsValidation);

lgraph = layerGraph(net);
[learnableLayer,classLayer] = findLayersToReplace(lgraph);
numClasses = numel(categories(imdsTrain.Labels));

if isa(learnableLayer,"nnet.cnn.layer.FullyConnectedLayer")
    newLearnableLayer = fullyConnectedLayer(numClasses, ...
        Name="new_fc", ...
        WeightLearnRateFactor=10, ...
        BiasLearnRateFactor=10);
elseif isa(learnableLayer,"nnet.cnn.layer.Convolution2DLayer")
    newLearnableLayer = convolution2dLayer(1,numClasses, ...
        Name="new_conv", ...
        WeightLearnRateFactor=10, ...
        BiasLearnRateFactor=10);
end

lgraph = replaceLayer(lgraph,learnableLayer.Name,newLearnableLayer);

newClassLayer = classificationLayer(Name="new_classoutput");
lgraph = replaceLayer(lgraph,classLayer.Name,newClassLayer);

validationFrequencyEpochs = 5;

numObservations = augimdsTrain.NumObservations;
numIterationsPerEpoch = floor(numObservations/miniBatchSize);
validationFrequency = validationFrequencyEpochs * numIterationsPerEpoch;

options = trainingOptions("sgdm", ...
    MaxEpochs=10, ...
    MiniBatchSize=miniBatchSize, ...
    InitialLearnRate=3e-4, ...
    Shuffle="every-epoch", ...
    ValidationData=augimdsValidation, ...
    ValidationFrequency=validationFrequency, ...
    Verbose=false);

end

Приложение 2: найдите, что слои заменяют

Эта функция находит один слой классификации и предыдущее learnable (полностью соединенными или сверточными) слоем графика слоев lgraph.

function [learnableLayer,classLayer] = findLayersToReplace(lgraph)

if ~isa(lgraph,"nnet.cnn.LayerGraph")
    error("Argument must be a LayerGraph object.")
end

src = string(lgraph.Connections.Source);
dst = string(lgraph.Connections.Destination);
layerNames = string({lgraph.Layers.Name}');

isClassificationLayer = arrayfun(@(l) ...
    (isa(l,"nnet.cnn.layer.ClassificationOutputLayer")|isa(l,"nnet.layer.ClassificationLayer")), ...
    lgraph.Layers);

if sum(isClassificationLayer) ~= 1
    error("Layer graph must have a single classification layer.")
end
classLayer = lgraph.Layers(isClassificationLayer);

currentLayerIdx = find(isClassificationLayer);
while true
    
    if numel(currentLayerIdx) ~= 1
        error("Layer graph must have a single learnable layer preceding the classification layer.")
    end
    
    currentLayerType = class(lgraph.Layers(currentLayerIdx));
    isLearnableLayer = ismember(currentLayerType, ...
        ["nnet.cnn.layer.FullyConnectedLayer","nnet.cnn.layer.Convolution2DLayer"]);
    
    if isLearnableLayer
        learnableLayer =  lgraph.Layers(currentLayerIdx);
        return
    end
    
    currentDstIdx = find(layerNames(currentLayerIdx) == dst);
    currentLayerIdx = find(src(currentDstIdx) == layerNames);
end
end


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

Приложения

Функции

Похожие темы