<jupyter_start><jupyter_text>CaptumCaptum is the Model Interpretation Library from PyTorch as available [here](https://captum.ai)To use this we need to install the package using `conda install captum -c pytorch`or `pip install captum`This is a Call back to use Captum.<jupyter_code># export

# Dirty hack as json_clean doesn't support CategoryMap type

from ipykernel import jsonutil

_json_clean=jsonutil.json_clean
def json_clean(o):
    o = list(o.items) if isinstance(o,CategoryMap) else o
    return _json_clean(o)

jsonutil.json_clean = json_clean
#export
from captum.attr import IntegratedGradients
from captum.attr import visualization as viz

from matplotlib.colors import LinearSegmentedColormap


from captum.insights import AttributionVisualizer, Batch
from captum.insights.features import ImageFeature
#export
class IntegradedGradientsCallback(Callback):
    "Captum Callback for Resnet Interpretation"
    def __init__(self):
        pass

    def after_fit(self):
        self.integrated_gradients = IntegratedGradients(self.model)
        
    def visualize(self, inp_data, n_steps=200, cmap_name='custom blue', colors=None, N=256, 
                  methods=None, signs=None, outlier_perc=1):
        if methods is None: methods=['original_image','heat_map']
        if signs is None: signs=["all", "positive"]
        dl = self.dls.test_dl(L(inp_data),with_labels=True, bs=1)
        self.enc_inp,self.enc_preds= dl.one_batch()
        dec_data=dl.decode((self.enc_inp,self.enc_preds))
        self.dec_img,self.dec_pred=dec_data[0][0],dec_data[1][0]
        self.colors = [(0, '#ffffff'),(0.25, '#000000'),(1, '#000000')] if colors is None else colors
        self.attributions_ig = self.integrated_gradients.attribute(self.enc_inp.to(self.dl.device), target=self.enc_preds, n_steps=200)
        default_cmap = LinearSegmentedColormap.from_list(cmap_name, 
                                                 self.colors, N=N)
        _ = viz.visualize_image_attr_multiple(np.transpose(self.attributions_ig.squeeze().cpu().detach().numpy(), (1,2,0)),
                             np.transpose(self.dec_img.numpy(), (1,2,0)),
                             methods=methods,
                             cmap=default_cmap,
                             show_colorbar=True,
                             signs=signs,
                             outlier_perc=outlier_perc, titles=[f'Original Image - ({self.dec_pred})', 'IG'])
from fastai2.vision.all import *
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=42,
    label_func=is_cat, item_tfms=Resize(128))

learn = cnn_learner(dls, resnet34, metrics=error_rate,cbs=IntegradedGradientsCallback())
learn.fine_tune(1)
paths=list(path.iterdir())

learn.integraded_gradients.visualize(paths,n_steps=1000)
#export
class CaptumInsightsCallback(Callback):
    "Captum Insights Callback for Image Interpretation"
    def __init__(self): pass
        
    def _formatted_data_iter(self, dl, normalize_func):
        dl_iter=iter(dl)
        while True:
            images,labels=next(dl_iter)
            images=normalize_func.decode(images).to(dl.device)
            yield Batch(inputs=images, labels=labels)
        
    def visualize(self, inp_data, debug=True):
        _baseline_func= lambda o: o*0
        _get_vocab = lambda vocab: list(map(str,vocab)) if isinstance(vocab[0],bool) else vocab
        dl = self.dls.test_dl(L(inp_data),with_labels=True, bs=4)
        normalize_func= next((func for func in dl.after_batch if type(func)==Normalize),noop)
        
        visualizer = AttributionVisualizer(
            models=[self.model],
            score_func=lambda o: torch.nn.functional.softmax(o, 1),
            classes=_get_vocab(dl.vocab),
            features=[
                ImageFeature(
                    "Image",
                    baseline_transforms=[_baseline_func],
                    input_transforms=[normalize_func],
                )
            ],
            dataset=self._formatted_data_iter(dl,normalize_func)
        )
        visualizer.render(debug=debug)
        
from fastai2.vision.all import *
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=42,
    label_func=is_cat, item_tfms=Resize(128))

learn = cnn_learner(dls, resnet34, metrics=error_rate,cbs=CaptumInsightsCallback())
learn.fine_tune(1)
paths=list(path.iterdir())

learn.captum_insights.visualize(paths)<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup