ディープ ネットワーク デザイナーでの image-to-image 回帰
この例では、ディープ ネットワーク デザイナーを使用して、超解像用の image-to-image 回帰ネットワークの構築と学習を行う方法を示します。
空間解像度は、デジタル イメージを構築するのに使用されるピクセル数です。空間解像度が高いイメージは、それを構成するピクセルの数も多いため、より詳細な情報が含まれることになります。超解像は、低解像度イメージを入力として受け取り、高解像度イメージにアップスケーリングするプロセスです。イメージ データを使用する際、データのサイズを抑えるために、情報の損失と引き換えに空間解像度を下げる場合があります。この損失情報を復元するために、深層学習ネットワークの学習を行い、イメージで損失した詳細情報を予測することができます。この例では、7 x 7 ピクセルに圧縮されたイメージから 28 x 28 ピクセルのイメージを復元します。
データの読み込み
この例では、手書き数字の合成グレースケール イメージ 10,000 個で構成された数字データ セットを使用します。イメージはそれぞれ 28 x 28 x 1 ピクセルです。
データを読み込み、イメージ データストアを作成します。
dataFolder = fullfile(toolboxdir('nnet'),'nndemos','nndatasets','DigitDataset'); imds = imageDatastore(dataFolder, ... 'IncludeSubfolders',true, .... 'LabelSource','foldernames');
学習前に関数shuffle
を使用してデータをシャッフルします。
imds = shuffle(imds);
関数splitEachLabel
を使用して、このイメージ データストアを学習用、検証用、テスト用のイメージを含む 3 つのイメージ データストアに分割します。
[imdsTrain,imdsVal,imdsTest] = splitEachLabel(imds,0.7,0.15,0.15,'randomized');
各イメージ内のデータを [0,1] の範囲に正規化します。正規化は、勾配降下を使用したネットワークの学習の安定化と高速化に有効です。データが適切にスケーリングされていない場合、学習中に損失が NaN になり、ネットワーク パラメーターが発散する可能性があります。
imdsTrain = transform(imdsTrain,@(x) rescale(x)); imdsVal = transform(imdsVal,@(x) rescale(x)); imdsTest = transform(imdsTest,@(x) rescale(x));
学習データの生成
アップサンプリングされた低解像度イメージと、それに対応する高解像度イメージで構成されるイメージのペアを生成することにより、学習データ セットを作成します。
image-to-image 回帰を実行するようにネットワークの学習を行うには、イメージは、入力と応答で構成される、サイズが同じイメージのイメージのペアとなる必要があります。各イメージを 7 x 7 ピクセルにダウンサンプリングしてから 28 x 28 ピクセルにアップサンプリングすることにより、学習データを生成します。変換されたイメージと元のイメージのペアを使用することで、ネットワークは 2 つの異なる解像度間でマッピングする方法を学習できます。
補助関数 upsampLowRes
を使用して入力データを生成します。この補助関数は imresize
を使用して低解像度イメージを生成します。
imdsInputTrain = transform(imdsTrain,@upsampLowRes); imdsInputVal= transform(imdsVal,@upsampLowRes); imdsInputTest = transform(imdsTest,@upsampLowRes);
関数combine
を使用し、低解像度と高解像度のイメージを組み合わせて単一のデータストアにします。関数 combine
の出力はCombinedDatastore
オブジェクトです。
dsTrain = combine(imdsInputTrain,imdsTrain); dsVal = combine(imdsInputVal,imdsVal); dsTest = combine(imdsInputTest,imdsTest);
ネットワーク アーキテクチャの作成
Computer Vision Toolbox™ から関数 unetLayers
を使用して、ネットワーク アーキテクチャを作成します。この関数は、image-to-image 回帰に簡単に適応可能な、セマンティック セグメンテーションに適したネットワークを提供します。
入力サイズが 28 x 28 x 1 ピクセルのネットワークを作成します。
layers = unetLayers([28,28,1],2,'encoderDepth',2);
ディープ ネットワーク デザイナーを使用して、image-to-image 回帰用にネットワークを編集します。
deepNetworkDesigner(layers);
[デザイナー] ペインから、ソフトマックス層とピクセル分類層を [層のライブラリ] にある回帰層に置き換えます。
最終畳み込み層を選択し、NumFilters
プロパティを 1
に設定します。
これでネットワークの学習準備が整いました。
データのインポート
ディープ ネットワーク デザイナーに学習データと検証データをインポートします。
[データ] タブで [データのインポート]、[カスタム データのインポート] とクリックし、dsTrain
を学習データとして、dsVal
を検証データとして選択します。[インポート] をクリックして両方のデータストアをインポートします。
ディープ ネットワーク デザイナーは、結合されたデータストア内にあるイメージのペアを表示します。アップスケーリングされた低解像度の入力イメージは左側に、元の高解像度の応答イメージは右側に表示されます。ネットワークは、入力イメージと応答イメージの間でマッピングする方法を学習します。
ネットワークの学習
学習オプションを選択し、ネットワークに学習させます。
[学習] タブで [学習オプション] を選択します。[ソルバー] リストから adam
を選択します。[MaxEpochs] を 10
に設定します。[OK] をクリックして学習オプションを確定します。
[学習] をクリックして、結合されたデータストアでネットワークに学習させます。
ネットワークが 2 つのイメージ間のマッピング方法を学習するため、検証の平方根平均二乗誤差 (RMSE) は減少します。
学習が完了したら、[エクスポート] をクリックして、学習済みネットワークをワークスペースにエクスポートします。学習済みネットワークは、変数 trainedNetwork_1
に保存されます。
ネットワークのテスト
テスト データを使用して、ネットワーク性能を評価します。
predict
を使用すれば、学習セットに含まれていなかった低解像度の入力イメージから高解像度イメージをネットワークが生成できるかどうかをテストできます。
ypred = predict(trainedNetwork_1,dsTest); for i = 1:8 I(1:2,i) = read(dsTest); I(3,i) = {ypred(:,:,:,i)}; end
入力イメージ、予測されたイメージ、応答イメージを比較します。
subplot(1,3,1) imshow(imtile(I(1,:),'GridSize',[8,1])) title('Input') subplot(1,3,2) imshow(imtile(I(3,:),'GridSize',[8,1])) title('Predict') subplot(1,3,3) imshow(imtile(I(2,:),'GridSize',[8,1])) title('Response')
ネットワークは、低解像度の入力から高解像度イメージを正常に生成しています。
この例のネットワークは非常に単純で、数字データ セットに合せて高度に調整されています。日常的なイメージを対象とした、より複雑な image-to-image 回帰ネットワークの作成方法を示す例については、深層学習を使用したイメージの高解像度化を参照してください。
サポート関数
function dataOut = upsampLowRes(dataIn) temp = dataIn; temp = imresize(temp,[7,7],'method','bilinear'); dataOut = {imresize(temp,[28,28],'method','bilinear')}; end
参考
ディープ ネットワーク デザイナー | trainingOptions