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 は既定のクラスター プロファイルを使用します。既定の設定を変更しない場合、parpool はプロセスベースのプールを開きます。この例は、2 つの GPU を備えたマシンで実行されました。

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

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

dataqueue = parallel.pool.DataQueue;

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

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

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

numExperiments = numel(layersCell);
handles = preparePlots(numExperiments);

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

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

trainingFuture(1:numExperiments) = parallel.FevalFuture;

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

for i=1:numExperiments
    trainingFuture(i) = parfeval(@trainnet,2,augmentedImdsTrain,layersCell{i},"crossentropy",options(i));
end

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

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

[network,trainingInfo] = fetchOutputs(trainingFuture);

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

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

結果のプロット

ネットワークの学習が完了した後、trainingInfo の情報を使用して学習の進行状況をプロットします。この例では、プロットの行を作成して、反復に対してプロットされた学習精度を検証精度と共に表示します。

t = tiledlayout(2,numExperiments);
title(t,"Training Progress Plots")

for i=1:numExperiments
    nexttile
    hold on; grid on;
    ylim([0 100]);
    plot(trainingInfo(i).TrainingHistory.Iteration,trainingInfo(i).TrainingHistory.Accuracy);
    plot(trainingInfo(i).ValidationHistory.Iteration,trainingInfo(i).ValidationHistory.Accuracy,".k",MarkerSize=10);
    xlabel("Iteration")
    ylabel("Accuracy")
end

次に、プロットの 2 行目を作成して、反復に対してプロットされた学習損失を検証損失と共に表示します。

for i=1:numExperiments
    nexttile
    hold on; grid on;
    ylim([0 10]);
    plot(trainingInfo(i).TrainingHistory.Iteration,trainingInfo(i).TrainingHistory.Loss);
    plot(trainingInfo(i).ValidationHistory.Iteration,trainingInfo(i).ValidationHistory.Loss,".k",MarkerSize=10);
    xlabel("Iteration")
    ylabel("Loss")
end

ネットワークを選択したら、それを使用してテスト データ imdsTest 内のイメージを分類できます。複数の観測値を使用して予測を行うには、関数minibatchpredictを使用します。予測スコアをラベルに変換するには、関数scores2labelを使用します。

参考

| | | (Parallel Computing Toolbox) | | | |

関連する例

詳細