主要内容

使用类激活映射研究网络预测

这个例子展示了如何使用类激活映射(CAM)来研究和解释用于图像分类的深度卷积神经网络的预测。

深度学习网络通常被认为是“黑盒子”,无法弄清楚网络学到了什么,或者网络输入的哪一部分负责网络的预测。当这些模型失败并给出错误的预测时,它们通常会在没有任何警告或解释的情况下失败。类激活映射[1]是一种可以用来对卷积神经网络的预测进行可视化解释的技术。不正确的,看起来不合理的预测往往有合理的解释。使用类激活映射,您可以检查输入图像的特定部分是否“混淆”了网络并导致它做出错误的预测。

您可以使用类激活映射来识别训练集中的偏差,并提高模型的准确性。如果您发现网络基于错误的特征进行预测,那么您可以通过收集更好的数据使网络更加健壮。例如,假设您训练一个网络来区分猫和狗的图像。该网络在训练集上具有很高的准确性,但在现实例子中表现不佳。通过在训练示例上使用类激活映射,您会发现网络的预测不是基于图像中的猫和狗,而是基于背景。然后你意识到你所有的猫的照片都是红色的背景,你所有的狗的照片都是绿色的背景,这是网络在训练中学到的背景颜色。然后,您可以收集新的数据,没有这种偏见。

这个示例类激活映射显示了输入图像的哪些区域对预测类贡献最大鼠标.红色区域贡献最大。

加载预训练网络和网络摄像头

加载预先训练的卷积神经网络进行图像分类。SqueezeNet、GoogLeNet、ResNet-18和MobileNet-v2是相对较快的网络。SqueezeNet是最快的网络,它的类激活映射比其他网络的映射分辨率高4倍。对于在网络末端有多个完全连接层的网络,如AlexNet、VGG-16和VGG-19,不能使用类激活映射。

网络=“squeezenet”;网= eval(网络);

创建一个网络摄像头对象并连接到您的网络摄像头。

相机=摄像头;

提取图像的输入大小和网络的输出类。的activationLayerName在本例末尾定义的Helper函数返回要从中提取激活的层的名称。这一层是在网络的最后一个卷积层之后的ReLU层。

inputSize = net.Layers (1) .InputSize (1:2);类= net.Layers . class(结束);layerName = activationLayerName(网络);

显示类激活映射

创建一个图形并在循环中执行类激活映射。若要终止循环的执行,请关闭图。

h =图(“单位”,“归一化”,“位置”,[0.05 0.05 0.9 0.8],“可见”,“上”);ishandle (h)

用网络摄像头拍一张快照。调整图像的大小,使其最短边的长度(在本例中为图像高度)等于网络的图像输入大小。在调整大小时,请保留图像的纵横比。您还可以将图像的大小调整为较大或较小的大小。使图像变大会增加最终类激活映射的分辨率,但会导致整体预测不太准确。

计算在网络的最后一个卷积层之后的ReLU层中调整大小的图像的激活。

我=快照(相机);imresize = imresize(im,[inputSize(1), NaN]);imageActivations =激活(网,imResized, layerName);

特定类的类激活映射是在最终卷积层之后的ReLU层的激活映射,由每个激活对该类最终得分的贡献度进行加权。这些权重等于该类的网络最终完全连接层的权重。SqueezeNet没有最终的完全连接层。相反,在最后一个卷积层之后的ReLU层的输出已经是类激活映射。

可以为任何输出类生成类激活映射。例如,如果网络做出了错误的分类,您可以比较真实类和预测类的类激活映射。对于本例,为分数最高的预测班级生成班级激活映射。

scores = squeeze(mean(imageactivation,[1 2]));如果网络~ =“squeezenet”fcWeights = net.Layers (end-2) .Weights;fcBias = net.Layers (end-2) .Bias;scores = fcWeights*scores + fcBias;[~, classIds] = maxk(分数,3);weightVector = shiftdim (fcWeights (classIds (1):), 1);classActivationMap = (imageActivations。* weightVector, 3)总和;其他的[~, classIds] = maxk(分数,3);classActivationMap = imageActivations (:,:, classIds (1));结束

计算最高的类标签和最终的规范化类分数。

成绩= exp(分数)/笔(exp(分数));maxScores =分数(classIds);标签=类(classIds);

绘制类激活图。在第一个副图中显示原始图像。在第二个子图中,使用CAMshowHelper函数,该函数在本例的末尾定义,用于在原始图像的暗灰度版本上显示类激活映射。显示前三个预测标签及其预测分数。

subplot(1,2,1) imshow(im) subplot(1,2,2) CAMshow(im,classActivationMap) title(字符串(标签)+”、“+字符串(maxScores));drawnow结束

清除摄像头对象。

清晰的相机

例子地图

网络正确地识别出这张照片中的物体是一个乐福鞋(一种鞋)。右边图像中的类激活映射显示了输入图像的每个区域对预测类的贡献游手好闲的人.红色区域贡献最大。该网络基于整个鞋子进行分类,但最强的输入来自红色区域——也就是鞋尖和鞋口。

网络将这张图片归类为老鼠。正如类激活映射所示,预测不仅基于图像中的鼠标,而且基于键盘。因为训练集的键盘旁边可能有许多老鼠的图像,网络预测包含键盘的图像更有可能包含老鼠。

网络将这张咖啡杯的图片归类为一个扣。如类激活映射所示,由于图像包含太多混淆对象,网络对图像进行了错误分类。网络检测并聚焦在腕带上,而不是咖啡杯上。

辅助函数

CAMshow (im,凸轮)覆盖类激活映射凸轮在暗的,灰度版本的图像上即时通讯.函数将类激活映射的大小调整为即时通讯,将其规范化,从下面设置阈值,并使用飞机colormap。

函数CAMshow(im,CAM) imSize = size(im);(凸轮凸轮= imresize imSize (1:2));凸轮= normalizeImage (CAM);凸轮(凸轮< 0.2)= 0;提出=喷气(255)。* linspace (1255 0) ';凸轮= ind2rgb (uint8(凸轮* 255),提出)* 255;combinedImage = double(rgb2gray(im))/2 + CAM;combinedImage = normalizeImage (combinedImage) * 255;imshow (uint8 (combinedImage));结束函数N = normalizeImage(I) minimum = min(I(:));最大= max(我(:));N = (I-minimum) /(最大最小);结束函数layerName = activationLayerName(网络)如果网络= =“squeezenet”layerName =“relu_conv10”elseif网络= =“googlenet”layerName =“inception_5b-output”elseif网络= =“resnet18”layerName =“res5b_relu”elseif网络= =“mobilenetv2”layerName =“out_relu”结束结束

参考文献

[1]周,Bolei, Aditya Khosla, Agata Lapedriza, Aude Oliva和Antonio Torralba。"学习辨别定位的深度特征"在IEEE计算机视觉与模式识别会议论文集, 2921 - 2929页。2016.

另请参阅

||||

相关的话题

Baidu
map