#hide ! [ -e /content ] && pip install -Uqq fastbook import fastbook fastbook.setup_book() #hide from fastbook import * [[chapter_cam]] path = untar_data(URLs.PETS)/'images' def is_cat(x): return x[0].isupper() dls = ImageDataLoaders.from_name_func( path, get_image_files(path), valid_pct=0.2, seed=21, label_func=is_cat, item_tfms=Resize(224)) learn = vision_learner(dls, resnet34, metrics=error_rate) learn.fine_tune(1) img = PILImage.create(image_cat()) x, = first(dls.test_dl([img])) class Hook(): def hook_func(self, m, i, o): self.stored = o.detach().clone() hook_output = Hook() hook = learn.model[0].register_forward_hook(hook_output.hook_func) with torch.no_grad(): output = learn.model.eval()(x) act = hook_output.stored[0] F.softmax(output, dim=-1) dls.vocab x.shape cam_map = torch.einsum('ck,kij->cij', learn.model[1][-1].weight, act) cam_map.shape x_dec = TensorImage(dls.train.decode((x,))[0][0]) _,ax = plt.subplots() x_dec.show(ctx=ax) ax.imshow(cam_map[1].detach().cpu(), alpha=0.6, extent=(0,224,224,0), interpolation='bilinear', cmap='magma'); hook.remove() class Hook(): def __init__(self, m): self.hook = m.register_forward_hook(self.hook_func) def hook_func(self, m, i, o): self.stored = o.detach().clone() def __enter__(self, *args): return self def __exit__(self, *args): self.hook.remove() with Hook(learn.model[0]) as hook: with torch.no_grad(): output = learn.model.eval()(x.cuda()) act = hook.stored class HookBwd(): def __init__(self, m): self.hook = m.register_backward_hook(self.hook_func) def hook_func(self, m, gi, go): self.stored = go[0].detach().clone() def __enter__(self, *args): return self def __exit__(self, *args): self.hook.remove() cls = 1 with HookBwd(learn.model[0]) as hookg: with Hook(learn.model[0]) as hook: output = learn.model.eval()(x.cuda()) act = hook.stored output[0,cls].backward() grad = hookg.stored w = grad[0].mean(dim=[1,2], keepdim=True) cam_map = (w * act[0]).sum(0) _,ax = plt.subplots() x_dec.show(ctx=ax) ax.imshow(cam_map.detach().cpu(), alpha=0.6, extent=(0,224,224,0), interpolation='bilinear', cmap='magma'); with HookBwd(learn.model[0][-2]) as hookg: with Hook(learn.model[0][-2]) as hook: output = learn.model.eval()(x.cuda()) act = hook.stored output[0,cls].backward() grad = hookg.stored w = grad[0].mean(dim=[1,2], keepdim=True) cam_map = (w * act[0]).sum(0) _,ax = plt.subplots() x_dec.show(ctx=ax) ax.imshow(cam_map.detach().cpu(), alpha=0.6, extent=(0,224,224,0), interpolation='bilinear', cmap='magma');