最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

複数の深層学習実験の並列実行

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

代替方法として、実験マネージャー アプリを使用して複数の深層学習実験をインタラクティブに逐次実行できます。詳細は、Experiment Manager を参照してください。

データセットの準備

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

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

多くのリソースで実験を行う場合は、クラウド内のクラスターでこの実験を実行できます。

  • Amazon S3 バケットにデータ セットをアップロードします。例については、クラウドへの深層学習データのアップロード (Parallel Computing Toolbox) を参照してください。

  • クラウド クラスターを作成します。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 = 2;
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 はネットワーク層の 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 を使用します。

save(['experiment-' datestr(now,'yyyymmddTHHMMSS')],'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 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)

関連する例

詳細