Explaining a CNN: Grad-CAM and activations
Grad-CAM
Grad-CAM highlights the parts of the image that pushed the model toward a class.
cam = cu.viz.gradcam(model, x) # x: (1, 3, H, W), as fed to the model
cu.viz.show_cam(x, cam) # input and heatmap overlay side by side
cam.class_idx, cam.scores # which class was explained, its score
cam.layer # which layer was used, e.g. "layer4"
Which class? The predicted one by default; ask for another with
class_idx=3. For a batch, pass one index per image.Which layer? The last layer that still has a spatial map, found automatically (
layer4for torchvision ResNets, the body for fastaivision_learner). Choose another withtarget_layer="layer3".Normalized input? Pass
mean=cu.viz.IMAGENET_MEAN, std=cu.viz.IMAGENET_STDtoshow_camso the image underneath looks natural.Reading the colors. A color bar next to the overlay maps colors to importance from 0 (ignored) to 1 (most important); the map is scaled per image. Hide it with
show_color_bar=False.
With fastai:
x = cu.viz.learner_input(learn, "cat.jpg") # same transforms as training
cam = cu.viz.gradcam(learn, x)
cu.viz.show_cam(x, cam, mean=cu.viz.IMAGENET_MEAN, std=cu.viz.IMAGENET_STD)
Other CAM methods
After cu.install("cam"), choose a method from
pytorch-grad-cam:
cu.viz.gradcam(model, x, method="gradcam++")
# also: "xgradcam", "hirescam", "layercam", "scorecam", "eigencam", "ablationcam"
Layer activations
cu.viz.layer_names(model, torch.nn.Conv2d) # what can I look at?
acts = cu.viz.activations(model, x, layers=["layer1", "layer3"])
acts["layer1"].shape # (1, 64, 56, 56)
cu.viz.show_feature_maps(acts["layer1"], n=16) # first 16 channels
Early layers respond to edges and colours; later layers to textures and parts.
None of these functions change your model: training mode, BatchNorm statistics, and parameter gradients are left exactly as they were.