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

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

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

Требования

Прежде чем можно будет запустить этот пример, необходимо сконфигурировать кластер и загрузить данные на Облако. В 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');

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

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

miniBatchSize = 128;
initialLearnRate = 1e-1 * miniBatchSize/256;
validationFrequency = floor(numel(imdsTrain.Labels)/miniBatchSize);
options = trainingOptions('sgdm', ...
    'MiniBatchSize',miniBatchSize, ... % Set the mini-batch size
    '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, ...
    'ValidationFrequency', validationFrequency);

Задайте глубины для сетевой архитектуры, на которой можно сделать развертку параметра. Выполните параллельную развертку параметра, обучающую несколько сетей одновременно с помощью parfeval. Используйте цикл, чтобы выполнить итерации через различную сетевую архитектуру в развертке. Создайте функцию помощника createNetworkArchitecture в конце скрипта, который берет входной параметр, чтобы управлять глубиной сети и создает архитектуру для CIFAR-10. Используйте parfeval разгружать расчеты, выполняемые trainNetwork рабочему в кластере. parfeval возвращает будущую переменную, чтобы содержать обучившую нейронные сети и учебную информацию, когда расчеты сделаны.

netDepths = 1:4;
for idx = 1:numel(netDepths)
    networksFuture(idx) = parfeval(@trainNetwork,2, ...
        augmentedImdsTrain,createNetworkArchitecture(netDepths(idx)),options);
end
Starting parallel pool (parpool) using the 'MyCluster' profile ...
Connected to the parallel pool (number of workers: 4).

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

[trainedNetworks,trainingInfo] = fetchOutputs(networksFuture);

Получите итоговую точность валидации конкретной сети путем доступа к trainingInfo структура. Например, получите точность первой сети.

accuracy = trainingInfo(1).ValidationAccuracy(end)
accuracy = 72.7600

Чтобы получить всю итоговую точность валидации, используйте cellfun.

accuracies = cellfun(@(x) x(end),{trainingInfo.ValidationAccuracy})
accuracies = 1×4

   72.7600   77.7000   77.5000   76.1200

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

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

Вычислите матрицу беспорядка для тестовых данных.

figure('Units','normalized','Position',[0.2 0.2 0.4 0.4]);
confusionchart(imdsTest.Labels,YPredicted,'RowSummary','row-normalized','ColumnSummary','column-normalized');

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

Подготовьте и инициализируйте графики, которые показывают процесс обучения в каждом из рабочих. Используйте 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{:}));

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

netDepths = 1:4;
addAttachedFiles(gcp,mfilename);
for idx = 1:numel(netDepths)
    
    miniBatchSize = 128;
    initialLearnRate = 1e-1 * miniBatchSize/256; % Scale the learning rate according to the mini-batch size.
    validationFrequency = floor(numel(imdsTrain.Labels)/miniBatchSize);
    
    options = trainingOptions('sgdm', ...
        'OutputFcn',@(state) sendTrainingProgress(D,idx,state), ... % Set an output function to send intermediate results to the client.
        '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, ...
        'ValidationFrequency', validationFrequency);
    
    networksFuture(idx) = parfeval(@trainNetwork,2, ...
        augmentedImdsTrain,createNetworkArchitecture(netDepths(idx)),options);
end

parfeval вызывает trainNetwork на рабочем в кластере. Расчеты происходят на фоне, таким образом, можно продолжить работать в MATLAB. Если вы хотите остановить parfeval расчет, можно вызвать cancel на его соответствующей будущей переменной. Например, если вы замечаете, что сеть показывает низкие результаты, можно отменить ее будущее. Когда вы делаете так, следующая будущая переменная с очередями запускает свои расчеты.

В этом случае выберите обучивший нейронные сети и их учебную информацию путем вызова fetchOutputs на будущих переменных.

[trainedNetworks,trainingInfo] = fetchOutputs(networksFuture);

Получите итоговую точность валидации для каждой сети при помощи cellfun.

accuracies = cellfun(@(x) x(end),{trainingInfo.ValidationAccuracy})
accuracies = 1×4

   72.9200   77.4800   76.9200   77.0400

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

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

function layers = createNetworkArchitecture(netDepth)
imageSize = [32 32 3];
netWidth = round(16/sqrt(netDepth)); % 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
    ];
end

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

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

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

| | | |

Похожие темы