特征可视化之CAM

1 介绍

类别激活映射Class Activation Maps(CAM)可用于可视化深度学习模型中间层特征图,它通过高亮输入图像的部分区域(对于模型识别目标的贡献较大),提供了对模型决策效果的直观解释。论文链接:CAM

具体操作:

CAM由两部分加权构成:原图+特征图,其中,特征图是通过:最后一个全连接层的参数与最后输出的特征图对应相乘再相加而成,如下图所示:
在这里插入图片描述

2 基于ConvNeXt可视化代码

import torch
import cv2
import numpy as np
from PIL import Image
import torchvision.transforms as transforms


def draw_feature(model, img_path, save_img_path):
    origin_image = Image.open(img_path)
    input_shape = [224, 224]
    data_transform = transforms.Compose(
        [transforms.Resize(input_shape),
         transforms.ToTensor(),
         transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])

    image = data_transform(origin_image)
    x = torch.unsqueeze(image, dim=0)
    x = model.downsample_layers[0](x)
    x = model.stages[0](x)
    x = model.downsample_layers[1](x)
    x = model.stages[1](x)
    x = model.downsample_layers[2](x)
    x = model.stages[2](x)
    x = model.downsample_layers[3](x)
    out = model.stages[3](x)    # 1×768×7×7
    the_feature = out

    out = model.norm(out.mean([-2, -1]))
    out = model.head(out)
    def extract(g):
        global feature_grad
        feature_grad = g

    pred = torch.argmax(out).item()
    pred_class = out[:, pred]
    the_feature.register_hook(extract)
    pred_class.backward()
    greds = feature_grad
    pooled_grads = torch.nn.functional.adaptive_avg_pool2d(greds, (1, 1))
    pooled_grads = pooled_grads[0]
    print(pooled_grads.shape)
    features = the_feature[0].cpu()
    for i in range(the_feature.shape[1]):
        features[i, ...] *= pooled_grads[i, ...]
    print(features.shape)
    heatmap = features.detach().numpy()
    print(heatmap.shape)
    heatmap = np.mean(heatmap, axis=0)
    print(heatmap.shape)
    heatmap /= np.max(heatmap)

    img = cv2.imread(img_path)
    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
    heatmap = np.uint8(255 * heatmap)
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
    superimposed_img = heatmap * 0.4 + img
    cv2.imwrite(save_img_path, superimposed_img)


if __name__ == '__main__':
    img_path = "images/daisy.jpg"
    model_path = "logs/best_model.pth"
    save_pic_path = "./cam.jpg"
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    model = torch.load(model_path, map_location='cpu')
    model.eval()
    draw_feature(model, img_path, save_pic_path)

可视化效果:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值