Обучите Нейронные сети для глубокого обучения параллельно

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

В качестве альтернативы можно использовать Experiment Manager (Deep Learning Toolbox) для интерактивного обучения нескольких глубоких сетей параллельно. Для получения дополнительной информации смотрите Использовать Experiment Manager для обучения сетей в Parallel (Deep Learning Toolbox).

Подготовка набора данных

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

datasetLocation = fullfile(matlabroot,'toolbox','nnet', ...
    'nndemos','nndatasets','DigitDataset');

Если вы хотите запустить эксперименты с большим количеством ресурсов, можно запустить этот пример в кластере в облаке.

  • Загрузите набор данных в блок S3 Amazon. Для получения примера смотрите Загрузку данных глубокого обучения в облако.

  • Создайте облако. В MATLAB можно создавать кластеры в облаке непосредственно с рабочего стола MATLAB. Для получения дополнительной информации см. раздел «Создание облака».

  • Выберите кластер облака по умолчанию, на вкладке «Вкладке Home», в разделе Environment, выберите Parallel > Select a Default Cluster.

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

Загрузите набор данных с помощью imageDatastore объект. Разделите набор данных на наборы для обучения, валидации и тестирования.

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

[imdsTrain,imdsValidation,imdsTest] = splitEachLabel(imds,0.8,0.1);

Чтобы обучить сеть с дополненными данными об изображениях, создайте augmentedImageDatastore (Deep Learning Toolbox). Используйте случайные переводы и горизонтальные отражения. Увеличение количества данных помогает предотвратить сверхподбор кривой сети и запоминание точных деталей обучающих изображений.

imageSize = [28 28 1];
pixelRange = [-4 4];
imageAugmenter = imageDataAugmenter( ...
    'RandXReflection',true, ...
    'RandXTranslation',pixelRange, ...
    'RandYTranslation',pixelRange);
augmentedImdsTrain = augmentedImageDatastore(imageSize,imdsTrain, ...
    'DataAugmentation',imageAugmenter);

Обучите сети параллельно

Запустите параллельный пул с таким количеством рабочих процессов, как графические процессоры. Количество доступных графических процессоров можно проверить с помощью gpuDeviceCount функция. MATLAB присваивает отдельный графический процессор каждому работнику. По умолчанию parpool использует профиль кластера по умолчанию. Если вы не изменили значение по умолчанию, это local. Этот пример выполнялся с использованием машины с 2 графическими процессорами.

numGPUs = gpuDeviceCount("available");
parpool(numGPUs);
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 2).

Чтобы отправить информацию о процессе обучения от работников во время обучения, используйте parallel.pool.DataQueue объект. Дополнительные сведения о том, как использовать очереди данных для получения обратной связи во время обучения, см. в примере Использование parfeval для обучения нескольких нейронных сетей для глубокого обучения.

dataqueue = parallel.pool.DataQueue;

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

[layersCell,options] = networkLayersAndOptions(augmentedImdsTrain,imdsValidation,dataqueue);

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

handles = preparePlots(numel(layersCell));

afterEach(dataqueue,@(data) updatePlots(handles,data));

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

trainingFuture(1:numel(layersCell)) = parallel.FevalFuture;

Цикл через слои сети и опции при помощи for цикл и используйте parfeval для обучения сетей на параллельном рабочем. Чтобы запросить два выходных аргументов у trainNetwork, задайте 2 как второй входной параметр для parfeval.

for i=1:numel(layersCell)
    trainingFuture(i) = parfeval(@trainNetwork,2,augmentedImdsTrain,layersCell{i},options(i));
end

parfeval не блокирует MATLAB, поэтому можно продолжать работу во время выполнения расчетов.

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

[network,trainingInfo] = fetchOutputs(trainingFuture);

Сохраните результаты на диск с помощью save функция. Чтобы загрузить результаты снова позже, используйте load функция. Использование sprintf и datetime для присвоения имени файлу с использованием текущей даты и времени.

filename = sprintf('experiment-%s',datetime('now','Format','yyyyMMdd''T''HHmmss'));
save(filename,'network','trainingInfo');

Графическое изображение результатов

После того, как сети завершат обучение, постройте график процесса обучения с помощью информации в trainingInfo.

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

figure('Units','normalized','Position',[0.1 0.1 0.6 0.6]);
title('Training Progress Plots');

for i=1:numel(layersCell)
    subplot(2,numel(layersCell),i);
    hold on; grid on;
    ylim([0 100]);
    iterationsPerEpoch = floor(augmentedImdsTrain.NumObservations/options(i).MiniBatchSize);
    epoch = (1:numel(trainingInfo(i).TrainingAccuracy))/iterationsPerEpoch;
    plot(epoch,trainingInfo(i).TrainingAccuracy);
    plot(epoch,trainingInfo(i).ValidationAccuracy,'.k','MarkerSize',10);
end
subplot(2,numel(layersCell),1), ylabel('Accuracy');

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

for i=1:numel(layersCell)
    subplot(2,numel(layersCell),numel(layersCell) + i);
    hold on; grid on;
    ylim([0 max([trainingInfo.TrainingLoss])]);
    iterationsPerEpoch = floor(augmentedImdsTrain.NumObservations/options(i).MiniBatchSize);
    epoch = (1:numel(trainingInfo(i).TrainingAccuracy))/iterationsPerEpoch;
    plot(epoch,trainingInfo(i).TrainingLoss);
    plot(epoch,trainingInfo(i).ValidationLoss,'.k','MarkerSize',10);
    xlabel('Epoch');
end
subplot(2,numel(layersCell),numel(layersCell)+1), ylabel('Loss');

После выбора сети можно использовать classify (Deep Learning Toolbox) и получить его точность на тестовых данных imdsTest.

См. также

| | | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox)

Похожие примеры

Подробнее о