分類用のシンプルな深層学習ネットワークの作成

7 views (last 30 days)
陸
on 26 Oct 2022
Commented: on 31 Oct 2022
「分類用のシンプルな深層学習ネットワークの作成」をMATLAB公式サンプルコードを用いてます。
画像ファイルの自前の画像にし、野菜の画像分類を行いたいです。
データのみオリジナルに変更し、試みていますが入力層の部分でエラーが発生しました。
下記は全てのコードです。
自前の画像データをサイズ変更すれば問題ないかと思いますが、サイズ変更の仕方やその他考えられる原因を特定したいです。
%digitDatasetPath = fullfile(matlabroot,'toolbox','nnet','nndemos', ...
%'nndatasets','DigitDataset');
%imds = imageDatastore(digitDatasetPath, ...
%'IncludeSubfolders',true,'LabelSource','foldernames');
unzip('Negi.zip');
imds = imageDatastore('Negi', ...
'IncludeSubfolders',true, ...
'LabelSource','foldernames');
figure;
perm = randperm(306,20);
for i = 1:20
subplot(4,5,i);
imshow(imds.Files{perm(i)});
end
labelCount = countEachLabel(imds)
img = readimage(imds,1);
%ans=1*3
% 1411 2124 3
numTrainFiles = 87;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,'randomize');
layers = [
imageInputLayer([28 28 1])
convolution2dLayer(3,8,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer(2,'Stride',2)
convolution2dLayer(3,16,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer(2,'Stride',2)
convolution2dLayer(3,32,'Padding','same')
batchNormalizationLayer
reluLayer
fullyConnectedLayer(10)
softmaxLayer
classificationLayer];
options = trainingOptions('sgdm', ...
'InitialLearnRate',0.01, ...
'MaxEpochs',4, ...
'Shuffle','every-epoch', ...
'ValidationData',imdsValidation, ...
'ValidationFrequency',30, ...
'Verbose',false, ...
'Plots','training-progress');
net = trainNetwork(imdsTrain,layers,options);
次を使用中:trainNetwork
画像のイメージサイズは1411*2124*3ですが、入力層にはサイズ28*28*1のイメージが必要です。
YPred = classify(net,imdsValidation);
YValidation = imdsValidation.Labels;
accuracy = sum(YPred == YValidation)/numel(YValidation)

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 28 Oct 2022
先の回答では多分うまく行かないので改めて回答を設けました。
上記はサイズ 28*28 のモノクロ画像である「数字の画像」を入力とする為、深層学習ネットワーク:入力層のサイズを [28 28] としています。それに対し今回試したい「野菜の画像」はサイズ 1411*2124 のカラー画像なので、上記入力層を設定した深層学習ネットワークではうまく学習出来ないでしょう。次の様にすれば野菜の画像に適した学習が出来ると思います。
unzip('Negi.zip');の中身は上記例題と同様、野菜の種類の名前が付いたフォルダが複数存在し、各フォルダの内部にはフォルダ名の野菜画像が複数枚入っているものと想定します。
入力層のサイズだけでなくその後に続く各種ネットワーク層も比較的大きな野菜の画像の適した形に変えていかないと、認識率の高い結果には結びつかないかもしれません。初めに調整すべきパラメータは入力層の画像サイズ、エポック数、学習させる画像の枚数(学習用の枚数が多い程良い結果になりそう)です。個人的には小さい画像の方がパラメータ変更の影響を観察しやすいと思います。
%digitDatasetPath = fullfile(matlabroot,'toolbox','nnet','nndemos', ...
%'nndatasets','DigitDataset');
%imds = imageDatastore(digitDatasetPath, ...
%'IncludeSubfolders',true,'LabelSource','foldernames');
unzip('Negi.zip');
imds = imageDatastore('Negi', ...
'IncludeSubfolders',true, ...
'LabelSource','foldernames');
% labelCount:ラベル数:分類する野菜の種類数("Negi"フォルダ内部にあると想定するサブフォルダ数)が表示される
labelCount = countEachLabel(imds)
img = readimage(imds,1);
inputSize = size(img) % 入力層のサイズをどうするか⇒単に1枚目の画像のサイズ(カラー/モノクロ含む)を得る
%ans=1*3
% 1411 2124 3
numTrainFiles = 87; % サンプルに倣うなら各種類の画像枚数の3/4を学習用、1/4を検証用に用いる
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,'randomize');
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
'ColorPreprocessing','rgb2gray'); % 野菜画像のサイズやカラー/モノクロがバラバラでも対応する
augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation, ...
'ColorPreprocessing','rgb2gray'); % 野菜画像のサイズやカラー/モノクロがバラバラでも対応する
% カラーに統一する場合は'ColorPreprocessing','gray2rgb'
% モノクロ(グレースケール画像)に統一する場合は'ColorPreprocessing','rgb2gray'
% 初めから全ての野菜画像がカラーかモノクロに統一されていれば'ColorPreprocessing'オプションは不要
% 例題の様に初めから野菜画像のサイズが全て同一であれば augmentedImageDatastore も不要
layers = [
imageInputLayer(inputSize) % 1枚目の画像のサイズ(カラー/モノクロ含む)を得る
convolution2dLayer(3,8,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer(2,'Stride',2)
convolution2dLayer(3,16,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer(2,'Stride',2)
convolution2dLayer(3,32,'Padding','same')
batchNormalizationLayer
reluLayer
fullyConnectedLayer(height(labelCount)) % 全結合層の OutputSize パラメータ:野菜の分類数に設定する
softmaxLayer
classificationLayer];
options = trainingOptions('sgdm', ...
'InitialLearnRate',0.01, ...
'MaxEpochs',4, ...
'Shuffle','every-epoch', ...
'ValidationData',augimdsValidation, ...
'ValidationFrequency',30, ...
'Verbose',false, ...
'Plots','training-progress');
net = trainNetwork(augimdsTrain,layers,options);
YPred = classify(net,augimdsValidation);
YValidation = imdsValidation.Labels;
accuracy = sum(YPred == YValidation)/numel(YValidation)
  1 Comment
陸
on 31 Oct 2022
ご回答ありがとうございます!!
上記コードで無事実装できました。ありがとうございました。(´;ω;`)

Sign in to comment.

More Answers (1)

Atsushi Ueno
Atsushi Ueno on 26 Oct 2022
imageInputLayer([28 28 1])
このCNNの入力層は28*28のグレースケールイメージを受け付けます。先日の質問と逆の('gray2rgb'でなく'rgb2gray')変換が必要です。
画像のイメージサイズは1411*2124*3ですが
上記エラーメッセージはサイズの大きなRGBカラーイメージを入力しようとしている事を意味します。
先日と同じaugmentedImageDatastore関数で、画像サイズと色のチャネル数を合致させましょう。
augimdsTrain = augmentedImageDatastore([28 28],imdsTrain,'ColorPreprocessing','rgb2gray');
% (中略)
net = trainNetwork(augimdsTrain,layers,options);
  2 Comments
Atsushi Ueno
Atsushi Ueno on 28 Oct 2022
augimdsTrain = augmentedImageDatastore([28 28],imdsTrain, ...
'ColorPreprocessing','rgb2gray');
augimdsValidation = augmentedImageDatastore([28 28],imdsValidation, ...
'ColorPreprocessing','rgb2gray');
% (中略)
%'ValidationData',imdsValidation, ... % 【変更前】
'ValidationData',augimdsValidation, ... % 【変更後】
%net = trainNetwork(imdsTrain,layers,options); % 【変更前】
net = trainNetwork(augimdsTrain,layers,options); % 【変更後】
回答で言っている事を反映するには上記の様な変更が必要ですが、ちょっと自分の勘違いがあるかもしれません。もう一つの回答の方をご確認ください。例題(数字の分類)におけるCNNの入力層サイズと野菜画像のサイズがかけ離れているのでこのまま出はうまく学習されないと思います。
また、そもそもなぜaugmentedImageSource関数の利用を提案したかというと、前の質問においてカラー/モノクロ画像が混在しているおそれがあった為です。野菜の画像が全てカラー/モノクロのいずれかに統一されているのであれば'ColorPreprocessing'オプションの指定は不要ですし、野菜画像のサイズが全て同一であれば augmentedImageSource関数自体も不要になります。

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!