交差検証を用いた誤分類率の検証について

1 view (last 30 days)
Kaneko
Kaneko on 31 Jan 2020
Commented: Kenta on 8 May 2020
交差検証を行おうとした結果、以下のようなエラーが出ました。
関数 '@(xtrain,ytrain,xtest)myCNNPredict(xtrain,ytrain,xtest,imds)' により次のエラーが発生しました:
'WindowChannelSize' の値は無効です。 入力 は以下のいずれかのタイプが必要です:
double, single, uint8, uint16, uint32, uint64, int8, int16, int32, int64
エラー: crossval>getLossVal (line 525)
funResult = evalFun(funorStr,arg(1:end-1));
エラー: crossval (line 424)
[funResult,outarg] = getLossVal(i, nData, cvp, data, predfun);
エラー: crosval2 (line 20)
mcr = crossval('mcr',X,y,'Predfun',@(xtrain,ytrain,xtest)myCNNPredict(xtrain,ytrain,xtest,imds),'partition',cp)
以下のコードを実行したのですが、エラーが、どういう意味なのか教えて頂けますでしょうか。
また、解決方法があれば教えて頂けますでしょうか。
よろしくお願いいたします。
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',3); % 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],'Name','input')
convolution2dLayer(3,8,'Padding','same','Name','conv1')
batchNormalizationLayer('Name','BN1')
reluLayer('Name','relu1')
maxPooling2dLayer(2,'Stride',2,'Name','pool1')
convolution2dLayer(3,16,'Padding','same','Name','conv2')
batchNormalizationLayer('Name','BN2')
reluLayer('Name','relu2')
maxPooling2dLayer(2,'Stride',2,'Name','pool2')
convolution2dLayer(3,32,'Padding','same','Name','conv3')
batchNormalizationLayer('Name','BN3')
reluLayer('Name','relu3')
fullyConnectedLayer(2,'Name','fc')
softmaxLayer('Name','softmax')
classificationLayer('Name','classoutput')];
options = trainingOptions('sgdm', ...
'InitialLearnRate',0.01, ...
'MaxEpochs',100, ...
'Shuffle','every-epoch', ...
'Verbose',false);
net3 = trainNetwork(imdsTrain,layers,options);
ypred = classify(net3,imdsValidation);
save net3
end
  1 Comment
Kenta
Kenta on 8 May 2020
私の回答に補足ですが、交差検証をしている例はここにありました。参考になれば幸いです。

Sign in to comment.

Accepted Answer

Kenta
Kenta on 1 Feb 2020
こんにちは、上のコメントでの対応で解決したようなので、こちらを回答とさせてください。
例えば、下のようにすれば、layersに関するエラーは回避できます。
crossChannelNormalizationLayerはチャンネルサイズをはじめに定義しないといけないですが、
それが抜けているのでエラーを返しています。
dropout層も少し間違っていたので訂正しています。
layers = [
imageInputLayer([150 200 3],'Name','input')
convolution2dLayer(3,8,'Padding','same','Name','conv1')
batchNormalizationLayer('Name','BN1')
reluLayer('Name','relu1')
crossChannelNormalizationLayer(5)
maxPooling2dLayer(2,'Stride',2,'Name','pool1')
convolution2dLayer(3,16,'Padding','same','Name','conv2')
batchNormalizationLayer('Name','BN2')
reluLayer('Name','relu2')
crossChannelNormalizationLayer(5)
maxPooling2dLayer(2,'Stride',2,'Name','pool2')
convolution2dLayer(3,32,'Padding','same','Name','conv3')
batchNormalizationLayer('Name','BN3')
reluLayer('Name','relu3')
dropoutLayer('probability',0.5,'Name','drop6')
fullyConnectedLayer(2,'Name','fc')
softmaxLayer('Name','softmax')
classificationLayer('Name','classoutput')];

More Answers (1)

Hiro Yoshino
Hiro Yoshino on 31 Jan 2020
Breakpointを使って、どこでエラーが発生しているか調べられますか?
  3 Comments
Kenta
Kenta on 31 Jan 2020
例えば、下のようにすれば、layersに関するエラーは回避できます。
crossChannelNormalizationLayerはチャンネルサイズをはじめに定義しないといけないですが、
それが抜けているのでエラーを返しています。
dropout層も少し間違っていたので訂正しています。
layers = [
imageInputLayer([150 200 3],'Name','input')
convolution2dLayer(3,8,'Padding','same','Name','conv1')
batchNormalizationLayer('Name','BN1')
reluLayer('Name','relu1')
crossChannelNormalizationLayer(5)
maxPooling2dLayer(2,'Stride',2,'Name','pool1')
convolution2dLayer(3,16,'Padding','same','Name','conv2')
batchNormalizationLayer('Name','BN2')
reluLayer('Name','relu2')
crossChannelNormalizationLayer(5)
maxPooling2dLayer(2,'Stride',2,'Name','pool2')
convolution2dLayer(3,32,'Padding','same','Name','conv3')
batchNormalizationLayer('Name','BN3')
reluLayer('Name','relu3')
dropoutLayer('probability',0.5,'Name','drop6')
fullyConnectedLayer(2,'Name','fc')
softmaxLayer('Name','softmax')
classificationLayer('Name','classoutput')];
Kaneko
Kaneko on 31 Jan 2020
ありがとうございます。おかげさまで誤分類率を出すことができました。
それともう一つ質問なのですが、その誤分類率を出した後、学習したネットワークを保存し、以下のコードを使ってgrad-camを用いて、別の画像の判別を行ったのですが、どの画像を判別しても、同じ方に判別されてしまい、ans = signal 1(100%)となってしまいます。また、ヒートマップも画像のように判別要因がでないというような状態です。
そもそも、誤分類率を出したコードでは、grad-camを使っての判別は不可能なのでしょうか。
よろしくお願いいたします。
ちなみに、以下のコードは、ディープラーニング評価キットD2_2_3_mygradcam_alexnet.mを参考にしています。
untitled.jpg
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._

Sign in to comment.

Categories

Find more on イメージを使用した深層学習 in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!