Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

深層学習ネットワークの並列学習

この例では、ローカル マシンで複数の深層学習実験を実行する方法を説明します。この例をテンプレートとして使用し、特定のアプリケーションのニーズに合わせてネットワーク層と学習オプションを変更することができます。このアプローチは 1 つまたは複数の GPU で使用可能です。GPU が 1 つの場合、ネットワークの学習はバックグラウンドで順次行われます。この例のアプローチでは、深層学習実験の進行中にも MATLAB® を続けて使用できます。

代わりに、実験マネージャーを使用し、複数の深層ネットワークの学習を並列で対話的に行うこともできます。詳細については、Run Experiments in Parallelを参照してください。

データセットの準備

例を実行する前に、深層学習データセットのローカル コピーへのアクセスが必要です。この例では、0 ~ 9 の数字の合成イメージのデータセットを使用します。次のコードで、使用しているデータセットを指すように場所を変更します。

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

さらに多くのリソースを使って実験する場合は、クラウド内のクラスターでこの例を実行できます。

  • Amazon S3 バケットにデータセットをアップロード。例については、AWS での深層学習データの処理を参照してください。

  • クラウド クラスターを作成します。MATLAB では、MATLAB デスクトップから直接、クラウドにクラスターを作成できます。詳細については、クラウド クラスターの作成 (Parallel Computing Toolbox)を参照してください。

  • [ホーム] タブの [環境] セクションで [並列][既定のクラスターの選択] を選択して、クラウド クラスターを既定値として選択。

データセットの読み込み

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);

ネットワークの並列学習

GPU と同じ数のワーカーを使用して並列プールを起動します。関数 gpuDeviceCount (Parallel Computing Toolbox) を使用することで、使用可能な GPU の数を確認できます。MATLAB により、各ワーカーに異なる GPU が割り当てられます。既定の設定では、parpool は既定のクラスター プロファイルを使用します。これは既定の設定を変更しない場合、local です。この例は、2 つの GPU を備えたマシンで実行されました。

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

学習中にワーカーから学習の進行状況の情報を送信するには、parallel.pool.DataQueue (Parallel Computing Toolbox) オブジェクトを使用します。データ キューを使用して学習中にフィードバックを取得する方法の詳細については、parfeval を使用した複数の深層学習ネットワークの学習の例を参照してください。

dataqueue = parallel.pool.DataQueue;

ネットワーク層と学習オプションを定義します。コードの可読性のため、いくつかのネットワーク アーキテクチャと学習オプションを返す関数でこれらを個別に定義することが可能です。この場合、networkLayersAndOptions はネットワーク層の cell 配列と、それと同じ長さの学習オプションの配列を返します。MATLAB でこの例を開き、networkLayersAndOptions をクリックして補助関数 networkLayersAndOptions を開きます。独自のネットワーク層とオプションを貼り付けます。ファイルには、出力関数を使用して情報をデータ キューに送信する方法を示すサンプルの学習オプションが含まれています。

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

学習の進行状況のプロットを用意し、各ワーカーがキューにデータを送信した後でこれらのプロットを更新するコールバック関数を設定します。preparePlotsupdatePlots はこの例のための補助関数です。

handles = preparePlots(numel(layersCell));

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

計算結果を並列ワーカー内に保持するには、future オブジェクトを使用します。各学習の結果のために future オブジェクトの配列を事前に割り当てます。

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

for ループを使用してネットワーク層とオプションをループし、parfeval (Parallel Computing Toolbox) を使用して並列ワーカー上でネットワークに学習させます。trainNetwork から出力引数を 2 つ要求するには、parfeval の 2 番目の入力引数として 2 を指定します。

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

parfeval は MATLAB をブロックしないため、計算の実行中に作業を継続できます。

future オブジェクトから結果を取得するには、関数 fetchOutputs を使用します。この例では、学習済みのネットワークとその学習情報を取得します。fetchOutputs は、結果が使用可能になるまで MATLAB をブロックします。この手順には数分かかることがあります。

[network,trainingInfo] = fetchOutputs(trainingFuture);

関数 save を使用して結果をディスクに保存します。結果を後でもう一度読み込むには、関数 load を使用します。sprintfdatetime を使用し、現在の日付と時刻を使用してファイルに名前を付けます。

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

結果のプロット

ネットワークの学習が完了した後、trainingInfo の情報を使用して学習の進行状況をプロットします。

サブプロットを使用して、各ネットワークの異なるプロットを分布させます。この例の場合、サブプロットの 1 行目を使用して、エポック数に対する学習精度を検証精度と共にプロットします。

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');

次に、サブプロットの 2 行目を使用して、エポック数に対する学習損失を検証損失と共にプロットします。

for i=1:numel(layersCell)
    subplot(2,numel(layersCell),numel(layersCell) + i);
    hold on; grid on;
    ylim([0 10]);
    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) | | |

関連する例

詳細