Main Content

回帰用の畳み込みニューラル ネットワークの学習

この例では、畳み込みニューラル ネットワークに学習させ、手書きの数字の回転角度を予測する方法を示します。

回帰タスクには、離散クラス ラベルの代わりに連続的な数値の予測が含まれます。この例では、回帰用の畳み込みニューラル ネットワーク アーキテクチャを構築し、ネットワークに学習させ、学習済みネットワークを使用して手書きの数字の回転角度を予測します。

次の図は、回帰ニューラル ネットワークを通るイメージ データの流れを示しています。

データの読み込み

データ セットには、手書きの数字の合成イメージと各イメージに対応する回転角度 (度単位) が含まれています。

MAT ファイル DigitsDataTrain.mat および DigitsDataTest.mat から学習データとテスト データをそれぞれ読み込みます。変数 anglesTrain および anglesTest は回転角度 (度単位) です。学習データ セットとテスト データ セットにはそれぞれ、5000 個のイメージが含まれています。

load DigitsDataTrain
load DigitsDataTest

学習イメージをいくつか表示します。

numObservations = size(XTrain,4);
idx = randperm(numObservations,49);
I = imtile(XTrain(:,:,:,idx));
figure
imshow(I);

この例にサポート ファイルとして添付されている関数 trainingPartitions を使用して、XTrainanglesTrain を学習区画と検証区画に分割します。この関数にアクセスするには、例をライブ スクリプトとして開きます。学習データの 15% を検証用に残しておきます。

[idxTrain,idxValidation] = trainingPartitions(numObservations,[0.85 0.15]);

XValidation = XTrain(:,:,:,idxValidation);
anglesValidaiton = anglesTrain(idxValidation);

XTrain = XTrain(:,:,:,idxTrain);
anglesTrain = anglesTrain(idxTrain);

データ正規化の確認

ニューラル ネットワークに学習させるときは、ネットワークのすべての段階でデータが正規化されていることを確認すると、多くの場合役に立ちます。正規化は、勾配降下を使用したネットワークの学習の安定化と高速化に有効です。データが適切にスケーリングされていない場合、学習中に損失が NaN になり、ネットワーク パラメーターが発散する可能性があります。データを正規化する一般的な方法として、データの範囲が [0,1] になるように、または平均が 0 で標準偏差が 1 になるように、データを再スケーリングする方法があります。次のデータを正規化できます。

  • 入力データ。ネットワークに入力する前に予測子を正規化します。この例では、入力イメージは範囲 [0,1] に既に正規化されています。

  • 層出力。バッチ正規化層を使用すると、畳み込み層と全結合層のそれぞれについて出力を正規化できます。

  • 応答。バッチ正規化層を使用してネットワークの最後で層出力を正規化する場合、学習の開始時にネットワークの予測が正規化されます。応答のスケールがこれらの予測と非常に異なる場合、ネットワークの学習が収束しないことがあります。応答が適切にスケーリングされていない場合は、正規化を試して、ネットワーク学習が改善されるか確認してください。学習の前に応答を正規化する場合、学習済みネットワークの予測を変換して、元の応答の予測を求めなければなりません。

応答の分布をプロットします。応答 (度単位の回転角度) は、-45 と 45 の間でほぼ一様分布しており、正規化しなくても問題ありません。分類問題では、出力はクラス確率であり、常に正規化されています。

figure
histogram(anglesTrain)
axis tight
ylabel("Counts")
xlabel("Rotation Angle")

一般的に、データを厳密に正規化する必要はありません。ただし、この例で anglesTrain ではなく 100*anglesTrain または anglesTrain+500 を予測するためにネットワークに学習させる場合、学習を開始すると、損失が NaN になり、ネットワーク パラメーターが発散します。aY+b を予測するネットワークと Y を予測するネットワークとが、最後の全結合層の重みとバイアスの単純な再スケーリングしか違わなくても、このような結果になります。

入力または応答の分布が非常に不均一な場合や偏っている場合は、ネットワークの学習前にデータを非線形変換 (対数を取るなど) することもできます。

ニューラル ネットワーク アーキテクチャの定義

ニューラル ネットワーク アーキテクチャを定義します。

  • イメージ入力用に、イメージ入力層を指定する。

  • フィルター数を増やして 4 つの convolution-batchnorm-ReLU ブロックを指定する。

  • 各ブロック間に、プーリング領域とサイズ 2 のストライドをもつ平均プーリング層を指定する。

  • ネットワークの最後に、応答の数と一致する出力サイズをもつ全結合層を含める。

numResponses = 1;

layers = [
    imageInputLayer([28 28 1])
    convolution2dLayer(3,8,Padding="same")
    batchNormalizationLayer
    reluLayer
    averagePooling2dLayer(2,Stride=2)
    convolution2dLayer(3,16,Padding="same")
    batchNormalizationLayer
    reluLayer
    averagePooling2dLayer(2,Stride=2)
    convolution2dLayer(3,32,Padding="same")
    batchNormalizationLayer
    reluLayer
    convolution2dLayer(3,32,Padding="same")
    batchNormalizationLayer
    reluLayer
    fullyConnectedLayer(numResponses)];

学習オプションの指定

学習オプションを指定します。オプションの中から選択するには、経験的解析が必要です。実験を実行してさまざまな学習オプションの構成を調べるには、Experiment Managerアプリを使用できます。

  • 初期学習率を 0.001 に設定し、20 エポック後に学習率を下げます。

  • 検証データと検証頻度を指定して、学習中にネットワークの精度を監視します。学習データでネットワークに学習させ、学習中に一定の間隔で検証データに対してその精度を計算します。検証データは、ネットワークの重みの更新には使用されません。

  • 学習の進行状況をプロットに表示し、平方根平均二乗誤差を監視します。

  • 詳細出力を無効にします。

miniBatchSize  = 128;
validationFrequency = floor(numel(anglesTrain)/miniBatchSize);

options = trainingOptions("sgdm", ...
    MiniBatchSize=miniBatchSize, ...
    InitialLearnRate=1e-3, ...
    LearnRateSchedule="piecewise", ...
    LearnRateDropFactor=0.1, ...
    LearnRateDropPeriod=20, ...
    Shuffle="every-epoch", ...
    ValidationData={XTest,anglesTest}, ...
    ValidationFrequency=validationFrequency, ...
    Plots="training-progress", ...
    Metrics="rmse", ...
    Verbose=false);

ニューラル ネットワークの学習

関数trainnetを使用してニューラル ネットワークに学習させます。回帰の場合は、平均二乗誤差損失を使用します。既定では、関数 trainnet は利用可能な GPU がある場合にそれを使用します。GPU を使用するには、Parallel Computing Toolbox™ ライセンスとサポートされている GPU デバイスが必要です。サポートされているデバイスについては、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。そうでない場合、関数は CPU を使用します。実行環境を指定するには、ExecutionEnvironment 学習オプションを使用します。

net = trainnet(XTrain,anglesTrain,layers,"mse",options);

ネットワークのテスト

テスト データに対する精度を評価することによって、ネットワーク性能をテストします。

関数minibatchpredictを使用して予測を行います。既定では、関数 minibatchpredict は利用可能な GPU がある場合にそれを使用します。

YTest = minibatchpredict(net,XTest);

平方根平均二乗誤差 (RMSE) を計算して、回転角度の予測値と実際の値の差を測定します。

predictionError = anglesTest - YTest;
squares = predictionError.^2;
rmse = sqrt(mean(squares))
rmse = single
    4.7017

散布図で予測を可視化します。真の値に対する予測値をプロットします。

figure
scatter(YTest,anglesTest,"+")
xlabel("Predicted Value")
ylabel("True Value")

hold on
plot([-60 60], [-60 60],"r--")

新しいデータでの予測の実行

ニューラル ネットワークを使用して、最初のテスト イメージで予測を行います。単一のイメージを使用して予測を行うには、関数predictを使用します。GPU を使用するには、まずデータを gpuArray に変換します。

X = XTest(:,:,:,1);
if canUseGPU
    X = gpuArray(X);
end
Y = predict(net,X)
Y = single
    35.1394

参考

| |

関連するトピック