Используйте parfor, чтобы Обучить Несколько Нейронных сетей для глубокого обучения

В этом примере показано, как использовать parfor цикл, чтобы выполнить развертку параметра на опции обучения.

Обучение глубокому обучению часто занимает часы или дни, и поиск хороших опций обучения может затруднить. С параллельными вычислениями можно убыстриться и автоматизировать поиск хороших моделей. Если у вас есть доступ к машине с несколькими графическими блоками обработки (графические процессоры), можно завершить этот пример на локальной копии набора данных с локальным parpool. Если вы хотите использовать больше ресурсов, можно увеличить обучение глубокому обучению к облаку. В этом примере показано, как использовать цикл parfor, чтобы выполнить развертку параметра на опции обучения MiniBatchSize в кластере в облаке. Можно изменить скрипт, чтобы сделать развертку параметра на любой другой опции обучения. Кроме того, этот пример показывает, как получить обратную связь от рабочих во время расчета с помощью DataQueue. Можно также отправить скрипт как пакетное задание к кластеру, таким образом, можно продолжить работать или закрыть MATLAB и выбрать результаты позже. Для получения дополнительной информации смотрите, Отправляют Пакетное задание Глубокого обучения в Кластер.

Требования

Прежде чем можно будет запустить этот пример, необходимо сконфигурировать кластер и загрузить данные на облако. В MATLAB можно создать кластеры в облаке непосредственно с Рабочего стола MATLAB. На вкладке Home, в меню Parallel, выбирают Create и Manage Clusters. В Кластерном менеджере по Профилю нажмите Create Cloud Cluster. В качестве альтернативы можно использовать MathWorks Cloud Center, чтобы создать и получить доступ, вычисляют кластеры. Для получения дополнительной информации смотрите Начало работы с Центром Облака. В данном примере гарантируйте, что ваш кластер установлен по умолчанию на вкладке MATLAB Home, параллельно> Выбирают Default Cluster. После этого загрузите свои данные на блок Amazon S3 и используйте их непосредственно из MATLAB. Этот пример использует копию набора данных CIFAR-10, который уже хранится в Amazon S3. Для инструкций смотрите Данные о Глубоком обучении Загрузки к Облаку.

Загрузите набор данных от облака

Загрузите обучение и наборы тестовых данных от облака с помощью imageDatastore. Разделите обучающий набор данных в наборы обучения и валидации и сохраните набор тестовых данных, чтобы протестировать лучшую сеть от развертки параметра. В этом примере вы используете копию набора данных CIFAR-10, сохраненного в Amazon S3. Чтобы гарантировать, что у рабочих есть доступ к datastore в облаке, убедитесь, что переменные окружения для учетных данных AWS установлены правильно. Смотрите Данные о Глубоком обучении Загрузки к Облаку.

imds = imageDatastore('s3://cifar10cloud/cifar10/train', ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

imdsTest = imageDatastore('s3://cifar10cloud/cifar10/test', ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9);

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

imageSize = [32 32 3];
pixelRange = [-4 4];
imageAugmenter = imageDataAugmenter( ...
    'RandXReflection',true, ...
    'RandXTranslation',pixelRange, ...
    'RandYTranslation',pixelRange);
augmentedImdsTrain = augmentedImageDatastore(imageSize,imdsTrain, ...
    'DataAugmentation',imageAugmenter, ...
    'OutputSizeMode','randcrop');

Архитектура сети Define

Задайте сетевую архитектуру для набора данных CIFAR-10. Чтобы упростить код, используйте сверточные блоки, которые применяют операцию свертки к входу. Слои объединения прореживают пространственные размерности.

imageSize = [32 32 3];
netDepth = 2; % netDepth controls the depth of a convolutional block
netWidth = 16; % netWidth controls the number of filters in a convolutional block

layers = [
    imageInputLayer(imageSize)
    
    convolutionalBlock(netWidth,netDepth)
    maxPooling2dLayer(2,'Stride',2)
    convolutionalBlock(2*netWidth,netDepth)
    maxPooling2dLayer(2,'Stride',2)
    convolutionalBlock(4*netWidth,netDepth)
    averagePooling2dLayer(8)
    
    fullyConnectedLayer(10)
    softmaxLayer
    classificationLayer
    ];

Обучите несколько сетей одновременно

Задайте мини-пакетные размеры, на которых можно сделать развертку параметра. Выделите переменные для получившихся сетей и точности.

miniBatchSizes = [64 128 256 512];
numMiniBatchSizes = numel(miniBatchSizes);
trainedNetworks = cell(numMiniBatchSizes,1);
accuracies = zeros(numMiniBatchSizes,1);

Выполните параллельное обучение развертки параметра несколько сетей в parfor цикл и варьирование мини-пакетного размера. Рабочие в кластере обучают сети одновременно и передают обратно обучивший нейронные сети и точность, когда обучение завершено. Если вы хотите проверять, что обучение работает, установите Verbose к true в опциях обучения. Обратите внимание на то, что рабочие вычисляют независимо, таким образом, командная строка выход не находится в том же последовательном порядке как итерации.

parfor idx = 1:numMiniBatchSizes
    
    miniBatchSize = miniBatchSizes(idx);
    initialLearnRate = 1e-1 * miniBatchSize/256; % Scale the learning rate according to the mini-batch size.
    
    % Define the training options. Set the mini-batch size.
    options = trainingOptions('sgdm', ...
        'MiniBatchSize',miniBatchSize, ... % Set the corresponding MiniBatchSize in the sweep.
        'Verbose',false, ... % Do not send command line output.
        'InitialLearnRate',initialLearnRate, ... % Set the scaled learning rate.
        'L2Regularization',1e-10, ...
        'MaxEpochs',30, ...
        'Shuffle','every-epoch', ...
        'ValidationData',imdsValidation, ...
        'LearnRateSchedule','piecewise', ...
        'LearnRateDropFactor',0.1, ...
        'LearnRateDropPeriod',25);
    
    % Train the network in a worker in the cluster.
    net = trainNetwork(augmentedImdsTrain,layers,options);
    
    % To obtain the accuracy of this network, use the trained network to
    % classify the validation images on the worker and compare the predicted labels to the
    % actual labels.
    YPredicted = classify(net,imdsValidation);
    accuracies(idx) = sum(YPredicted == imdsValidation.Labels)/numel(imdsValidation.Labels);
    
    % Send the trained network back to the client.
    trainedNetworks{idx} = net;
end
Starting parallel pool (parpool) using the 'MyClusterInTheCloud' profile ...
Connected to the parallel pool (number of workers: 4).

После parfor концы, trainedNetworks содержит получившиеся сети, обученные рабочими. Отобразите обучивший нейронные сети и их точность.

trainedNetworks
trainedNetworks = 4×1 cell array
    {1×1 SeriesNetwork}
    {1×1 SeriesNetwork}
    {1×1 SeriesNetwork}
    {1×1 SeriesNetwork}

accuracies
accuracies = 4×1

    0.8188
    0.8232
    0.8162
    0.8050

Выберите лучшую сеть в терминах точности. Проверьте его производительность против набора тестовых данных.

[~, I] = max(accuracies);
bestNetwork = trainedNetworks{I(1)};
YPredicted = classify(bestNetwork,imdsTest);
accuracy = sum(YPredicted == imdsTest.Labels)/numel(imdsTest.Labels)
accuracy = 0.8173

Отправьте данные об отклике во время обучения

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

f = figure;
f.Visible = true;
for i=1:4
    subplot(2,2,i)
    xlabel('Iteration');
    ylabel('Training accuracy');
    lines(i) = animatedline;
end

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

D = parallel.pool.DataQueue;
afterEach(D, @(opts) updatePlot(lines, opts{:}));

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

parfor idx = 1:numel(miniBatchSizes)
    
    miniBatchSize = miniBatchSizes(idx);
    initialLearnRate = 1e-1 * miniBatchSize/256; % Scale the learning rate according to the miniBatchSize.
    
    % Define the training options. Set an output function to send data back
    % to the client each iteration.
    options = trainingOptions('sgdm', ...
        'MiniBatchSize',miniBatchSize, ... % Set the corresponding MiniBatchSize in the sweep.
        'Verbose',false, ... % Do not send command line output.
        'InitialLearnRate',initialLearnRate, ... % Set the scaled learning rate.
        'OutputFcn',@(state) sendTrainingProgress(D,idx,state), ... % Set an output function to send intermediate results to the client.
        'L2Regularization',1e-10, ...
        'MaxEpochs',30, ...
        'Shuffle','every-epoch', ...
        'ValidationData',imdsValidation, ...
        'LearnRateSchedule','piecewise', ...
        'LearnRateDropFactor',0.1, ...
        'LearnRateDropPeriod',25);
    
    % Train the network in a worker in the cluster. The workers send
    % training progress information during training to the client.
    net = trainNetwork(augmentedImdsTrain,layers,options);
    
    % To obtain the accuracy of this network, use the trained network to
    % classify the validation images on the worker and compare the predicted labels to the
    % actual labels.
    YPredicted = classify(net,imdsValidation);
    accuracies(idx) = sum(YPredicted == imdsValidation.Labels)/numel(imdsValidation.Labels);
    
    % Send the trained network back to the client.
    trainedNetworks{idx} = net;
end
Analyzing and transferring files to the workers ...done.

После parfor концы, trainedNetworks содержит получившиеся сети, обученные рабочими. Отобразите обучивший нейронные сети и их точность.

trainedNetworks
trainedNetworks = 4×1 cell array
    {1×1 SeriesNetwork}
    {1×1 SeriesNetwork}
    {1×1 SeriesNetwork}
    {1×1 SeriesNetwork}

accuracies
accuracies = 4×1

    0.8214
    0.8172
    0.8132
    0.8084

Выберите лучшую сеть в терминах точности. Проверьте его производительность против набора тестовых данных.

[~, I] = max(accuracies);
bestNetwork = trainedNetworks{I(1)};
YPredicted = classify(bestNetwork,imdsTest);
accuracy = sum(YPredicted == imdsTest.Labels)/numel(imdsTest.Labels)
accuracy = 0.8187

Функции помощника

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

function layers = convolutionalBlock(numFilters,numConvLayers)
layers = [
    convolution2dLayer(3,numFilters,'Padding','same')
    batchNormalizationLayer
    reluLayer
    ];

layers = repmat(layers,numConvLayers,1);
end

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

function sendTrainingProgress(D,idx,info)
if info.State == "iteration"
    send(D,{idx,info.Iteration,info.TrainingAccuracy});
end
end

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

function updatePlot(lines,idx,iter,acc)
addpoints(lines(idx),iter,acc);
drawnow limitrate nocallbacks
end

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

| (Parallel Computing Toolbox) |

Связанные примеры

Больше о