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

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

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

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

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

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

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

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

  • Создайте облако. В MATLAB можно создавать кластеры в облаке непосредственно с рабочего стола MATLAB. Для получения дополнительной информации смотрите Создание Кластера Облака (Parallel Computing Toolbox).

  • Выберите кластер облака по умолчанию, на вкладке «Вкладке 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. Используйте случайные переводы и горизонтальные отражения. Увеличение количества данных помогает предотвратить сверхподбор кривой сети и запоминание точных деталей обучающих изображений.

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

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

Запустите параллельный пул с таким количеством рабочих процессов, как графические процессоры. Количество доступных графических процессоров можно проверить с помощью gpuDeviceCount (Parallel Computing Toolbox) функция. 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 (Parallel Computing Toolbox) объект. Чтобы узнать больше о том, как использовать очереди данных для получения обратной связи во время обучения, смотрите пример Использовать parfeval для обучения нескольких нейронных сетей для глубокого обучения (Parallel Computing Toolbox).

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 (Parallel Computing Toolbox) для обучения сетей параллельным рабочим. Чтобы запросить два выходных аргументов у 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 и получить его точность по тестовым данным imdsTest.

См. также

| | | | | (Parallel Computing Toolbox) | (Parallel Computing Toolbox)

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

Подробнее о