# 类别激活图(CAM)可视化 ## 类别激活图可视化工具介绍 MMPretrain 提供 `tools/visualization/vis_cam.py` 工具来可视化类别激活图。请使用 `pip install "grad-cam>=1.3.6"` 安装依赖的 [pytorch-grad-cam](https://github.com/jacobgil/pytorch-grad-cam)。 目前支持的方法有: | Method | What it does | | :----------: | :-----------------------------------------------------------------------------------------------: | | GradCAM | 使用平均梯度对 2D 激活进行加权 | | GradCAM++ | 类似 GradCAM,但使用了二阶梯度 | | XGradCAM | 类似 GradCAM,但通过归一化的激活对梯度进行了加权 | | EigenCAM | 使用 2D 激活的第一主成分(无法区分类别,但效果似乎不错) | | EigenGradCAM | 类似 EigenCAM,但支持类别区分,使用了激活 * 梯度的第一主成分,看起来和 GradCAM 差不多,但是更干净 | | LayerCAM | 使用正梯度对激活进行空间加权,对于浅层有更好的效果 | **命令行**: ```bash python tools/visualization/vis_cam.py \ ${IMG} \ ${CONFIG_FILE} \ ${CHECKPOINT} \ [--target-layers ${TARGET-LAYERS}] \ [--preview-model] \ [--method ${METHOD}] \ [--target-category ${TARGET-CATEGORY}] \ [--save-path ${SAVE_PATH}] \ [--vit-like] \ [--num-extra-tokens ${NUM-EXTRA-TOKENS}] [--aug_smooth] \ [--eigen_smooth] \ [--device ${DEVICE}] \ [--cfg-options ${CFG-OPTIONS}] ``` **所有参数的说明**: - `img`:目标图片路径。 - `config`:模型配置文件的路径。 - `checkpoint`:权重路径。 - `--target-layers`:所查看的网络层名称,可输入一个或者多个网络层, 如果不设置,将使用最后一个`block`中的`norm`层。 - `--preview-model`:是否查看模型所有网络层。 - `--method`:类别激活图图可视化的方法,目前支持 `GradCAM`, `GradCAM++`, `XGradCAM`, `EigenCAM`, `EigenGradCAM`, `LayerCAM`,不区分大小写。如果不设置,默认为 `GradCAM`。 - `--target-category`:查看的目标类别,如果不设置,使用模型检测出来的类别做为目标类别。 - `--save-path`:保存的可视化图片的路径,默认不保存。 - `--eigen-smooth`:是否使用主成分降低噪音,默认不开启。 - `--vit-like`: 是否为 `ViT` 类似的 Transformer-based 网络 - `--num-extra-tokens`: `ViT` 类网络的额外的 tokens 通道数,默认使用主干网络的 `num_extra_tokens`。 - `--aug-smooth`:是否使用测试时增强 - `--device`:使用的计算设备,如果不设置,默认为'cpu'。 - `--cfg-options`:对配置文件的修改,参考[学习配置文件](../user_guides/config.md)。 ```{note} 在指定 `--target-layers` 时,如果不知道模型有哪些网络层,可使用命令行添加 `--preview-model` 查看所有网络层名称; ``` ## 如何可视化 CNN 网络的类别激活图(如 ResNet-50) `--target-layers` 在 `Resnet-50` 中的一些示例如下: - `'backbone.layer4'`,表示第四个 `ResLayer` 层的输出。 - `'backbone.layer4.2'` 表示第四个 `ResLayer` 层中第三个 `BottleNeck` 块的输出。 - `'backbone.layer4.2.conv1'` 表示上述 `BottleNeck` 块中 `conv1` 层的输出。 ```{note} 对于 `ModuleList` 或者 `Sequential` 类型的网络层,可以直接使用索引的方式指定子模块。比如 `backbone.layer4[-1]` 和 `backbone.layer4.2` 是相同的,因为 `layer4` 是一个拥有三个子模块的 `Sequential`。 ``` 1. 使用不同方法可视化 `ResNet50`,默认 `target-category` 为模型检测的结果,使用默认推导的 `target-layers`。 ```shell python tools/visualization/vis_cam.py \ demo/bird.JPEG \ configs/resnet/resnet50_8xb32_in1k.py \ https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_batch256_imagenet_20200708-cfb998bf.pth \ --method GradCAM # GradCAM++, XGradCAM, EigenCAM, EigenGradCAM, LayerCAM ``` | Image | GradCAM | GradCAM++ | EigenGradCAM | LayerCAM | | ------------------------------------ | --------------------------------------- | ----------------------------------------- | -------------------------------------------- | ---------------------------------------- | |
|
|
|
|
| 2. 同一张图不同类别的激活图效果图,在 `ImageNet` 数据集中,类别238为 'Greater Swiss Mountain dog',类别281为 'tabby, tabby cat'。 ```shell python tools/visualization/vis_cam.py \ demo/cat-dog.png configs/resnet/resnet50_8xb32_in1k.py \ https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_batch256_imagenet_20200708-cfb998bf.pth \ --target-layers 'backbone.layer4.2' \ --method GradCAM \ --target-category 238 # --target-category 281 ``` | Category | Image | GradCAM | XGradCAM | LayerCAM | | -------- | ---------------------------------------------- | ------------------------------------------------ | ------------------------------------------------- | ------------------------------------------------- | | Dog |
|
|
|
| | Cat |
|
|
|
| 3. 使用 `--eigen-smooth` 以及 `--aug-smooth` 获取更好的可视化效果。 ```shell python tools/visualization/vis_cam.py \ demo/dog.jpg \ configs/mobilenet_v3/mobilenet-v3-large_8xb128_in1k.py \ https://download.openmmlab.com/mmclassification/v0/mobilenet_v3/convert/mobilenet_v3_large-3ea3c186.pth \ --target-layers 'backbone.layer16' \ --method LayerCAM \ --eigen-smooth --aug-smooth ``` | Image | LayerCAM | eigen-smooth | aug-smooth | eigen&aug | | ------------------------------------ | --------------------------------------- | ------------------------------------------- | ----------------------------------------- | ----------------------------------------- | |
|
|
|
|
| ## 如何可视化 Transformer 类型网络的类别激活图 `--target-layers` 在 Transformer-based 网络中的一些示例如下: - Swin-Transformer 中:`'backbone.norm3'` - ViT 中:`'backbone.layers[-1].ln1'` 对于 Transformer-based 的网络,比如 ViT、T2T-ViT 和 Swin-Transformer,特征是被展平的。为了绘制 CAM 图,我们需要指定 `--vit-like` 选项,从而让被展平的特征恢复方形的特征图。 除了特征被展平之外,一些类 ViT 的网络还会添加额外的 tokens。比如 ViT 和 T2T-ViT 中添加了分类 token,DeiT 中还添加了蒸馏 token。在这些网络中,分类计算在最后一个注意力模块之后就已经完成了,分类得分也只和这些额外的 tokens 有关,与特征图无关,也就是说,分类得分对这些特征图的导数为 0。因此,我们不能使用最后一个注意力模块的输出作为 CAM 绘制的目标层。 另外,为了去除这些额外的 toekns 以获得特征图,我们需要知道这些额外 tokens 的数量。MMPretrain 中几乎所有 Transformer-based 的网络都拥有 `num_extra_tokens` 属性。而如果你希望将此工具应用于新的,或者第三方的网络,而且该网络没有指定 `num_extra_tokens` 属性,那么可以使用 `--num-extra-tokens` 参数手动指定其数量。 1. 对 `Swin Transformer` 使用默认 `target-layers` 进行 CAM 可视化: ```shell python tools/visualization/vis_cam.py \ demo/bird.JPEG \ configs/swin_transformer/swin-tiny_16xb64_in1k.py \ https://download.openmmlab.com/mmclassification/v0/swin-transformer/swin_tiny_224_b16x64_300e_imagenet_20210616_090925-66df6be6.pth \ --vit-like ``` 2. 对 `Vision Transformer(ViT)` 进行 CAM 可视化: ```shell python tools/visualization/vis_cam.py \ demo/bird.JPEG \ configs/vision_transformer/vit-base-p16_ft-64xb64_in1k-384.py \ https://download.openmmlab.com/mmclassification/v0/vit/finetune/vit-base-p16_in21k-pre-3rdparty_ft-64xb64_in1k-384_20210928-98e8652b.pth \ --vit-like \ --target-layers 'backbone.layers[-1].ln1' ``` 3. 对 `T2T-ViT` 进行 CAM 可视化: ```shell python tools/visualization/vis_cam.py \ demo/bird.JPEG \ configs/t2t_vit/t2t-vit-t-14_8xb64_in1k.py \ https://download.openmmlab.com/mmclassification/v0/t2t-vit/t2t-vit-t-14_3rdparty_8xb64_in1k_20210928-b7c09b62.pth \ --vit-like \ --target-layers 'backbone.encoder[-1].ln1' ``` | Image | ResNet50 | ViT | Swin | T2T-ViT | | --------------------------------------- | ------------------------------------------ | -------------------------------------- | --------------------------------------- | ------------------------------------------ | |
|
|
|
|
|