Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

Grad-CAM を使用したセマンティック セグメンテーション ネットワークの調査

この例では、Grad-CAM を使用して事前学習済みのセマンティック セグメンテーション ネットワークの予測を調査する方法を説明します。

セマンティック セグメンテーション ネットワークはイメージ内のすべてのピクセルを分類して、クラスごとにセグメント化されたイメージを作成します。深層学習の可視化手法である Grad-CAM を使用することで、ピクセル分類判定にとってイメージのどの領域が重要かを確認できます。

事前学習済みのネットワークのダウンロード

University of Cambridge の CamVid データ セット [1] で学習させたセマンティック セグメンテーション ネットワークをダウンロードします。セマンティック セグメンテーション ネットワークの構築と学習の詳細については、深層学習を使用したセマンティック セグメンテーション (Deep Learning Toolbox)を参照してください。

pretrainedURL = "https://www.mathworks.com/supportfiles/vision/data/deeplabv3plusResnet18CamVid.mat";
pretrainedFolder = fullfile(tempdir,"pretrainedNetwork");
pretrainedNetwork = fullfile(pretrainedFolder,"deeplabv3plusResnet18CamVid.mat");

if ~exist(pretrainedNetwork,"file")
    mkdir(pretrainedFolder);
    disp("Downloading pretrained network (58 MB)...");
    websave(pretrainedNetwork,pretrainedURL);
end
pretrainedNet = load(pretrainedNetwork); 
net = pretrainedNet.net;

セマンティック セグメンテーションの実行

Grad-CAM を使用してネットワークの予測を解析する前に、事前学習済みのネットワークを使用してテスト イメージをセグメント化します。

テスト イメージを読み込み、ネットワークに必要なサイズに合わせてサイズ変更します。

img = imread('highway.png');
inputSize = net.Layers(1).InputSize(1:2);
img = imresize(img,inputSize);

関数 semanticseg を使用して、イメージのピクセル ラベルを予測します。

predLabels = semanticseg(img,net);

セグメント化した結果を元のイメージに重ね合わせ、結果を表示します。

cmap = camvidColorMap;
segImg = labeloverlay(img,predLabels,Colormap=cmap,Transparency=0.4);

figure
imshow(segImg,InitialMagnification=40)
classes = camvidClasses();
pixelLabelColorbar(cmap,classes)

一部の領域は、このネットワークによって間違って分類されています。たとえば、タイヤの近くの道路が車として誤分類されています。次に、Grad-CAM を使用してネットワークの予測を調査し、ネットワークが特定の領域を誤分類した原因を調べます。

ネットワークの予測の調査

深層ネットワークは複雑であるため、ネットワークがどのようにして特定の予測に至るかを理解するのは困難です。Grad-CAM を使用することで、セマンティック セグメンテーション ネットワークがテスト イメージのどの領域を使用してピクセルを分類したかを確認できます。

Grad-CAM は、選択した層に含まれる畳み込みの特徴について、クラスのスコアなどの微分可能な出力の勾配を計算します。Grad-CAM は、通常、イメージ分類タスク [2] に使用されますが、セマンティック セグメンテーションの問題 [3] に拡張できます。

セマンティック セグメンテーション タスクでは、ネットワークのソフトマックス層が元のイメージに含まれるすべてのピクセルに対する各クラスのスコアを出力します。これは、通常のイメージ分類問題とは対照的です。通常のイメージ分類問題では、ソフトマックス層はイメージ全体に対する各クラスのスコアを出力します。クラス c の Grad-CAM マップは次のようになります。

Mc=ReLU(kαckAk)、ここで αck=1/Ni,jdycdAi,jk

N はピクセルの数、Ak は対象の特徴マップであり、yc はスカラーのクラスのスコアに対応します。シンプルなイメージ分類問題では、yc は対象のクラスに関するソフトマックス スコアです。セマンティック セグメンテーションでは、対象のクラスに対するピクセル単位のクラス スコアをスカラーに変換することで、yc が得られます。たとえば、ソフトマックス層の空間次元を次のように加算します。yc=(i,j)Pyi,jc。ここで、P は、セマンティック セグメンテーション ネットワーク [3] の出力層に含まれるピクセルです。この例では、出力層はピクセル分類層の前にあるソフトマックス層です。マップ Mc は、クラス c の判定に影響を与える領域を強調表示します。イメージ内で値が高い領域は、ピクセル分類判定にとって重要であることを表します。

Grad-CAM を使用するには、特徴マップを抽出する特徴層と、出力活性化を抽出するリダクション層を選択する必要があります。analyzeNetwork を使用して、Grad-CAM を使う層を見つけます。

analyzeNetwork(net)

特徴層を指定します。通常、これは、ネットワークの最後にある畳み込み層の出力を受け取る ReLU 層です。

featureLayer = "dec_relu4";

リダクション層を指定します。関数 gradCAM は、指定したクラスについてリダクション層の空間次元を加算し、スカラー値を生成します。その後、このスカラー値は特徴層の各特徴に対して微分されます。セマンティック セグメンテーションの問題では、通常、リダクション層はソフトマックス層です。

reductionLayer = "softmax-out";

道路と歩道のクラスに関する Grad-CAM マップを計算します。

classes = ["Road" "Car"];

gradCAMMap = gradCAM(net,img,classes, ...
    ReductionLayer=reductionLayer, ...
    FeatureLayer=featureLayer);

この 2 つのクラスに関する Grad-CAM マップを、ネットワークによって予測されたピクセル ラベルと比較します。

figure
subplot(2,2,1)
imshow(img)
title("Test Image")
subplot(2,2,2)
imshow(segImg)
title("Semantic Segmentation")
subplot(2,2,3)
imshow(img)
hold on
imagesc(gradCAMMap(:,:,1),AlphaData=0.5)
title("Grad-CAM: " + classes(1))
colormap jet
subplot(2,2,4)
imshow(img)
hold on
imagesc(gradCAMMap(:,:,2),AlphaData=0.5)
title("Grad-CAM: " + classes(2))
colormap jet

Grad-CAM マップとセマンティック セグメンテーション マップのどちらも同じように強調表示されています。道路のクラスの Grad-CAM マップを見ると、ネットワークの分類判定ではシーンの中央がより重視されていることがわかります。このネットワークは、タイヤと道路の境界の解像度が低いために、車の下部に近い道路の領域を誤分類したと考えられます。

中間層の調査

ネットワークの最後に近い層を使用して計算すると、Grad-CAM マップとセマンティック セグメンテーション マップは同じような結果になります。Grad-CAM を使用すると、学習済みのネットワークに含まれる中間層を調査することもできます。最初の方の層では、ネットワークの最後にある層と比べて、受容野のサイズが小さく、学習する特徴は小さく低レベルになります。

ネットワーク内の連続的な深い層について、Grad-CAM マップを計算します。

layers = ["res5b_relu","catAspp","dec_relu1"];
numLayers = length(layers);

res5b_relu 層はネットワークの中間に位置します。一方、dec_relu1 はネットワークの最後の方に位置します。

車と道路のクラスについて、ネットワークの分類判定を調査します。各層とクラスについて、Grad-CAM マップを計算します。

classes = ["Car" "Road"];
numClasses = length(classes);

gradCAMMaps = [];
for i = 1:numLayers
    gradCAMMaps(:,:,:,i) = gradCAM(net,img,classes, ...
        ReductionLayer=reductionLayer, ...
        FeatureLayer=layers(i));
end

各層とクラスの Grad-CAM マップを表示します。行は各層のマップを表し、ネットワーク内で最初の方にある層から最後にある層の順に並んでいます。

figure;
idx = 1;
for i=1:numLayers
    for j=1:numClasses
        subplot(numLayers,numClasses,idx)
        imshow(img)
        hold on
        imagesc(gradCAMMaps(:,:,j,i),AlphaData=0.5)
        title(sprintf("%s (%s)",classes(j),layers(i)), ...
            Interpreter="none")
        colormap jet
        idx = idx + 1;
    end
end

最後の方にある層は、セグメンテーション マップと非常に似ているマップを生成します。一方で、ネットワーク内の最初の方にある層は、抽象的な結果となります。これらの層では、一般に、セマンティック クラスがほとんど認識されず、縁部などの低レベルの特徴の方が関係します。たとえば、最初の方にある層のマップを見ると、車と道路のどちらのクラスについても空が強調表示されていることがわかります。これは、最初の方にある層では、イメージ内でそのクラスに関係する領域に焦点を当てるものの、その領域が必ずしもそのクラスに属しているとは限らないことを示しています。

参考文献

[1] Brostow, Gabriel J., Julien Fauqueur, and Roberto Cipolla.“Semantic Object Classes in Video: A High-Definition Ground Truth Database.” Pattern Recognition Letters 30, no. 2 (January 2009): 88–97. https://doi.org/10.1016/j.patrec.2008.04.005.

[2] Selvaraju, R. R., M. Cogswell, A. Das, R. Vedantam, D. Parikh, and D. Batra."Grad-CAM:Visual Explanations from Deep Networks via Gradient-Based Localization."In IEEE International Conference on Computer Vision (ICCV), 2017, pp. 618–626. Available at Grad-CAM on the Computer Vision Foundation Open Access website.

[3] Vinogradova, Kira, Alexandr Dibrov, and Gene Myers.“Towards Interpretable Semantic Segmentation via Gradient-Weighted Class Activation Mapping (Student Abstract).”Proceedings of the AAAI Conference on Artificial Intelligence 34, no. 10 (April 3, 2020):13943–44. https://doi.org/10.1609/aaai.v34i10.7244.

サポート関数

function classes = camvidClasses()
% Return the CamVid class names used during network training. 
%
% The CamVid data set has 32 classes. Group them into 11 classes following
% the original SegNet training methodology [1].
%
% The 11 classes are:
%   "Sky", "Building", "Pole", "Road", "Pavement", "Tree", "SignSymbol",
%   "Fence", "Car", "Pedestrian",  and "Bicyclist".
%
classes = [
    "Sky"
    "Building"
    "Pole"
    "Road"
    "Pavement"
    "Tree"
    "SignSymbol"
    "Fence"
    "Car"
    "Pedestrian"
    "Bicyclist"
    ];
end
function pixelLabelColorbar(cmap, classNames)
% Add a colorbar to the current axis. The colorbar is formatted
% to display the class names with the color.

colormap(gca,cmap)

% Add a colorbar to the current figure.
c = colorbar("peer",gca);

% Use class names for tick marks.
c.TickLabels = classNames;
numClasses = size(cmap,1);

% Center tick labels.
c.Ticks = 1/(numClasses*2):1/numClasses:1;

% Remove tick marks.
c.TickLength = 0;
end

function cmap = camvidColorMap
% Define the colormap used by the CamVid data set.

cmap = [
    128 128 128   % Sky
    128 0 0       % Building
    192 192 192   % Pole
    128 64 128    % Road
    60 40 222     % Pavement
    128 128 0     % Tree
    192 128 128   % SignSymbol
    64 64 128     % Fence
    64 0 128      % Car
    64 64 0       % Pedestrian
    0 128 192     % Bicyclist
    ];

% Normalize between [0 1].
cmap = cmap ./ 255;
end