イメージ分類用のデータストアの作成と確認
この例では、深層学習ネットワークの学習で使用するイメージ データストアの作成、読み取り、および拡張を行う方法を示します。特に、この例では、イメージ コレクションから ImageDatastore
オブジェクトを作成し、データストアのプロパティを読み取って抽出し、学習中に使用するための augmentedImageDatastore
を作成する方法を示します。
イメージ データストアの作成
imageDatastore
オブジェクトを使用して、メモリに完全に収まらない大規模なイメージ コレクションを管理します。深層学習アプリケーションでは大規模なイメージ コレクションが一般的で、何千ものラベル付きイメージで学習させることがよく行われています。これらのイメージは多くの場合、クラスごとにイメージが格納されたサブフォルダーをもつフォルダーに保存されます。
データ セットのダウンロード
この例では、食品イメージのサンプルというデータセットを使用します。このデータセットには 9 クラスの 978 枚の食品の写真が含まれており、サイズは約 77 MB です。MathWorks の Web サイトから ExampleFoodImageDataset.zip
ファイルをダウンロードし、ファイルを解凍します。
zipFile = matlab.internal.examples.downloadSupportFile('nnet','data/ExampleFoodImageDataset.zip'); filepath = fileparts(zipFile); dataFolder = fullfile(filepath,'ExampleFoodImageDataset'); unzip(zipFile,dataFolder);
このデータ セットのイメージは、クラスごとにサブフォルダーに分けられています。
パスとそのサブフォルダー内のイメージからイメージ データストアを作成します。フォルダー名をラベル名として使用します。
foodImds = imageDatastore(dataFolder, ... 'IncludeSubfolders',true, ... 'LabelSource','foldernames');
データストアのプロパティ
データストアのプロパティを抽出します。
観測値の総数を求めます。このデータ セットには、9 つのクラスに分割された 978 個の観測値があります。
numObs = length(foodImds.Labels)
numObs = 978
クラスごとの観測値の数を求めます。このデータ セットでは、含まれる各クラスの観測値の数が同じでないことがわかります。
numObsPerClass = countEachLabel(foodImds)
numObsPerClass=9×2 table
Label Count
_____________ _____
caesar_salad 26
caprese_salad 15
french_fries 181
greek_salad 24
hamburger 238
hot_dog 31
pizza 299
sashimi 40
sushi 124
ヒストグラムを使用して、クラス ラベルの分布を可視化することもできます。
histogram(foodImds.Labels) set(gca,'TickLabelInterpreter','none')
データストアの確認
データストアからランダムに選択したイメージを表示して、データが期待どおりであることをチェックします。
numObsToShow = 8; idx = randperm(numObs,numObsToShow); imshow(imtile(foodImds.Files(idx),'GridSize',[2 4],'ThumbnailSize',[100 100]))
特定のクラスに属するイメージを表示することもできます。
class ="pizza"; idxClass = find(foodImds.Labels == class); idx = randsample(idxClass,numObsToShow); imshow(imtile(foodImds.Files(idx),'GridSize',[2 4],'ThumbnailSize',[100 100]));
データストアまたはフォルダー内の個々のイメージを詳しく調べるには、イメージ ブラウザー (Image Processing Toolbox)アプリを使用します。
イメージ拡張
拡張では、イメージ データの歪みに対して不変になるようにネットワークに学習させることができます。たとえば、存在する回転に対してネットワークが不変になるように、入力イメージにランダムな回転を追加できます。augmentedImageDatastore
オブジェクトは、分類問題用の 2 次元イメージに限られた拡張を適用する便利な方法を提供します。
拡張スキームを定義します。このスキームは、[–90,90] 度の範囲のランダムな回転と、[1,2] の範囲のランダムなスケーリングを適用します。拡張データストアは、学習中にイメージのサイズを inputSize
値に自動的に変更します。
imageAugmenter = imageDataAugmenter( ... 'RandRotation',[-90 90], ... 'RandScale',[1 2]); inputSize = [100 100];
拡張スキームを使用して、拡張イメージ データストアを定義します。
augFoodImds = augmentedImageDatastore(inputSize,foodImds, ... 'DataAugmentation',imageAugmenter);
拡張データストアには、元のイメージ データストアと同じ数のイメージが含まれています。
augFoodImds.NumObservations
ans = 978
拡張イメージ データストアを学習イメージのソースとして使用する場合、データストアは各エポックの学習データにランダムに摂動を与えます。ここで、1 エポックは学習データ セット全体に対する学習アルゴリズムを一巡することです。したがって、各エポックで使用されるデータ セットはわずかに異なりますが、各エポックにおける学習イメージの実際の数は変化しません。
拡張データの可視化
ネットワークに学習させるために使用する拡張イメージ データを可視化します。
データストアをシャッフルします。
augFoodImds = shuffle(augFoodImds);
augmentedImageDatastore
オブジェクトは、データストアの読み取り時に変換を適用し、変換されたイメージをメモリに保存しません。その結果、同じイメージを読み取るたびに、定義されている拡張のランダムな組み合わせが表示されます。
関数read
を使用して、拡張データストアのサブセットを読み取ります。
subset1 = read(augFoodImds);
read を呼び出す前の状態にデータストアをリセットし、データストアのサブセットを再度読み取ります。
reset(augFoodImds) subset2 = read(augFoodImds);
拡張イメージの 2 つのサブセットを表示します。
imshow(imtile(subset1.input,'GridSize',[2 4]))
imshow(imtile(subset2.input,'GridSize',[2 4]))
両方のインスタンスが、同じイメージを異なる変換処理で表示していることがわかります。イメージへの変換処理の適用は、ランダムな変更が加えられたバージョンのイメージでネットワークに学習させることができるため、深層学習アプリケーションで有効です。そうすることで、ネットワークをそのクラスのイメージのさまざまなバリエーションに触れさせ、視覚的特性が異なるイメージについても分類を学習させることが可能になります。
データストア オブジェクトを作成したら、ディープ ネットワーク デザイナーアプリまたは関数trainNetwork
を使用してイメージ分類ネットワークに学習させます。例については、事前学習済みのネットワークを使用した転移学習を参照してください。
深層学習アプリケーション用のイメージの前処理の詳細については、イメージの深層学習向け前処理を参照してください。関数transform
およびcombine
を使用して、さまざまなレベルの明度や彩度といった、より高度な拡張を適用することもできます。詳細については、深層学習用のデータストアを参照してください。
参考
trainNetwork
| ディープ ネットワーク デザイナー | augmentedImageDatastore
| imageDatastore