class_docstr: This class computes the occlusion sensitivity for a model's prediction of a given image. By occlusion sensitivity,
  we mean how the probability of a given prediction changes as the occluded section of an image changes. This can be
  useful to understand why a network is making certain decisions.
  
  As important parts of the image are occluded, the probability of classifying the image correctly will decrease.
  Hence, more negative values imply the corresponding occluded volume was more important in the decision process.
  
  Two ``torch.Tensor`` will be returned by the ``__call__`` method: an occlusion map and an image of the most probable
  class. Both images will be cropped if a bounding box used, but voxel sizes will always match the input.
  
  The occlusion map shows the inference probabilities when the corresponding part of the image is occluded. Hence,
  more -ve values imply that region was important in the decision process. The map will have shape ``BCHW(D)N``,
  where ``N`` is the number of classes to be inferred by the network. Hence, the occlusion for class ``i`` can
  be seen with ``map[...,i]``.
  
  The most probable class is an image of the probable class when the corresponding part of the image is occluded
  (equivalent to ``occ_map.argmax(dim=-1)``).
  
  See: R. R. Selvaraju et al. Grad-CAM: Visual Explanations from Deep Networks via
  Gradient-based Localization. https://doi.org/10.1109/ICCV.2017.74.
  
  Examples:
  
  .. code-block:: python
  
      # densenet 2d
      from monai.networks.nets import DenseNet121
      from monai.visualize import OcclusionSensitivity
      import torch
  
      model_2d = DenseNet121(spatial_dims=2, in_channels=1, out_channels=3)
      occ_sens = OcclusionSensitivity(nn_module=model_2d)
      occ_map, most_probable_class = occ_sens(x=torch.rand((1, 1, 48, 64)), b_box=[2, 40, 1, 62])
  
      # densenet 3d
      from monai.networks.nets import DenseNet
      from monai.visualize import OcclusionSensitivity
  
      model_3d = DenseNet(spatial_dims=3, in_channels=1, out_channels=3, init_features=2, growth_rate=2, block_config=(6,))
      occ_sens = OcclusionSensitivity(nn_module=model_3d, n_batch=10)
      occ_map, most_probable_class = occ_sens(torch.rand(1, 1, 6, 6, 6), b_box=[1, 3, -1, -1, -1, -1])
  
  See Also:
  
      - :py:class:`monai.visualize.occlusion_sensitivity.OcclusionSensitivity.`
class_docstr_tok: ["This","class","computes","the","occlusion","sensitivity","for","a","model","'s","prediction","of","a","given","image",".","By","occlusion","sensitivity",",","we","mean","how","the","probability","of","a","given","prediction","changes","as","the","occluded","section","of","an","image","changes",".","This","can","be","useful","to","understand","why","a","network","is","making","certain","decisions",".","As","important","parts","of","the","image","are","occluded",",","the","probability","of","classifying","the","image","correctly","will","decrease",".","Hence",",","more","negative","values","imply","the","corresponding","occluded","volume","was","more","important","in","the","decision","process",".","Two","``","torch.Tensor","``","will","be","returned","by","the","``","__call__","``","method",":","an","occlusion","map","and","an","image","of","the","most","probable","class",".","Both","images","will","be","cropped","if","a","bounding","box","used",",","but","voxel","sizes","will","always","match","the","input",".","The","occlusion","map","shows","the","inference","probabilities","when","the","corresponding","part","of","the","image","is","occluded",".","Hence",",","more","-ve","values","imply","that","region","was","important","in","the","decision","process",".","The","map","will","have","shape","``","BCHW","(","D",")","N","``",",","where","``","N","``","is","the","number","of","classes","to","be","inferred","by","the","network",".","Hence",",","the","occlusion","for","class","``","i","``","can","be","seen","with","``","map","[","...",",","i","]","``",".","The","most","probable","class","is","an","image","of","the","probable","class","when","the","corresponding","part","of","the","image","is","occluded","(","equivalent","to","``","occ_map.argmax","(","dim=-1",")","``",")",".","See",":","R.","R.","Selvaraju","et","al",".","Grad-CAM",":","Visual","Explanations","from","Deep","Networks","via","Gradient-based","Localization",".","https",":","\/\/doi.org\/10.1109\/ICCV.2017.74",".","Examples",":","..","code-block",":",":","python","#","densenet","2d","from","monai.networks.nets","import","DenseNet121","from","monai.visualize","import","OcclusionSensitivity","import","torch","model_2d","=","DenseNet121","(","spatial_dims=2",",","in_channels=1",",","out_channels=3",")","occ_sens","=","OcclusionSensitivity","(","nn_module=model_2d",")","occ_map",",","most_probable_class","=","occ_sens","(","x=torch.rand","(","(","1",",","1",",","48",",","64",")",")",",","b_box=","[","2",",","40",",","1",",","62","]",")","#","densenet","3d","from","monai.networks.nets","import","DenseNet","from","monai.visualize","import","OcclusionSensitivity","model_3d","=","DenseNet","(","spatial_dims=3",",","in_channels=1",",","out_channels=3",",","init_features=2",",","growth_rate=2",",","block_config=","(","6",",",")",")","occ_sens","=","OcclusionSensitivity","(","nn_module=model_3d",",","n_batch=10",")","occ_map",",","most_probable_class","=","occ_sens","(","torch.rand","(","1",",","1",",","6",",","6",",","6",")",",","b_box=","[","1",",","3",",","-1",",","-1",",","-1",",","-1","]",")","See","Also",":","-",":","py",":","class",":","`","monai.visualize.occlusion_sensitivity.OcclusionSensitivity.","`"]
docstr: Crop the meshgrid so we only perform occlusion sensitivity on a subsection of the image.
docstr_tok: ["Crop","the","meshgrid","so","we","only","perform","occlusion","sensitivity","on","a","subsection","of","the","image","."]
code: def crop_meshgrid(
      grid: MetaTensor, b_box: Sequence, mask_size: Sequence
  ) -> tuple[MetaTensor, SpatialCrop, Sequence]:
      """Crop the meshgrid so we only perform occlusion sensitivity on a subsection of the image."""
      # distance from center of mask to edge is -1 // 2.
      mask_edge = [(m - 1) // 2 for m in mask_size]
      bbox_min = [max(b - m, 0) for b, m in zip(b_box[::2], mask_edge)]
      bbox_max = []
      for b, m, s in zip(b_box[1::2], mask_edge, grid.shape[2:]):
          # if bbox is -ve for that dimension, no cropping so use current image size
          if b == -1:
              bbox_max.append(s)
          # else bounding box plus distance to mask edge. Make sure it's not bigger than the size of the image
          else:
              bbox_max.append(min(b + m, s))
      # bbox_max = [min(b + m, s) if b >= 0 else s for b, m, s in zip(b_box[1::2], mask_edge, grid.shape[2:])]
      # No need for batch and channel slices. Batch will be removed and added back in, and
      # SpatialCrop doesn't act on the first dimension anyway.
      slices = [slice(s, e) for s, e in zip(bbox_min, bbox_max)]
      cropper = SpatialCrop(roi_slices=slices)
      cropped: MetaTensor = cropper(grid[0])[None]  # type: ignore
      mask_size = list(mask_size)
      for i, s in enumerate(cropped.shape[2:]):
          mask_size[i] = min(s, mask_size[i])
      return cropped, cropper, mask_size
  
file_path: MONAI/monai/visualize/occlusion_sensitivity.py
imports: from __future__ import annotations
  from collections.abc import Callable, Mapping, Sequence
  from typing import Any
  import numpy
  import torch
  import torch.nn
  from monai.data.meta_tensor import MetaTensor
  from monai.networks.utils import eval_mode
  from monai.transforms import Compose, GaussianSmooth, Lambda, ScaleIntensity, SpatialCrop
  from monai.utils import ensure_tuple_rep
label_desc: Use image node_id 5 for calling the OcclusionSensitivity obj's underlying member method code with example usage: obj.crop_meshgrid(grid, b_box, mask_size) and returns: cropped,  cropper,  mask_size