在我们使用 CNN 进行图片分类时,模型到底关注的是图像的哪个区域?Grad-CAM 利用卷积网络最后一个特征图的信息,并加权对应的梯度而构建模型分类的热力图,通过该热力图,我们可以清楚地了解哪一块区域对于类别是最重要的。
你在训练神经网络进行图片分类时,有没有想过网络是否就是像人类感知信息一样去理解图像?这个问题很难回答,因为多数情况下深度神经网络都被视作黑箱。我们喂给它输入数据进而得到输出。整个流程如果出现问题很难去调试。尽管预测的已经相当精准,但这并不能说明他们足以和人类感知的方式媲美。
为何会这样?
假设你需要对大象和企鹅进行二分类(我知道这个任务十分简单)。现在你已经获取了数据集,训好了模型并完成部署。这个模型想必是适用于绝大多数数据的,但是总有可能会出现误判。有人可能会把它看作是一个极端情况,但是你觉得对于 CNN 来说,什么时候物体才是明确可辨的?
结合上述内容,显然在图像中,大象常伴着草木出现,企鹅常伴着冰雪出现。所以,实际上模型已经学会了分辨草木与冰雪的颜色/形状,而不是真的学会了按对象分类。
由上文案例知,如颜色通道统计那样的简单图像处理技术,与训练模型是一样的。因为在没有智能的情况下,模型只能依靠颜色辩物。现在你或许会问,如何知道 CNN 究竟在寻找什么?答案就是,Grad-CAM。
加权梯度类激活映射(Grad-CAM)
我们在本篇博客中实现了加权梯度类激活映射。首先,我们要知道这不是唯一的解决方案。原作说,
加权梯度类激活映射 (Grad-CAM) 通过任意目标概念的梯度(比如说类别「狗」的分对数甚至是「狗」这个字),将这些知识传递到最后的卷积层进而产生一张粗略的定位图,用于凸显图像中对于预测相关概念至关重要的区域。
通俗点讲,我们只取最终卷积层的特征图,然后将该特征中的每个通道通过与该通道相关的类的梯度进行加权。这种方法只不过是输入图像如何通过每个通道对于类的重要性来激活不同的通道,最重要的是它不需要对现有架构进行任何重训练或更改。
特定类的特征空间得分就是对应类的输出值 y^c 关于特征图 A_ij 的偏导在 i 和 j 维上的特征进行全局平均池化操作。然后,我们将结果与特征图沿其通道轴 k 相乘。最后,将结果在通道维度 k 上求平均/池化。因此,特征空间的得分凸的大小是 i×j。Σ 符号用于描述池化和平均操作。
ReLU 激活函数用于得分图,随后被归一化以便输出正区域预测。
实现
为了达到本篇博客的目的,我们套用一个预训练好的 VGG 模型,并导入一些必要包开始实现代码。
from keras.applications.vgg16 import VGG16, preprocess_input, decode_predictionsfrom keras.preprocessing import imageimport keras.backend as Kimport numpy as npimport cv2import sys
我们使用 Keras 自带的 VGG16 模型。并加载一些有助于加载和处理图像的函数。
model = VGG16(weights=
领取专属 10元无门槛券
私享最新 技术干货