メインコンテンツ

minibatchqueue

深層学習用のミニバッチの作成

説明

minibatchqueue オブジェクトを使用して、深層学習用のデータのミニバッチを作成し、前処理し、管理します。

minibatchqueue オブジェクトはデータストアに対して反復処理を行い、学習または予測に適した形式でデータを提供します。このオブジェクトは、オンデマンドで前処理されたミニバッチのキューを準備します。minibatchqueue オブジェクトを使用すると、dlarraygpuArray へのデータの自動変換、異なる精度へのデータの変換、またはデータを前処理するためのカスタム関数の適用を行うことができます。バックグラウンドで並列処理してデータを準備できます。

minibatchqueue オブジェクトを使用して、カスタム学習ループでデータを管理できます。関数 shuffle を使用して各学習エポックの開始時にデータをシャッフルし、関数 next を使用して学習の反復ごとにキューからデータを収集することができます。関数 hasdata を使用してキューにデータが残っていないかチェックし、キューが空になったときに reset を使用してキューをリセットすることができます。

作成

説明

mbq = minibatchqueue(ds) は、入力データストア ds から minibatchqueue オブジェクトを作成します。mbq に格納されるミニバッチの数は、入力データストアに対して read を実行した結果として得られる変数の数と同じです。

mbq = minibatchqueue(ds,numOutputs) は、入力データストア ds から minibatchqueue オブジェクトを作成し、各ミニバッチに含まれる変数の数を設定します。MiniBatchFcn を使用して入力データストア ds の変数の数と異なる数の出力をもつミニバッチ前処理関数を指定する場合、この構文を使用します。

mbq = minibatchqueue(___,Name=Value) は、名前と値の引数を使用して 1 つ以上のプロパティを設定します。たとえば、minibatchqueue(ds,MiniBatchSize=64,PartialMiniBatch="discard") は、返されるミニバッチのサイズを 64 に設定し、観測値の数が 64 個より少ないミニバッチを破棄します。

入力引数

すべて展開する

入力データストア。MATLAB® のデータストアまたはカスタム データストアとして指定します。

深層学習用のデータストアの詳細については、深層学習用のデータストアを参照してください。

ミニバッチ変数の数。正の整数として指定します。既定では、ミニバッチ変数の数は入力データストアの変数の数に等しくなります。

read(ds) の出力を調べることで、入力データストアの変数の数を判断できます。データストアが table を返す場合、変数の数は table に含まれる変数の数になります。データストアが cell 配列を返す場合、変数の数は cell 配列の 2 番目の次元のサイズになります。

名前と値の引数 MiniBatchFcn を使用して、入力データストアと異なる数の変数を返すミニバッチ前処理関数を指定する場合、関数の出力の数と一致するように numOutputs を設定しなければなりません。

例: 2

プロパティ

すべて展開する

この プロパティ は読み取り専用です。

関数 next によって返されるミニバッチのサイズ。正の整数として指定します。既定値は 128 です。

ヒント

最高のパフォーマンスを得るために、入力データストア dsimageDatastore などの ReadSize プロパティがある場合は、入力データストアの ReadSize プロパティと minibatchqueue オブジェクトの MiniBatchSize プロパティを同じ値に設定します。入力データストア dsaugmentedImageDatastore などの MiniBatchSize プロパティがある場合は、入力データストアの MiniBatchSize プロパティと minibatchqueue オブジェクトの MiniBatchSize プロパティを同じ値に設定します。

例: 256

不完全なミニバッチを返すか破棄するか。"return" または "discard" として指定します。

観測値の総数が MiniBatchSize で割り切れない場合、関数 next によって最後に返されるミニバッチは、観測値の数が MiniBatchSize より少なくなる可能性があります。このプロパティは、次のオプションを使用して、不完全なミニバッチをどのように処理するかを指定します。

  • "return" — ミニバッチは MiniBatchSize より少ない数の観測値をもつことができます。すべてのデータが返されます。

    "discard" — すべてのミニバッチに MiniBatchSize と同じ数の観測値が含まれていなければなりません。完全なミニバッチを構成するのに十分なデータが存在しない場合、キューに含まれるデータの一部が破棄される可能性があります。

すべてのミニバッチを同じサイズにする必要がある場合は、PartialMiniBatch"discard" に設定します。

minibatchqueue オブジェクトは、このプロパティを文字ベクトルとして格納します。

例: "discard"

データ型: char | string

この プロパティ は読み取り専用です。

ミニバッチ前処理関数。"collate" または関数ハンドルとして指定します。

MiniBatchFcn の既定値は "collate" です。この関数は、ミニバッチ変数を連結して配列とします。ミニバッチ変数が N 個の次元をもつ場合、この関数は N+1 次元目に沿ってミニバッチ変数を連結します。

カスタム学習で使用するミニバッチを前処理するため、カスタム関数への関数ハンドルを使用します。分類ラベルの one-hot 符号化、シーケンス データのパディング、平均イメージの計算などでは、この方法を推奨します。サイズの異なる配列で構成された cell 配列がデータに含まれている場合、カスタム関数を指定しなければなりません。

カスタム ミニバッチ前処理関数を指定する場合、その関数は、前処理後に出力変数の各バッチを連結して配列とし、各変数を個別の関数出力として返さなければなりません。この関数は、少なくとも基になるデータストアの変数と同じ数の入力を受け入れなければなりません。入力は N 行 1 列の cell 配列としてカスタム関数に渡されます。ここで、N はミニバッチに含まれる観測値の数です。この関数は必要な数だけ変数を返すことができます。MiniBatchFcn で指定された関数が入力と異なる数の出力を返す場合、関数の出力の数として numOutputs を指定します。

カスタム関数の内部で、以下のアクションは推奨されません。目的の動作を再現するには、minibatchqueue オブジェクトの作成時に、対応するプロパティを設定します。

アクション推奨されるプロパティ
変数を別のデータ型にキャスト。OutputCast
データを GPU に移動。OutputEnvironment
データを dlarray に変換。OutputAsDlarray
dlarray 変数にデータ形式を適用。MiniBatchFormat

minibatchqueue オブジェクトは、このプロパティを文字ベクトルまたは関数ハンドルとして格納します。

例: @myCustomFunction

データ型: char | string | function_handle

R2024a 以降

ミニバッチの取得と前処理を行うための環境。次のいずれかの値として指定します。

  • "serial" – データの取得と前処理は逐次実行されます。

  • "background" – バックグラウンド プールを使用してデータの取得と前処理が行われます。ミニバッチ前処理関数 MiniBatchFcn は、スレッドベースの環境をサポートしなければなりません。詳細については、スレッドベースの環境での MATLAB 関数の実行を参照してください。

  • "parallel" – 並列ワーカーを使用してデータの取得と前処理が行われます。ローカル プールが開かれていなければ、ソフトウェアは既定のプロファイルを使用して並列プールを開きます。ローカルではない並列プールはサポートされません。このオプションを使用するには、Parallel Computing Toolbox™ が必要です。

"background" オプションまたは "parallel" オプションを使用するには、入力データストアがサブセット化可能または分割可能でなければなりません。カスタム データストアには matlab.io.datastore.Subsettable クラスが実装されていなければなりません。

"background" オプションまたは "parallel" オプションを使用すると、next 関数によって返されるミニバッチの順序が変化するため、deep.gpu.deterministicAlgorithms 関数を使用する場合でも、minibatchqueue を使用したネットワークの学習は非確定的になります。

前処理環境は MiniBatchFcn がどのように適用されるかを定義しますが、OutputCastOutputEnvironmentOutputAsDlarray、および MiniBatchFormat の効果の適用といった追加の処理には影響しません。

ミニバッチに大幅な前処理が必要な場合は、"background" オプションを使用します。前処理がスレッドでサポートされていない場合、またはワーカー数を制御する必要がある場合は、"parallel" オプションを使用します。前処理環境の詳細については、Preprocess Data in the Background or in Parallelを参照してください。

minibatchqueue オブジェクトは、このプロパティを文字ベクトルとして格納します。

R2024a より前: ミニバッチを並列で前処理するには、DispatchInBackground プロパティを 1 (true) に設定します。

データ型: char | string

この プロパティ は読み取り専用です。

各ミニバッチ変数のデータ型。"single""double""int8""int16""int32""int64""uint8""uint16""uint32""uint64""logical""char"、またはこれらの値の string 配列、これらの値の文字ベクトルの cell 配列、あるいは空のベクトルとして指定します。

OutputCast を空のベクトルとして指定した場合、各ミニバッチ変数のデータ型は変更されません。ミニバッチ変数ごとに異なるデータ型を指定するには、各ミニバッチ変数のエントリが格納された string 配列を指定します。この string 配列の要素の順序は、ミニバッチ変数が返される順序と同じでなければなりません。この順序は、MiniBatchFcn で指定された関数から返される変数の順序と同じです。MiniBatchFcn のカスタム関数を指定しない場合、この順序は、基になるデータストアによって返される変数の順序と同じになります。

OutputCast の値が OutputAsDlarray プロパティまたは OutputEnvironment プロパティの値と競合しないことを確認してください。OutputAsDlarraytrue または 1 として指定した場合、OutputCast で指定されたデータ型が dlarray によってサポートされていることを確認してください。OutputEnvironment"gpu" または "auto" として指定し、サポートされている GPU を利用できる場合、OutputCast で指定されたデータ型が gpuArray (Parallel Computing Toolbox) によってサポートされていることを確認してください。

minibatchqueue オブジェクトは、このプロパティを文字ベクトルの cell 配列として格納します。

例: ["single" "single" "logical"]

データ型: char | string

この プロパティ は読み取り専用です。

ミニバッチ変数を dlarray に変換するフラグ。数値または logical の 1 (true) または 0 (false)、あるいは数値または logical 値のベクトルとして指定します。

出力ごとに異なる値を指定するには、各ミニバッチ変数のエントリが格納されたベクトルを指定します。このベクトルの要素の順序は、ミニバッチ変数が返される順序と同じでなければなりません。この順序は、MiniBatchFcn で指定された関数から返される変数の順序と同じです。MiniBatchFcn のカスタム関数を指定しない場合、この順序は、基になるデータストアによって返される変数の順序と同じになります。

dlarray に変換された変数は、基になるデータ型として OutputCast プロパティで指定されたデータ型をもちます。

例: [1 1 0]

データ型: logical

この プロパティ は読み取り専用です。

ミニバッチ変数のデータ形式。string スカラー、文字ベクトル、string 配列、または文字ベクトルの cell 配列として指定します。

このミニバッチの形式は、dlarray 変数にのみ適用されます。dlarray でないミニバッチ変数については、MiniBatchFormat"" に設定しなければなりません。

dlarray 変数と dlarray でない変数が混在しているときにエラーが発生するのを防ぐには、各ミニバッチ変数のエントリが格納された string 配列を与えて各出力の値を指定しなければなりません。この string 配列の要素の順序は、ミニバッチ変数が返される順序と同じでなければなりません。これは、MiniBatchFcn で指定された関数から返される変数の順序と同じです。MiniBatchFcn のカスタム関数を指定しない場合、この順序は、基になるデータストアによって返される変数の順序と同じになります。

データに含まれている次元よりも多くの次元を指定した場合、それらは大きさが 1 の次元として追加されます。たとえば、大きさが 1 のチャネル次元をデータに追加するには、最後に "C" 次元を追加します。

データ形式は文字列で、各文字は対応するデータ次元のタイプを表します。

各文字は以下のとおりです。

  • "S" — 空間

  • "C" — チャネル

  • "B" — バッチ

  • "T" — 時間

  • "U" — 指定なし

たとえば、シーケンスのバッチを表し、1 番目、2 番目、および 3 番目の次元がそれぞれチャネル、観測値、およびタイム ステップに対応する配列があるとします。データは "CBT" (チャネル、バッチ、時間) の形式で記述できます。

"S" または "U" のラベルが付いた次元については、複数回指定できます。ラベル "C""B"、および "T" はそれぞれ 1 回まで使用できます。ソフトウェアは、2 番目の次元の後ろにある大きさが 1 の "U" 次元を無視します。

詳細については、深層学習のデータ形式を参照してください。

minibatchqueue オブジェクトは、このプロパティを文字ベクトルの cell 配列として格納します。

例: ["SSCB" ""]

データ型: char | string

関数 next を使用して返されるミニバッチ変数のハードウェア リソース。次のいずれかの値として指定します。

  • "auto" — 利用できる場合は GPU 上のミニバッチ変数を返します。そうでない場合は CPU 上のミニバッチ変数を返します。

  • "gpu" — GPU 上のミニバッチ変数を返します。

  • "cpu" — CPU 上のミニバッチ変数を返します。

GPU 上の特定の変数のみを返すには、各ミニバッチ変数のエントリが格納された string 配列として OutputEnvironment を指定します。この string 配列の要素の順序は、ミニバッチ変数が返される順序と同じでなければなりません。この順序は、MiniBatchFcn で指定された関数から返される変数の順序と同じです。カスタムの MiniBatchFcn を指定しない場合、この順序は、基になるデータストアによって返される変数の順序と同じになります。

GPU を使用するには Parallel Computing Toolbox が必要です。深層学習に GPU を使用するには、サポートされている GPU デバイスもなければなりません。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。"gpu" オプションの選択時に Parallel Computing Toolbox または適切な GPU が利用できない場合、エラーが返されます。

minibatchqueue オブジェクトは、このプロパティを文字ベクトルの cell 配列として格納します。

例: ["gpu" "cpu"]

データ型: char | string

オブジェクト関数

hasdataDetermine if minibatchqueue can return mini-batch
nextミニバッチキューからの次のデータ ミニバッチの取得
partitionPartition minibatchqueue
resetReset minibatchqueue to start of data
shuffleShuffle data in minibatchqueue

すべて折りたたむ

minibatchqueue オブジェクトを使用して、trainnet 関数を使用した学習やカスタム学習ループでの学習に使用するイメージと分類ラベルのミニバッチを自動的に準備します。

データストアを作成します。auimds に対して read を呼び出すと、イメージ データが格納された input および対応する分類ラベルが格納された response という 2 つの変数を含む table が生成されます。

auimds = augmentedImageDatastore([100 100],digitDatastore);
A = read(auimds);
head(A,2)
ans = 
         input         response
    _______________    ________

    {100×100 uint8}       0    
    {100×100 uint8}       0    

auimds から minibatchqueue オブジェクトを作成します。MiniBatchSize プロパティを 256 に設定します。

minibatchqueue オブジェクトは、auimds の変数 inputresponse からそれぞれ取得したイメージと分類ラベルである 2 つの出力変数をもちます。GPU 上で形式を整えた dlarray としてイメージを返すように、minibatchqueue オブジェクトを設定します。このイメージは、単一チャネルの白黒イメージです。形式 "SSBC" をバッチに適用し、大きさが 1 であるチャネル次元を追加します。CPU 上にあるラベルを非 dlarray として返します。

mbq = minibatchqueue(auimds,...
    MiniBatchSize=256, ...
    OutputAsDlarray=[1 0], ...
    MiniBatchFormat=["SSBC" ""], ...
    OutputEnvironment=["gpu" "cpu"])

カスタム学習ループで使用するために mbq からミニバッチを取得するには、next 関数を使用します。

[X,Y] = next(mbq);

minibatchqueue およびカスタム ミニバッチ前処理関数を使用して、データを前処理します。このカスタム関数は、入力イメージ データを 0 ~ 1 の範囲に再スケーリングし、平均イメージを計算します。

データを解凍してデータストアを作成します。

unzip("MerchData.zip");
imds = imageDatastore("MerchData", ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames"); 

minibatchqueue. を作成します。

  • 関数の出力の数と一致するように、出力の数を 2 に設定します。

  • ミニバッチのサイズを設定します。

  • この例の終わりに定義されているカスタム関数 preprocessMiniBatch を使用してデータを前処理します。このカスタム関数は、イメージ データを連結して数値配列とし、イメージを 0 ~ 1 の範囲に再スケーリングして、イメージ バッチの平均を計算します。この関数は、再スケーリングされたイメージ バッチおよび平均イメージを返します。

  • PreprocessingEnvironment プロパティを "background" に設定し、バックグラウンドで前処理関数を適用します。前処理関数がスレッドベースの環境に対応している場合、データをバックグラウンドで前処理できます。

  • ミニバッチの出力変数は dlarray に変換しません。

mbq = minibatchqueue(imds,2,...
    MiniBatchSize=16,...
    MiniBatchFcn=@preprocessMiniBatch,...
    PreprocessingEnvironment="background",...
    OutputAsDlarray=false)
mbq = 
minibatchqueue with 2 outputs and properties:

   Mini-batch creation:
               MiniBatchSize: 16
            PartialMiniBatch: 'return'
                MiniBatchFcn: @preprocessMiniBatch
    PreprocessingEnvironment: 'background'

   Outputs:
                  OutputCast: {'single'  'single'}
             OutputAsDlarray: [0 0]
             MiniBatchFormat: {''  ''}
           OutputEnvironment: {'auto'  'auto'}

ミニバッチを取得し、ミニバッチに含まれるイメージの平均を表示します。backgroundPool 内のスレッド ワーカーによって前処理関数が適用されます。

[X,averageImage] = next(mbq);
imshow(averageImage)

Figure contains an axes object. The hidden axes object contains an object of type image.

function [X,averageImage] = preprocessMiniBatch(XCell)
    X = cat(4,XCell{:});
    
    X = rescale(X,InputMin=0,InputMax=255);
    averageImage = mean(X,4);
end

minibatchqueue を使用してネットワークに学習させ、ミニバッチの処理を管理します。

学習データの読み込み

数字の学習データを読み込み、そのデータをデータストアに格納します。arrayDatastore を使用して、イメージ用とラベル用のデータストアを作成します。その後、データストアを結合し、minibatchqueue で使用する 1 つのデータストアを生成します。

[XTrain,YTrain] = digitTrain4DArrayData;
dsX = arrayDatastore(XTrain,IterationDimension=4);
dsY = arrayDatastore(YTrain);

dsTrain = combine(dsX,dsY);

ラベル データに含まれる一意のクラスの数を判定します。

classes = categories(YTrain);
numClasses = numel(classes);

ネットワークの定義

dlnetwork オブジェクトを作成します。

net = dlnetwork;

層を指定し、イメージ入力層で Mean オプションを使用して平均イメージの値を指定します。

layers = [
    imageInputLayer([28 28 1],Mean=mean(XTrain,4))
    convolution2dLayer(5,20)
    reluLayer
    convolution2dLayer(3,20,Padding=1)
    reluLayer
    convolution2dLayer(3,20,Padding=1)
    reluLayer
    fullyConnectedLayer(numClasses)
    softmaxLayer];

層を追加してネットワークを初期化します。

net = addLayers(net,layers);
net = initialize(net);

モデル損失関数の定義

例の最後にリストされている補助関数 modelLoss を作成します。この関数は、dlnetwork オブジェクト net、入力データのミニバッチ X とそれに対応するラベル Y を入力として受け取り、損失、および net 内の学習可能なパラメーターについての損失の勾配を返します。

学習オプションの指定

学習中に使用するオプションを指定します。

numEpochs = 10;
miniBatchSize = 128;

学習の進行状況をプロットに可視化します。

plots = "training-progress";

minibatchqueue を作成します。

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(dsTrain,...
    MiniBatchSize=miniBatchSize,...
    PartialMiniBatch="discard",...
    MiniBatchFcn=@preprocessMiniBatch,...    
    MiniBatchFormat=["SSCB",""]);

ネットワークの学習

カスタム学習ループを使用してモデルに学習させます。各エポックについて、minibatchqueue にデータが残っている間、データをシャッフルしてミニバッチをループで回します。関数 adamupdate を使用してネットワーク パラメーターを更新します。各エポックの最後に、学習の進行状況を表示します。

平均勾配および 2 乗平均勾配を初期化します。

averageGrad = [];
averageSqGrad = [];

学習の進行状況モニター用に合計反復回数を計算します。

numObservationsTrain = numel(YTrain);
numIterationsPerEpoch = ceil(numObservationsTrain / miniBatchSize);
numIterations = numEpochs * numIterationsPerEpoch;

TrainingProgressMonitor オブジェクトを初期化します。監視オブジェクトを作成するとタイマーが開始されるため、学習ループに近いところでオブジェクトを作成するようにしてください。

if plots == "training-progress"
    monitor = trainingProgressMonitor(Metrics="Loss",Info="Epoch",XLabel="Iteration");
end

ネットワークに学習をさせます。

iteration = 0;
epoch = 0;

while epoch < numEpochs && ~monitor.Stop
    epoch = epoch + 1;

    % Shuffle data.
    shuffle (mbq);
        
    while hasdata(mbq)  && ~monitor.Stop
        iteration = iteration + 1;
        
        % Read mini-batch of data.
        [X,Y] = next(mbq);
              
        % Evaluate the model loss and gradients using dlfeval and the
        % modelLoss helper function.
        [loss,grad] = dlfeval(@modelLoss,net,X,Y);

        % Update the network parameters using the Adam optimizer.
        [net,averageGrad,averageSqGrad] = adamupdate(net,grad,averageGrad,averageSqGrad,iteration);

        % Update the training progress monitor.
        if plots == "training-progress"
            recordMetrics(monitor,iteration,Loss=loss);
            updateInfo(monitor,Epoch=epoch + " of " + numEpochs);
            monitor.Progress = 100 * iteration/numIterations;
        end
    end
end

モデル損失関数

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

function [loss,gradients] = modelLoss(net,X,Y)
    YPred = forward(net,X);    
    loss = crossentropy(YPred,Y);    
    gradients = dlgradient(loss,net.Learnables);
    
end

ミニバッチ前処理関数

関数 preprocessMiniBatch は、次の手順でデータを前処理します。

  1. 入力 cell 配列からイメージ データを抽出し、そのデータを連結して数値配列とします。4 番目の次元でイメージ データを連結することにより、3 番目の次元が各イメージに追加されます。この次元は、シングルトン チャネル次元として使用されます。

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

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

function [X,Y] = preprocessMiniBatch(XCell,YCell)
    % Extract image data from the cell array and concatenate over fourth
    % dimension to add a third singleton dimension, as the channel
    % dimension.
    X = cat(4,XCell{:});

    % Extract label data from cell and concatenate.
    Y = cat(2,YCell{:});
    
    % One-hot encode labels.
    Y = onehotencode(Y,1);

end

バージョン履歴

R2020b で導入

すべて展開する