이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
畳み込みニューラルネットワークを用いた画像判別について
조회 수: 1 (최근 30일)
이전 댓글 표시
MATLAB初心者です。畳み込みニューラルネットワークを使って学習データと評価データを使い、画像の判別を行い、その後、分割交差検証を使って、過学習を防ぐようにしたいです。また、その判別をしたモデルを使って、学習データと評価データで使った画像とは別の画像の判別を行いたいと考えています。
何かいい方法はないでしょうか。
よろしくお願いいたします。
채택된 답변
Kenta
2020년 1월 28일
こんにちは、こちらで試したわけではないので不確かなのですが、たとえば、functionのなかで、netができたあとに
save net net
などで、そのネットワークを保存すればそのディレクトリにnetが保存される気がします。ただ、
n回するうちに上書きされるので、最後のnetが保存されることになると思います。
そして、畳み込みニューラルネットワークによる画像分類であれば基本的にgrad-camも可能であると思います。
댓글 수: 10
Kaneko
2020년 1월 28일
ありがとうございます。別の画像の判別はできましたが、以下のようなエラーが出て、grad-camが実行されませんでした。
どこがいけないのか教えて頂けますでしょうか。
よろしくお願いいたします。
エラー:
nnet.internal.cnn.dlnetwork>iAssertLayerNameExist (line
453)
層 'relu5' は存在しません。
エラー: nnet.internal.cnn.dlnetwork>iGetOutputIndices
(line 431)
iAssertLayerNameExist(layerName, map);
エラー:
nnet.internal.cnn.dlnetwork>@(l)iGetOutputIndices(l,layerNameMap,layers)
(line 171)
[outputLayerIdx, outputLayerPortIdx] =
cellfun( @(l)iGetOutputIndices(l,
layerNameMap, layers), outputNames );
エラー:
nnet.internal.cnn.dlnetwork/getOutputLayersIndicesFromNames
(line 171)
[outputLayerIdx, outputLayerPortIdx] =
cellfun( @(l)iGetOutputIndices(l,
layerNameMap, layers), outputNames );
エラー: dlnetwork/parseForwardMethodsNameValuePairs
(line 246)
[layerIndices, layerOutputIndices] =
getOutputLayersIndicesFromNames(this.PrivateNetwork,
outputNames);
エラー: dlnetwork/predict (line 204)
[layerIndices, layerOutputIndices] =
net.parseForwardMethodsNameValuePairs(varargin{:});
エラー: kasika>Gradient_function (line 36)
[scores,conv_output] = predict(net0, I2, 'Outputs',
{softmaxlayer, activationlayer}); % 予測確率とMAPを作る層
までの出力を得る
エラー: deep.internal.dlfeval (line 18)
[varargout{1:nout}] = fun(x{:});
エラー: dlfeval (line 40)
[varargout{1:nout}] =
deep.internal.dlfeval(fun,varargin{:});
エラー: kasika (line 22)
[conv_output,gradients] = dlfeval(@Gradient_function,net0,img2,softmaxlayer,activationlayer,class);
load('net10.mat')
%% Autodiffにかけられるようにdlnetworkに変更
lgraph = layerGraph(net10.Layers); %
Outputlayer = lgraph.Layers(end);
newlgraph = removeLayers(lgraph,lgraph.Layers(end).Name); % calssificationの層だけ取る
net0 = dlnetwork(newlgraph); % dlnetworkに変更
softmaxlayer = 'softmax' ; % 予測確率が出てくる最後のレイヤを指定
activationlayer = 'relu5'; % MAPを適用するレイヤを指定
%% 画像の読み込み
labeltbl = {'sioaritest';'sionasitest'};
colortbl = [255 255 102; 73 6 248];
img = imread(fullfile('houdentestdata','sionasitest','houden_190807_0005 (35).jpg'));% 画像の取り込み
img = imresize(img,[150 200]); % ネットワークと同じサイズに変更
[class,score] = classify(net,img); % 推論
class
max(score)
img2 = dlarray(single(img),'SSC');
% 指定レイヤの出力とGradientをとる
[conv_output,gradients] = dlfeval(@Gradient_function,net0,img2,softmaxlayer,activationlayer,class);
% 得られた出力から演算でヒートマップを作製
gradcam = sum(conv_output .* mean(gradients, [1 2]), 3); % GradientのGlobal average poolingし出力とかけ和をとる
gradcam = extractdata(gradcam); % single型で取り出し。
gradcam = max(gradcam,0); % relu関数を適用
gradcam = imresize(gradcam, [150 200], 'Method', 'bicubic'); % 画像サイズに合わせる
HeatMap = map2jpg(gradcam, [150 200], 'jet'); % ヒートマップ表示の画像データに変換する
HeatMap = uint8((im2double(img)*0.3+HeatMap*0.5)*255); % 元画像と重ね合わせる
out2 = [img HeatMap]; % 元画像と結果を横方向に結合する
imshow(out2);shg
%%
function [conv_output,gradients] = Gradient_function(net0,I2,softmaxlayer,activationlayer,class)
[scores,conv_output] = predict(net0, I2, 'Outputs', {softmaxlayer, activationlayer}); % 予測確率とMAPを作る層までの出力を得る
loss = scores(class); % 指定したクラスのスコアをとる
gradients = dlgradient(loss,conv_output); % MAPを作る層でのgradientをとる
gradients = gradients / (sqrt(mean(gradients.^2,'all')) + 1e-5); % 正規化する
end
% ヒートマップに変換する関数
function img = map2jpg(imgmap, range, colorMap)
imgmap = double(imgmap);
if(~exist('range', 'var') || isempty(range))
range = [min(imgmap(:)) max(imgmap(:))];
end
heatmap_gray = mat2gray(imgmap, range);
heatmap_x = gray2ind(heatmap_gray, 256);
heatmap_x(isnan(imgmap)) = 0;
if(~exist('colorMap', 'var'))
img = ind2rgb(heatmap_x, jet(256));
else
img = ind2rgb(heatmap_x, eval([colorMap '(256)']));
end
end
%%
% _Copyright 2018-2019 The MathWorks, Inc._
Kenta
2020년 1월 28일
こんにちは、解決し、よかったです。
grad-camのほうですが、エラーは「層 'relu5' は存在しません」と書いていますね。
ということはお使いになられているCNNに、その名前をもつ層がないということではないでしょうか。
grad-camで参照したい特徴マップの直前のrelu層を取り出すと思いますが、それの名前を探してみてはいかがでしょうか。
analyzenetworkでネットワークを見れるので、あとは、変数netをクリックして調べたりすれば、ターゲットとなるrelu層が見つかると思います。その名前を指定すれば良いと思います。
ただ、お使いになられているCNNの構造を知りませんので、これを解決してもさらなるエラーがでるかもしれません。
Kaneko
2020년 1월 29일
回答ありがとうございます。relu5についてですが、学習済みネットワークであるalexnetのものでした。いろいろと、ネットにあるサンプルコードを使っていった結果、alexnetを使ってないから、relu5が存在しません、と出てしまったと考えられます。
交差検証のコードに、alexnetを使えば、この問題は解決すると思いますが、以下のコードに、alexnetを入れることは可能でしょうか。よろしくお願いいたします。
imds = imageDatastore('houdenmatlab1', ...
'IncludeSubfolders',true, ...
'LabelSource','foldernames');
figure;
perm = randperm(200,20);
for i = 1:20
subplot(4,5,i);
imshow(imds.Files{perm(i)});
end
labelCount = countEachLabel(imds)
img = readimage(imds,1);
size(img)
numTrainFiles = 80;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,'randomize');
%% ダミーのトレーニングインデックスを生成
X = (1:imds.numpartitions)';
y = imds.Labels;
%% 交差検定にCNNの予測ラベル関数のポインタを渡す
cp = cvpartition(y,'k',10); % Stratified cross-validation
mcr = crossval('mcr',X,y,'Predfun',@(xtrain,ytrain,xtest)myCNNPredict(xtrain,ytrain,xtest,imds),'partition',cp)
%% CNNを学習し、予測ラベルを出力する関数
function ypred = myCNNPredict(xtrain,ytrain,xtest,imds)
% 結果が一意になるように乱数シードをデフォルト値に設定
rng('default');
% ダミーの変数ベクトルを受けてimageDatastoreを学習用とテスト用に分割
imdsTrain = imageDatastore(imds.Files(xtrain));
imdsTrain.Labels = ytrain;
imdsValidation = imageDatastore(imds.Files(xtest));
layers = [
imageInputLayer([150 200 3])
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(2)
softmaxLayer
classificationLayer];
options = trainingOptions('sgdm', ...
'InitialLearnRate',0.01, ...
'MaxEpochs',5, ...
'Shuffle','every-epoch', ...
'Verbose',false);
net10 = trainNetwork(imdsTrain,layers,options);
ypred = classify(net10,imdsValidation);
save net10
end
Kenta
2020년 1월 29일
こんにちは、
「ネットにあるサンプルコードを使っていった結果、alexnetを使ってないから、relu5が存在しません、と出てしまったと考えられます」はい、そうですね、私もそうだと思います。
コードも共有いただきありがとうございます。
自分で定義したCNNを使っていたんですね。はい、alexnetにもできます。
layers...のところを削除します。あらかじめ、load alexnetでロードしておき、
自分のクラス数にあうように適宜、レイヤーを入れ替えます。これはコードでもできますし、deepnetworkdesignerでもできます。
そして、functionの引数にalexnetも含めるようにして、つまり
function ypred = myCNNPredict(xtrain,ytrain,xtest,imds,layers)
とすれば動くと思います。「MATLAB初心者です」とのことですが、いきなりだと少し難しいかもしれませんね...
Kaneko
2020년 1월 30일
回答ありがとうございます。上記のコードのlayers...をdeepnetworkdesignerを使って、leyer_1として作成しました。以下のようにやってみたのですが、mcr = crossval('mcr',X,y,'Predfun',@(xtrain,ytrain,xtest)myCNNPredict(xtrain,ytrain,xtest,imds),'partition',cp)の部分で入力引数が不足しています。と出てしまいましたがどういう事か分かりません。
よろしくお願いいたします。
load layer_1
imds = imageDatastore('houdenmatlab1', ...
'IncludeSubfolders',true, ...
'LabelSource','foldernames');
figure;
perm = randperm(200,20);
for i = 1:20
subplot(4,5,i);
imshow(imds.Files{perm(i)});
end
labelCount = countEachLabel(imds)
img = readimage(imds,1);
size(img)
numTrainFiles = 80;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,'randomize');
%% ダミーのトレーニングインデックスを生成
X = (1:imds.numpartitions)';
y = imds.Labels;
%% 交差検定にCNNの予測ラベル関数のポインタを渡す
cp = cvpartition(y,'k',10); % Stratified cross-validation
mcr = crossval('mcr',X,y,'Predfun',@(xtrain,ytrain,xtest)myCNNPredict(xtrain,ytrain,xtest,imds),'partition',cp)
%% CNNを学習し、予測ラベルを出力する関数
function ypred = myCNNPredict(xtrain,ytrain,xtest,imds,layers)
% 結果が一意になるように乱数シードをデフォルト値に設定
rng('default');
% ダミーの変数ベクトルを受けてimageDatastoreを学習用とテスト用に分割
imdsTrain = imageDatastore(imds.Files(xtrain));
imdsTrain.Labels = ytrain;
imdsValidation = imageDatastore(imds.Files(xtest));
options = trainingOptions('sgdm', ...
'InitialLearnRate',0.01, ...
'MaxEpochs',5, ...
'Shuffle','every-epoch', ...
'Verbose',false);
net10 = trainNetwork(imdsTrain,layers,options);
ypred = classify(net10,imdsValidation);
save net10
end
Kaneko
2020년 1월 31일
편집: Kaneko
2020년 1월 31일
すみません、もう一つ質問よろしいでしょうか。以下のコードで誤分類率を出すことはできたのですが、保存した、net2をディープラーニング評価キットのD2_2_3_mygradcam_alexnet.mを使って、別の画像を判別してみたのですが、どの画像を判別しても、同じ方に判別されてしまい、ans = signal 1(100%)となってしまいます。また、ヒートマップも画像のように判別要因がでないというような状態です。
何度も質問してしまい、申し訳ございません。よろしくお願いいたします。

load net2
%% Autodiffにかけられるようにdlnetworkに変更
lgraph = layerGraph(net2.Layers); %
Outputlayer = lgraph.Layers(end);
newlgraph = removeLayers(lgraph,lgraph.Layers(end).Name); % calssificationの層だけ取る
net0 = dlnetwork(newlgraph); % dlnetworkに変更
softmaxlayer = 'softmax' ; % 予測確率が出てくる最後のレイヤを指定
activationlayer = 'relu3'; % MAPを適用するレイヤを指定
%% 画像の読み込み
labeltbl = {'sioaritest';'sionasitest'};
colortbl = [255 255 102; 73 6 248];
img = imread(fullfile('houdentestdata','sionasitest','houden_190807_0005 (1).jpg'));% 画像の取り込み
img = imresize(img,[150 200]); % ネットワークと同じサイズに変更
[class,score] = classify(net2,img); % 推論
class
max(score)
img2 = dlarray(single(img),'SSC');
% 指定レイヤの出力とGradientをとる
[conv_output,gradients] = dlfeval(@Gradient_function,net0,img2,softmaxlayer,activationlayer,class);
% 得られた出力から演算でヒートマップを作製
gradcam = sum(conv_output .* mean(gradients, [1 2]), 3); % GradientのGlobal average poolingし出力とかけ和をとる
gradcam = extractdata(gradcam); % single型で取り出し。
gradcam = max(gradcam,0); % relu関数を適用
gradcam = imresize(gradcam, [150 200], 'Method', 'bicubic'); % 画像サイズに合わせる
HeatMap = map2jpg(gradcam, [150 200], 'jet'); % ヒートマップ表示の画像データに変換する
HeatMap = uint8((im2double(img)*0.3+HeatMap*0.5)*255); % 元画像と重ね合わせる
out2 = [img HeatMap]; % 元画像と結果を横方向に結合する
imshow(out2);shg
%%
function [conv_output,gradients] = Gradient_function(net0,I2,softmaxlayer,activationlayer,class)
[scores,conv_output] = predict(net0, I2, 'Outputs', {softmaxlayer, activationlayer}); % 予測確率とMAPを作る層までの出力を得る
loss = scores(class); % 指定したクラスのスコアをとる
gradients = dlgradient(loss,conv_output); % MAPを作る層でのgradientをとる
gradients = gradients / (sqrt(mean(gradients.^2,'all')) + 1e-5); % 正規化する
end
% ヒートマップに変換する関数
function img = map2jpg(imgmap, range, colorMap)
imgmap = double(imgmap);
if(~exist('range', 'var') || isempty(range))
range = [min(imgmap(:)) max(imgmap(:))];
end
heatmap_gray = mat2gray(imgmap, range);
heatmap_x = gray2ind(heatmap_gray, 256);
heatmap_x(isnan(imgmap)) = 0;
if(~exist('colorMap', 'var'))
img = ind2rgb(heatmap_x, jet(256));
else
img = ind2rgb(heatmap_x, eval([colorMap '(256)']));
end
end
%%
% _Copyright 2018-2019 The MathWorks, Inc._
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Deep Learning Toolbox에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)