モデル関数を使用した予測の実行
この例では、データをミニバッチに分割することにより、モデル関数を使用して予測を行う方法を示します。
データ セットが大きい場合、またはメモリが限られたハードウェアで予測を行う場合、データをミニバッチに分割して予測を行います。dlnetwork オブジェクトで予測を行う場合、関数 minibatchpredict は入力データをミニバッチに自動的に分割します。モデル関数では、データをミニバッチに手動で分割しなければなりません。
モデル関数の作成とパラメーターの読み込み
MAT ファイル digitsMIMO.mat からモデル パラメーターを読み込みます。この MAT ファイルは、parameters という名前の struct にモデル パラメーター、state という名前の struct にモデルの状態、classNames にクラス名を格納しています。
s = load("digitsMIMO.mat");
parameters = s.parameters;
state = s.state;
classNames = s.classNames;例の最後にリストされているモデル関数 model は、与えられたモデルのパラメーターと状態に基づいてモデルを定義します。
予測用データの読み込み
予測用の数字データを読み込みます。
unzip("DigitsData.zip"); dataFolder = "DigitsData"; imds = imageDatastore(dataFolder, ... IncludeSubfolders=true, ... LabelSource="foldernames"); numObservations = numel(imds.Files);
予測の実行
テスト データのミニバッチをループ処理して、カスタム予測ループを使って予測を行います。
minibatchqueueを使用して、イメージのミニバッチを処理および管理します。ミニバッチ サイズとして 128 を指定します。イメージ データストアの読み取りサイズ プロパティをミニバッチ サイズに設定します。
各ミニバッチで次を行います。
カスタム ミニバッチ前処理関数
preprocessMiniBatch(この例の最後に定義) を使用して、データをバッチに連結し、イメージを正規化。イメージを次元
'SSCB'(spatial、spatial、channel、batch) で形式を整えます。既定では、minibatchqueueオブジェクトは、基となる型がsingleのdlarrayオブジェクトにデータを変換します。GPU が利用できる場合、GPU で予測を実行。既定では、
minibatchqueueオブジェクトは、GPU が利用可能な場合、出力をgpuArrayに変換します。GPU を使用するには、Parallel Computing Toolbox™ とサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。
miniBatchSize = 128; imds.ReadSize = miniBatchSize; mbq = minibatchqueue(imds,... MiniBatchSize=miniBatchSize,... MiniBatchFcn=@preprocessMiniBatch,... MiniBatchFormat="SSCB");
データのミニバッチをループ処理し、モデル関数を使用して予測を行います。関数 scores2label を使用して、クラス ラベルを判定します。予測クラス ラベルを保存します。
doTraining = false; Y1 = []; Y2 = []; % Loop over mini-batches. while hasdata(mbq) % Read mini-batch of data. X = next(mbq); % Make predictions using the model function. [Y1Batch,Y2Batch] = model(parameters,X,doTraining,state); % Determine corresponding classes. Y1Batch = scores2label(Y1Batch,classNames); Y1 = [Y1 Y1Batch]; Y2Batch = extractdata(Y2Batch); Y2 = [Y2 Y2Batch]; end
一部のイメージと、その予測を表示します。
idx = randperm(numObservations,9); figure for i = 1:9 subplot(3,3,i) I = imread(imds.Files{idx(i)}); imshow(I) hold on sz = size(I,1); offset = sz/2; thetaPred = Y2(idx(i)); plot(offset*[1-tand(thetaPred) 1+tand(thetaPred)],[sz 0],"r--") hold off label = string(Y1(idx(i))); title("Label: " + label) end

モデル関数
関数 model は、モデル パラメーター parameters、入力データ X、モデルが学習と予測のどちらの出力を返すべきかを指定するフラグ doTraining、およびネットワークの状態 state を受け取ります。ネットワークはラベルの予測、角度の予測、および更新されたネットワークの状態を出力します。
function [Y1,Y2,state] = model(parameters,X,doTraining,state) % Convolution weights = parameters.conv1.Weights; bias = parameters.conv1.Bias; Y = dlconv(X,weights,bias,Padding="same"); % Batch normalization, ReLU offset = parameters.batchnorm1.Offset; scale = parameters.batchnorm1.Scale; trainedMean = state.batchnorm1.TrainedMean; trainedVariance = state.batchnorm1.TrainedVariance; if doTraining [Y,trainedMean,trainedVariance] = batchnorm(Y,offset,scale,trainedMean,trainedVariance); % Update state state.batchnorm1.TrainedMean = trainedMean; state.batchnorm1.TrainedVariance = trainedVariance; else Y = batchnorm(Y,offset,scale,trainedMean,trainedVariance); end Y = relu(Y); % Convolution, batch normalization (Skip connection) weights = parameters.convSkip.Weights; bias = parameters.convSkip.Bias; YSkip = dlconv(Y,weights,bias,Stride=2); offset = parameters.batchnormSkip.Offset; scale = parameters.batchnormSkip.Scale; trainedMean = state.batchnormSkip.TrainedMean; trainedVariance = state.batchnormSkip.TrainedVariance; if doTraining [YSkip,trainedMean,trainedVariance] = batchnorm(YSkip,offset,scale,trainedMean,trainedVariance); % Update state state.batchnormSkip.TrainedMean = trainedMean; state.batchnormSkip.TrainedVariance = trainedVariance; else YSkip = batchnorm(YSkip,offset,scale,trainedMean,trainedVariance); end % Convolution weights = parameters.conv2.Weights; bias = parameters.conv2.Bias; Y = dlconv(Y,weights,bias,Padding="same",Stride=2); % Batch normalization, ReLU offset = parameters.batchnorm2.Offset; scale = parameters.batchnorm2.Scale; trainedMean = state.batchnorm2.TrainedMean; trainedVariance = state.batchnorm2.TrainedVariance; if doTraining [Y,trainedMean,trainedVariance] = batchnorm(Y,offset,scale,trainedMean,trainedVariance); % Update state state.batchnorm2.TrainedMean = trainedMean; state.batchnorm2.TrainedVariance = trainedVariance; else Y = batchnorm(Y,offset,scale,trainedMean,trainedVariance); end Y = relu(Y); % Convolution weights = parameters.conv3.Weights; bias = parameters.conv3.Bias; Y = dlconv(Y,weights,bias,Padding="same"); % Batch normalization offset = parameters.batchnorm3.Offset; scale = parameters.batchnorm3.Scale; trainedMean = state.batchnorm3.TrainedMean; trainedVariance = state.batchnorm3.TrainedVariance; if doTraining [Y,trainedMean,trainedVariance] = batchnorm(Y,offset,scale,trainedMean,trainedVariance); % Update state state.batchnorm3.TrainedMean = trainedMean; state.batchnorm3.TrainedVariance = trainedVariance; else Y = batchnorm(Y,offset,scale,trainedMean,trainedVariance); end % Addition, ReLU Y = YSkip + Y; Y = relu(Y); % Fully connect, softmax (labels) weights = parameters.fc1.Weights; bias = parameters.fc1.Bias; Y1 = fullyconnect(Y,weights,bias); Y1 = softmax(Y1); % Fully connect (angles) weights = parameters.fc2.Weights; bias = parameters.fc2.Bias; Y2 = fullyconnect(Y,weights,bias); end
ミニバッチ前処理関数
関数 preprocessMiniBatch は、次の手順でデータを前処理します。
入力 cell 配列からデータを抽出し、数値配列に連結します。4 番目の次元で連結することにより、3 番目の次元が各イメージに追加されます。この次元は、シングルトン チャネル次元として使用されることになります。
0と1の間のピクセル値を正規化します。
function X = preprocessMiniBatch(data) % Extract image data from cell and concatenate X = cat(4,data{:}); % Normalize the images. X = X/255; end
参考
dlarray | dlgradient | dlfeval | sgdmupdate | dlconv | batchnorm | relu | fullyconnect | softmax | minibatchqueue | onehotdecode