自動マルチ GPU のサポートを使用したネットワークの学習
この例では、自動並列サポートを使用した深層学習のために、ローカル マシンで複数の GPU を使用する方法を説明します。
多くの場合、深層学習ネットワークの学習には数時間または数日かかります。並列計算を使用すると、複数の GPU を使用して学習を高速化できます。並列学習のオプションの詳細については、Scale Up Deep Learning in Parallel, on GPUs, and in the Cloudを参照してください。
要件
この例を実行する前に、CIFAR-10 データセットをローカル マシンにダウンロードしなければなりません。CIFAR-10 データ セットをダウンロードするには、この例にサポート ファイルとして添付されている関数 downloadCIFARToFolders
を使用します。このファイルにアクセスするには、例をライブ スクリプトとして開きます。以下のコードは、データセットを現在のディレクトリにダウンロードします。CIFAR-10 のローカル コピーを既にもっている場合は、この節をスキップできます。
directory = pwd; [locationCifar10Train,locationCifar10Test] = downloadCIFARToFolders(directory);
Downloading CIFAR-10 data set...done. Copying CIFAR-10 to folders...done.
データセットの読み込み
imageDatastore
オブジェクトを使用して、学習データセットとテスト データセットを読み込みます。以下のコードで、データストアの場所がローカル マシンの CIFAR-10 を指していることを確認します。
imdsTrain = imageDatastore(locationCifar10Train, ... IncludeSubfolders=true, ... LabelSource="foldernames"); imdsTest = imageDatastore(locationCifar10Test, ... IncludeSubfolders=true, ... LabelSource="foldernames");
拡張イメージ データを使用してネットワークに学習させるために、augmentedImageDatastore
オブジェクトを作成します。ランダムな平行移動と水平方向の反転を使用します。データ拡張は、ネットワークで過適合が発生したり、学習イメージの正確な詳細が記憶されたりすることを防止するのに役立ちます。
imageSize = [32 32 3]; pixelRange = [-4 4]; imageAugmenter = imageDataAugmenter( ... RandXReflection=true, ... RandXTranslation=pixelRange, ... RandYTranslation=pixelRange); augmentedImdsTrain = augmentedImageDatastore(imageSize,imdsTrain, ... DataAugmentation=imageAugmenter);
ネットワーク アーキテクチャと学習オプションの定義
CIFAR-10 データセット用のネットワーク アーキテクチャを定義します。コードを簡略化するために、入力を畳み込む畳み込みブロックを使用します。プーリング層は空間次元をダウンサンプリングします。
blockDepth = 4; % blockDepth controls the depth of a convolutional block. netWidth = 32; % netWidth controls the number of filters in a convolutional block. layers = [ imageInputLayer(imageSize) convolutionalBlock(netWidth,blockDepth) maxPooling2dLayer(2,Stride=2) convolutionalBlock(2*netWidth,blockDepth) maxPooling2dLayer(2,Stride=2) convolutionalBlock(4*netWidth,blockDepth) averagePooling2dLayer(8) fullyConnectedLayer(10) softmaxLayer classificationLayer ];
学習オプションを定義します。実行環境を multi-gpu
に設定し、複数の GPU を使用してネットワークの並列学習を行います。複数の GPU を使用する場合、利用可能な計算リソースを増やします。GPU の数でミニバッチ サイズをスケールアップし、各 GPU での作業負荷を一定に維持します。この例では、GPU の数は 4 です。ミニバッチ サイズに応じて学習率をスケーリングします。学習率のスケジュールを使用して、学習の進行に応じて学習率を下げます。学習の進行状況プロットをオンにして、学習中に、可視化されたフィードバックを取得します。
numGPUs = gpuDeviceCount("available")
numGPUs = 4
miniBatchSize = 256*numGPUs; initialLearnRate = 1e-1*miniBatchSize/256; options = trainingOptions("sgdm", ... ExecutionEnvironment="multi-gpu", ... % Turn on automatic multi-gpu support. InitialLearnRate=initialLearnRate, ... % Set the initial learning rate. MiniBatchSize=miniBatchSize, ... % Set the MiniBatchSize. Verbose=false, ... % Do not send command line output. Plots="training-progress", ... % Turn on the training progress plot. L2Regularization=1e-10, ... MaxEpochs=60, ... Shuffle="every-epoch", ... ValidationData=imdsTest, ... ValidationFrequency=floor(numel(imdsTrain.Files)/miniBatchSize), ... LearnRateSchedule="piecewise", ... LearnRateDropFactor=0.1, ... LearnRateDropPeriod=50);
ネットワークの学習と分類での使用
ネットワークに学習をさせます。学習中に進行状況のプロットが表示されます。
net = trainNetwork(augmentedImdsTrain,layers,options)
Starting parallel pool (parpool) using the 'Processes' profile ... Connected to the parallel pool (number of workers: 4).
net = SeriesNetwork with properties: Layers: [43×1 nnet.cnn.layer.Layer] InputNames: {'imageinput'} OutputNames: {'classoutput'}
学習済みネットワークを使用してローカル マシン上でテスト イメージを分類し、ネットワークの精度を判断します。次に、予測ラベルを実際のラベルと比較します。
YPredicted = classify(net,imdsTest); accuracy = sum(YPredicted == imdsTest.Labels)/numel(imdsTest.Labels)
accuracy = 0.8972
自動マルチ GPU のサポートにより、複数の GPU を利用してネットワークの学習を高速化できます。以下のプロットは、4 つの NVIDIA© TITAN Xp GPU が搭載された Linux マシンにおいて、GPU の数が増えるにつれて全体的な学習時間が短縮される様子を示しています。
補助関数の定義
ネットワーク アーキテクチャで畳み込みブロックを作成する関数を定義します。
function layers = convolutionalBlock(numFilters,numConvLayers) layers = [ convolution2dLayer(3,numFilters,Padding="same") batchNormalizationLayer reluLayer]; layers = repmat(layers,numConvLayers,1); end
参考
trainNetwork
| trainingOptions
| imageDatastore