Этот пример показывает, как запустить несколько экспериментов глубокого обучения на вашей локальной машине. Используя этот пример как шаблон, можно изменить сетевые слои и опции обучения, чтобы удовлетворить определенным потребностям приложения. Можно использовать этот подход с синглом или несколькими графическими процессорами. Если у вас есть один графический процессор, сети обучаются один за другим в фоновом режиме. Подход в этом примере позволяет вам продолжить использовать MATLAB®, в то время как эксперименты глубокого обучения происходят.
Прежде чем можно будет запустить пример, у вас должен быть доступ к локальной копии набора данных глубокого обучения. Этот пример использует набор данных с синтетическими изображениями цифр от 0 до 9. В следующем коде измените местоположение, чтобы указать на ваш набор данных.
datasetLocation = fullfile(matlabroot,'toolbox','nnet', ... 'nndemos','nndatasets','DigitDataset');
Если вы хотите запустить эксперименты с большим количеством ресурсов, можно запустить этот пример в кластере в облаке.
Загрузите набор данных на блок Amazon S3. Для примера смотрите Данные о Глубоком обучении Загрузки к Облаку.
Создайте кластер облака. В 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
. Используйте случайные переводы и горизонтальные отражения. Увеличение данных помогает препятствовать тому, чтобы сеть сверхсоответствовала и запомнила точные детали учебных изображений.
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 = 2; parpool(numGPUs);
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 2).
Чтобы отправить учебную информацию о прогрессе от рабочих во время обучения, используйте объект 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
.
save(['experiment-' datestr(now,'yyyymmddTHHMMSS')],'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
.
augmentedImageDatastore
| fetchOutputs (FevalFuture)
| imageDatastore
| parfeval
| trainNetwork
| trainingOptions