如何可视化你的CV模型?

2022-09-22 11:35:03 浏览数 (1)

点关注,不迷路,定期更新干货算法笔记~

可视化分析是CV中常用的技巧,通过可视化分析,可以发现模型在学习过程中重点关注了图像中的哪部分区域,帮助我们debug模型学习过程中可能存在的问题。例如在图像分类任务中,可以通过可视化分析,来看模型最关注的图像区域是对于分类至关重要的关键实体,还是背景,进而推断模型目前的学习情况。

那么如何可视化CV模型呢?这里我们介绍两种方法,第一种方法是CAM,一般用于ResNet等以卷积网络为主体的模型;第二种方法是直接绘制Attention Map,可以用于近期比较火的以Transformer为主题结构的ViT等模型中。最后,我们会详细介绍ViT可视化Attention Map的示例和代码,可以比较方便的用于各种分析场景。

1

CAM可视化

当我们通过ResNet等模型结构得到feature map后,可视化的方法就是根据每个feature map的重要性,对各个feature map进行加权融合,进而得到图像中各个位置对于分类重要程度的可视化结果。CAM类的方法是最常用的可视化方法之一。

CAM方法是在Learning Deep Features for Discriminative Localization(CVPR)中被提出的。该方法总共分为以下3个步骤:

  • 首先,获取模型最后一层卷积输出的特征图[W, H, C],其中C是channel维度,也就是特征图的个数,每个特征图是W*H的矩阵。利用Global Average Pooling(GAP)将每一个channel的特征图融合。
  • 然后,利用全连接 softmax根据各个channel的特征图学习分类任务,这样就能通过softmax得到每个channel的权重。对于一个多分类任务,选择正确类别相对于各个channel的softmax打分,作为每个特征图的权重w。
  • 最后,利用学到的权重w对各个channel的特征图加权平均,得到最终的可视化结果,即图像上每个位置的重要性。整个过程如下图所示。

CAM方法的缺陷在于,GAP 全连接这种网络结构并不通用,可能原始模型并没有这种结构。并且CAM只能可视化模型的最后一层。如果希望对结构不同的模型,或者不是最后一层的feature map进行可视化,需要重新训练全连接层,非常不方便。因此,后续Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization(ICCV)提出了一种更通用的可视化方法Grad-CAM。

Grad-CAM是根据梯度计算每个feature map权重的。对于图像分类问题,将目标label对应的梯度回传到要可视化的层的各个feature map,将这个梯度作为每个feature map的权重。这个梯度也会在每个feature map的维度进行Gobal Average Pooling,公式可以表示如下:

2

ViT可视化

随着Transformer在CV领域的应用,ViT最近逐渐成为非常火的图像backbone。ViT将图像分patch转换成序列,输入到Transformer中,并采用和BERT类似的[CLS] token进行分类。[CLS] token汇聚了对分类有帮助的图像中的重要信息。

对于VIT的可视化,非常直观的思路就是直接绘制attention矩阵。例如对于图像分类任务,我们一般关注用于分类的[CLS] token汇聚了哪些patch的信息。因此我们可以绘制每层的[CLS] token和各个patch的attention得分对应的热力图,来分析哪些patch对于分类最重要。

3

ViT可视化示例详解

下面我们通过实际代码来看看ViT是如何实现可视化的。代码来自github:链接,最核心的代码如下:

下面我们解析一下这段可视化代码。

  • 第一步——融合多head结果:需要先获取到ViT每层的[CLS] token对于各个patch的attention打分。一般ViT使用的都是多头注意力机制,这里我们把各个head的attention score求平均作为每层的整体attention。
  • 第二步——考虑残差连接:由于Transformer中,每层之间都有residual connection,直接将上一层的输入和本层的输出加和。这对应于每个位置的token和自己做了一个权重为1的attention。为了把这部分信息体现出来,通过生成一个对角线为1的矩阵,加和到初始的attention score矩阵上,再进行归一化,得到考虑了残差连接的attention打分。
  • 第三步——考虑多层累乘关系,当我们想绘制多层attention矩阵时,各层attention矩阵是有一个传导关系的。第二层Transformer在做attention时,输入是第一层attention加权的结果。为了把这个因素考虑在内,代码中会循环进行attention weight相乘。用上一层累乘的attention矩阵,与当前层直接从模型中获取的attention矩阵相乘,模拟了输入是上一层attention加权融合后的结果。
  • 第四步——插值还原:我们得到的attention map是pacth_size * patch_size的,和原来图像的尺寸肯定是不一样的。我们需要把这个attention矩阵通过插值的方法还原成和图像相同的尺寸,再用这个attention score和图像上对应像素点相乘,得到可视化图像。代码中直接使用了cv2的resize函数,这个函数通过双线性插值的方法将输入矩阵扩大成和原图像相同的尺寸。

最终绘制完成的可视化图像效果如下,可以看到模型对于主体的attention分数更大,对于背景的attention分数更小,表明ViT学到了根据图像主体进行分类。

4

总结

模型可视化是我们在日常分析模型效果的一个重要手段,通过可视化模型对于图像各个部分的关注程度,可以帮助判断模型学的好坏,是否关注了我们希望模型关注的区域,进而针对性进行优化。

END

0 人点赞