Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

forward

学習用の深層学習ネットワーク出力の計算

説明

深層学習層によっては学習時と推論時 (予測時) の動作が異なる場合があります。たとえば、学習時には過適合を防ぐためにドロップアウト層によって入力要素がランダムに 0 に設定されますが、推論時にはドロップアウト層によって入力が変更されることはありません。

学習用のネットワーク出力を計算するには、関数 forward を使用します。推論用のネットワーク出力を計算するには、関数 predict を使用します。

Y = forward(net,X) は、入力データ X が与えられたときに、学習時のネットワーク出力 Y を返します。

Y = forward(net,X1,...,XM) は、M 個の入力 X1, ...,XM、および M 個の入力と 1 つの出力をもつネットワーク net が与えられたときに、学習時のネットワーク出力 Y を返します。

[Y1,...,YN] = forward(___) は、前述のいずれかの構文を使用して、N 個の出力をもつネットワークについて、N 個の学習時の出力 Y1, …, YN を返します。

[Y1,...,YK] = forward(___,'Outputs',layerNames) は、前述のいずれかの構文を使用して、指定された層について、学習時の出力 Y1, …, YK を返します。

[___] = forward(___,'Acceleration',acceleration) は、前述の構文の入力引数に加え、学習時に使用するパフォーマンスの最適化も指定します。

[___,state] = forward(___) は、更新されたネットワークの状態も返します。

[___,state,pruningActivations] = forward(___) は、枝刈り層の活性化の cell 配列も返します。この構文は、netTaylorPrunableNetwork オブジェクトである場合にのみ適用できます。

深層ニューラル ネットワークの枝刈りを行うには、Deep Learning Toolbox™ Model Quantization Library サポート パッケージが必要です。このサポート パッケージは無料のアドオンで、アドオン エクスプローラーを使用してダウンロードできます。または、Deep Learning Toolbox Model Quantization Library を参照してください。

すべて折りたたむ

この例では、カスタム学習率スケジュールで手書きの数字を分類するネットワークに学習させる方法を示します。

ほとんどのタイプのニューラル ネットワークは、関数trainNetworkと関数trainingOptionsを使用して学習させることができます。必要なオプション (たとえば、カスタム学習率スケジュール) が関数 trainingOptions に用意されていない場合、自動微分のために dlarray オブジェクトと dlnetwork オブジェクトを使用して独自のカスタム学習ループを定義できます。関数 trainNetwork を使用して事前学習済みの深層学習ネットワークに再学習させる方法を示す例については、事前学習済みのネットワークを使用した転移学習を参照してください。

深層ニューラル ネットワークの学習は最適化タスクです。ニューラル ネットワークを関数 f(X;θ) と見なすことにより (ここで、X はネットワーク入力、θ は学習可能なパラメーターのセット)、θ を最適化して学習データに基づく損失値を最小化できます。たとえば、与えらえた入力 X と対応するターゲット T に対して、予測 Y=f(X;θ)T の間の誤差が最小になるように、学習可能なパラメーター θ を最適化します。

使用される損失関数は、タスクのタイプによって異なります。次に例を示します。

  • 分類タスクの場合、予測とターゲットの間のクロス エントロピー誤差を最小化できます。

  • 回帰タスクの場合、予測とターゲットの間の平均二乗誤差を最小化できます。

勾配降下法を使用して目的を最適化できます。勾配降下法では、学習可能なパラメーターについての損失の勾配を使用して最小化に向けてステップを実行することで、学習可能なパラメーター θ を反復的に更新することにより、損失 L を最小化します。勾配降下法アルゴリズムは通常、θt+1=θt-ρL の形式の更新ステップのバリアントを使用して、学習可能なパラメーターを更新します。ここで、t は反復回数、ρ は学習率、L は勾配 (学習可能なパラメーターについての損失の微分) を表します。

この例では、"時間ベースの減衰" 学習率スケジュールで手書きの数字を分類するようにネットワークに学習させます。各反復で、ソルバーは ρt=ρ01+k t によって与えられる学習率を使用します。ここで、t は反復回数、ρ0 は初期学習率、k は減衰です。

学習データの読み込み

関数 imageDatastore を使用して数字データをイメージ データストアとして読み込み、イメージ データが格納されているフォルダーを指定します。

dataFolder = fullfile(toolboxdir("nnet"),"nndemos","nndatasets","DigitDataset");

imds = imageDatastore(dataFolder, ...
    IncludeSubfolders=true, ....
    LabelSource="foldernames");

データを学習セットと検証セットに分割します。関数 splitEachLabel を使用して、データの 10% を検証用に残しておきます。

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9,"randomize");

この例で使用されるネットワークには、サイズが 28 x 28 x 1 の入力イメージが必要です。学習イメージのサイズを自動的に変更するには、拡張イメージ データストアを使用します。学習イメージに対して実行する追加の拡張演算として、イメージを水平軸方向および垂直軸方向に最大 5 ピクセルだけランダムに平行移動させる演算を指定します。データ拡張は、ネットワークで過適合が発生したり、学習イメージの正確な詳細が記憶されたりすることを防止するのに役立ちます。

inputSize = [28 28 1];
pixelRange = [-5 5];

imageAugmenter = imageDataAugmenter( ...
    RandXTranslation=pixelRange, ...
    RandYTranslation=pixelRange);

augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain,DataAugmentation=imageAugmenter);

他のデータ拡張を実行せずに検証イメージのサイズを自動的に変更するには、追加の前処理演算を指定せずに拡張イメージ データストアを使用します。

augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

学習データ内のクラスの数を決定します。

classes = categories(imdsTrain.Labels);
numClasses = numel(classes);

ネットワークの定義

イメージ分類のネットワークを定義します。

  • イメージ入力用に、学習データと一致する入力サイズのイメージ入力層を指定します。

  • イメージ入力は正規化せず、入力層の Normalization オプションを "none" に設定します。

  • 畳み込み層、バッチ正規化層、ReLU 層のブロックを 3 つ指定します。

  • Padding オプションを "same" に設定して、出力が同じサイズになるように畳み込み層に入力をパディングします。

  • 最初の畳み込み層には、サイズ 5 のフィルターを 20 個指定します。残りの畳み込み層には、サイズ 3 のフィルターを 20 個指定します。

  • 分類用に、クラスの数と一致するサイズの全結合層を指定します。

  • 出力を確率にマッピングするために、ソフトマックス層を含めます。

カスタム学習ループを使用してネットワークに学習させる場合、出力層は含めません。

layers = [
    imageInputLayer(inputSize,Normalization="none")
    convolution2dLayer(5,20,Padding="same")
    batchNormalizationLayer
    reluLayer
    convolution2dLayer(3,20,Padding="same")
    batchNormalizationLayer
    reluLayer
    convolution2dLayer(3,20,Padding="same")
    batchNormalizationLayer
    reluLayer
    fullyConnectedLayer(numClasses)
    softmaxLayer];

層配列から dlnetwork オブジェクトを作成します。

net = dlnetwork(layers)
net = 
  dlnetwork with properties:

         Layers: [12×1 nnet.cnn.layer.Layer]
    Connections: [11×2 table]
     Learnables: [14×3 table]
          State: [6×3 table]
     InputNames: {'imageinput'}
    OutputNames: {'softmax'}
    Initialized: 1

モデル損失関数の定義

深層ニューラル ネットワークの学習は最適化タスクです。ニューラル ネットワークを関数 f(X;θ) と見なすことにより (ここで、X はネットワーク入力、θ は学習可能なパラメーターのセット)、θ を最適化して学習データに基づく損失値を最小化できます。たとえば、与えらえた入力 X と対応するターゲット T に対して、予測 Y=f(X;θ)T の間の誤差が最小になるように、学習可能なパラメーター θ を最適化します。

例のモデル損失関数の節にリストされている関数 modelLoss を作成します。この関数は、dlnetwork オブジェクト、入力データのミニバッチと対応するターゲットを入力として受け取り、学習可能なパラメーターについての損失と損失の勾配、およびネットワークの状態を返します。

学習オプションの指定

ミニバッチ サイズを 128 として 10 エポック学習させます。

numEpochs = 10;
miniBatchSize = 128;

SGDM 最適化のオプションを指定します。減衰 0.01 の初期学習率 0.01、およびモーメンタム 0.9 を指定します。

initialLearnRate = 0.01;
decay = 0.01;
momentum = 0.9;

モデルの学習

学習中にイメージのミニバッチを処理および管理するminibatchqueueオブジェクトを作成します。各ミニバッチで次を行います。

  • カスタム ミニバッチ前処理関数 preprocessMiniBatch (この例の最後に定義) を使用して、ラベルを one-hot 符号化変数に変換します。

  • イメージ データを次元ラベル "SSCB" (spatial、spatial、channel、batch) で書式設定します。既定では、minibatchqueue オブジェクトは、基となる型が singledlarray オブジェクトにデータを変換します。クラス ラベルは書式設定しません。

  • GPU が利用できる場合、GPU で学習を行います。既定では、minibatchqueue オブジェクトは、GPU が利用可能な場合、各出力を gpuArray に変換します。GPU を使用するには、Parallel Computing Toolbox™ とサポートされている GPU デバイスが必要です。サポートされているデバイスについては、リリース別の GPU サポート (Parallel Computing Toolbox)を参照してください。

mbq = minibatchqueue(augimdsTrain,...
    MiniBatchSize=miniBatchSize,...
    MiniBatchFcn=@preprocessMiniBatch,...
    MiniBatchFormat=["SSCB" ""]);

学習の進行状況プロットを初期化します。

figure
C = colororder;
lineLossTrain = animatedline(Color=C(2,:));
ylim([0 inf])
xlabel("Iteration")
ylabel("Loss")
grid on

SGDM ソルバーの速度パラメーターを初期化します。

velocity = [];

カスタム学習ループを使用してネットワークに学習させます。各エポックについて、データをシャッフルしてデータのミニバッチをループで回します。各ミニバッチで次を行います。

  • 関数 dlfeval と関数 modelLoss を使用してモデルの損失、勾配、および状態を評価し、ネットワークの状態を更新。

  • 時間ベースの減衰学習率スケジュールの学習率を決定。

  • 関数 sgdmupdate を使用してネットワーク パラメーターを更新。

  • 学習の進行状況を表示。

iteration = 0;
start = tic;

% Loop over epochs.
for epoch = 1:numEpochs

    % Shuffle data.
    shuffle(mbq);
    
    % Loop over mini-batches.
    while hasdata(mbq)
        iteration = iteration + 1;
        
        % Read mini-batch of data.
        [X,T] = next(mbq);
        
        % Evaluate the model gradients, state, and loss using dlfeval and the
        % modelLoss function and update the network state.
        [loss,gradients,state] = dlfeval(@modelLoss,net,X,T);
        net.State = state;
        
        % Determine learning rate for time-based decay learning rate schedule.
        learnRate = initialLearnRate/(1 + decay*iteration);
        
        % Update the network parameters using the SGDM optimizer.
        [net,velocity] = sgdmupdate(net,gradients,velocity,learnRate,momentum);
        
        % Display the training progress.
        D = duration(0,0,toc(start),Format="hh:mm:ss");
        loss = double(loss);
        addpoints(lineLossTrain,iteration,loss)
        title("Epoch: " + epoch + ", Elapsed: " + string(D))
        drawnow
    end
end

モデルのテスト

真のラベルをもつ検証セットで予測を比較し、モデルの分類精度をテストします。

学習後に新しいデータについて予測を行う際、ラベルは必要ありません。テスト データの予測子のみを含む minibatchqueue オブジェクトを作成します。

  • テスト用のラベルを無視するには、ミニバッチ キューの出力数を 1 に設定します。

  • 学習に使用されるサイズと同じミニバッチ サイズを指定します。

  • 例の最後にリストされている関数 preprocessMiniBatchPredictors を使用して予測子を前処理します。

  • データストアの単一の出力では、ミニバッチの形式 "SSCB" (spatial、spatial、channel、batch) を指定します。

numOutputs = 1;

mbqTest = minibatchqueue(augimdsValidation,numOutputs, ...
    MiniBatchSize=miniBatchSize, ...
    MiniBatchFcn=@preprocessMiniBatchPredictors, ...
    MiniBatchFormat="SSCB");

例の最後にリストされている関数 modelPredictions を使用して、ミニバッチをループ処理し、イメージを分類します。

YTest = modelPredictions(net,mbqTest,classes);

分類精度を評価します。

TTest = imdsValidation.Labels;
accuracy = mean(TTest == YTest)
accuracy = 0.7210

混同チャートで予測を可視化します。

figure
confusionchart(TTest,YTest)

対角線上の大きな値は、対応するクラスに対する正確な予測を示しています。対角線外の大きな値は、対応するクラス間での強い混同を示しています。

サポート関数

モデル損失関数

関数 modelLoss は、dlnetwork オブジェクト net、入力データのミニバッチ X とそれに対応するターゲット T を受け取り、net 内の学習可能パラメーターについての損失と損失の勾配、およびネットワークの状態を返します。勾配を自動的に計算するには、関数 dlgradient を使用します。

function [loss,gradients,state] = modelLoss(net,X,T)

% Forward data through network.
[Y,state] = forward(net,X);

% Calculate cross-entropy loss.
loss = crossentropy(Y,T);

% Calculate gradients of loss with respect to learnable parameters.
gradients = dlgradient(loss,net.Learnables);

end

モデル予測関数

関数 modelPredictions は、dlnetwork オブジェクト net、入力データの minibatchqueue オブジェクト mbq、およびネットワーク クラスを受け取り、minibatchqueue オブジェクトに含まれるすべてのデータを反復処理することによってモデル予測を計算します。この関数は、関数 onehotdecode を使用して、スコアが最も高い予測されたクラスを見つけます。

function Y = modelPredictions(net,mbq,classes)

Y = [];

% Loop over mini-batches.
while hasdata(mbq)
    X = next(mbq);

    % Make prediction.
    scores = predict(net,X);

    % Decode labels and append to output.
    labels = onehotdecode(scores,classes,1)';
    Y = [Y; labels];
end

end

ミニ バッチ前処理関数

関数 preprocessMiniBatch は、次の手順を使用して予測子とラベルのミニバッチを前処理します。

  1. 関数 preprocessMiniBatchPredictors を使用してイメージを前処理します。

  2. 入力 cell 配列からラベル データを抽出し、2 番目の次元に沿って categorical 配列に連結します。

  3. カテゴリカル ラベルを数値配列に one-hot 符号化します。最初の次元への符号化は、ネットワーク出力の形状と一致する符号化された配列を生成します。

function [X,T] = preprocessMiniBatch(dataX,dataT)

% Preprocess predictors.
X = preprocessMiniBatchPredictors(dataX);

% Extract label data from cell and concatenate.
T = cat(2,dataT{1:end});

% One-hot encode labels.
T = onehotencode(T,1);

end

ミニバッチ予測子前処理関数

関数 preprocessMiniBatchPredictors は、入力 cell 配列からイメージ データを抽出することで予測子のミニバッチを前処理し、数値配列に連結します。グレースケール入力では、4 番目の次元で連結することにより、3 番目の次元が各イメージに追加されます。この次元は、シングルトン チャネル次元として使用されることになります。

function X = preprocessMiniBatchPredictors(dataX)

% Concatenate.
X = cat(4,dataX{1:end});

end

入力引数

すべて折りたたむ

この引数は、次のいずれかを表すことができます。

  • カスタム学習ループのネットワーク。dlnetwork オブジェクトとして指定します。

  • カスタム枝刈りループのネットワーク。TaylorPrunableNetwork オブジェクトとして指定します。

深層ニューラル ネットワークの枝刈りを行うには、Deep Learning Toolbox Model Quantization Library サポート パッケージが必要です。このサポート パッケージは無料のアドオンで、アドオン エクスプローラーを使用してダウンロードできます。または、Deep Learning Toolbox Model Quantization Library を参照してください。

入力データ。書式化された dlarray として指定します。dlarray の形式に関する詳細については、dlarray の入力引数 fmt を参照してください。

出力の抽出元の層。層の名前を含む string 配列、または層の名前を含む文字ベクトルの cell 配列として指定します。

  • layerNames(i) が 1 つの出力をもつ層に対応する場合、layerNames(i) は層の名前です。

  • layerNames(i) が複数の出力をもつ層に対応する場合、layerNames(i) はまず層の名前、その後に文字 "/"、さらに層出力の名前が続きます ('layerName/outputName')。

パフォーマンスの最適化。次のいずれかとして指定します。

  • 'auto' — 入力ネットワークとハードウェア リソースに適した最適化の回数を自動的に適用します。

  • 'none' — すべての高速化を無効にします。

既定のオプションは 'auto' です。

'auto' 高速化オプションを使用すると、パフォーマンス上のメリットが得られますが、初期実行時間が長くなります。互換性のあるパラメーターを使用した後続の呼び出しは、より高速になります。サイズと形状が同じである異なる入力データを使用して関数を複数回呼び出す場合は、パフォーマンスの最適化を使用してください。

出力引数

すべて折りたたむ

出力データ。書式化された dlarray として返されます。dlarray の形式に関する詳細については、dlarray の入力引数 fmt を参照してください。

更新されたネットワークの状態。table として返されます。

ネットワークの状態は、次の 3 つの列をもつ table です。

  • Layer – 層の名前。string スカラーとして指定します。

  • Parameter – 状態パラメーターの名前。string スカラーとして指定します。

  • Value – 状態パラメーターの値。dlarray オブジェクトとして指定します。

層の状態には、層処理中に計算された情報が格納されます。この情報は、層の後続のフォワード パスで使用するために保持されます。たとえば、LSTM 層のセル状態と隠れ状態、またはバッチ正規化層の実行中の統計が格納されます。

LSTM 層などの再帰層の場合、HasStateInputs プロパティを 1 (true) に設定すると、その層の状態に関するエントリはステート table に格納されません。

State プロパティを使用して dlnetwork の状態を更新します。

枝刈り層の活性化の cell 配列 (入力ネットワークが TaylorPrunableNetwork オブジェクトの場合)。

拡張機能

バージョン履歴

R2019b で導入

すべて展開する