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)
可视化效果:
1166

被折叠的 条评论
为什么被折叠?



