可视化#
Tensorboard 可视化#
- monai.visualize.img2tensorboard.add_animated_gif(writer, tag, image_tensor, max_out=3, frame_dim=-3, scale_factor=1.0, global_step=None)[source]#
使用 ‘CHWD’ 格式的图像张量创建动态 GIF,并使用 SummaryWriter 写入。
- 参数:
writer (
UnionType[SummaryWriter,SummaryWriter]) – 用于写入的 Tensorboard SummaryWritertag (
str) – 数据标识符image_tensor (
UnionType[ndarray,Tensor]) – 要添加的图像张量,期望格式为 CHWDmax_out (
int) – 动画化时的最大图像通道数frame_dim (
int) – 用作 GIF 图像帧的维度,期望输入数据形状为 CHWD,默认为 -3(第一个空间维度)scale_factor (
float) – 数值乘数。如果图像数据在 0 到 1 之间,将其设为 255 可将其缩放至可显示范围global_step (
Optional[int,None]) – 要记录的全局步数
- 返回类型:
None
- monai.visualize.img2tensorboard.make_animated_gif_summary(tag, image, writer=None, max_out=3, frame_dim=-3, scale_factor=1.0)[source]#
使用 ‘CHWD’ 格式的图像张量创建动态 GIF,并返回 Summary 对象。
- 参数:
tag (
str) – 数据标识符image (
UnionType[ndarray,Tensor]) – 图像,期望格式为 CHWDwriter (
Union[SummaryWriter,SummaryWriter,None]) – 用于绘制图像的 tensorboard 写入器max_out (
int) – 动画化时的最大图像通道数frame_dim (
int) – 用作 GIF 图像帧的维度,期望输入数据形状为 CHWD,默认为 -3(第一个空间维度)scale_factor (
float) – 数值乘数。如果图像数据在 0 到 1 之间,将其设为 255 可将其缩放至可显示范围
- 返回类型:
Summary
- monai.visualize.img2tensorboard.plot_2d_or_3d_image(data, step, writer, index=0, max_channels=1, frame_dim=-3, max_frames=24, tag='output')[source]#
在 TensorBoard 上绘制 2D 或 3D 图像,3D 图像将被转换为 GIF 图像。
注意
将 3D 或 2D 图像(具有超过 3 个通道)绘制为独立图像。如果写入器来自 TensorBoardX 且数据有 3 个通道且 max_channels=3,将绘制为 RGB 视频。
- 参数:
data (
Union[~NdarrayTensor,list[~NdarrayTensor]]) – 在 TensorBoard 上绘制为图像的目标数据。期望数据具有 ‘NCHW[D]’ 维度,或包含 CHW[D] 维度数据的列表,仅绘制批处理中的第一个。step (
int) – 图表中的当前步数。writer (
UnionType[SummaryWriter,SummaryWriter]) – 指定用于绘制图像的 TensorBoard 或 TensorBoardX SummaryWriter。index (
int) – 绘制输入数据批次中的哪个元素,默认为第一个元素。max_channels (
int) – 要绘制的通道数。frame_dim (
int) – 若将 3D 图像绘制为 GIF,指定用作帧的维度,期望输入数据形状为 NCHWD,默认为 -3(第一个空间维度)max_frames (
int) – 若在 TensorBoardX 中将 3D RGB 图像绘制为视频,将 FPS 设置为 max_frames。tag (
str) – 在 TensorBoard 上绘制的图像标签。
- 返回类型:
None
类激活映射#
- class monai.visualize.class_activation_maps.CAM(nn_module, target_layers, fc_layers='fc', upsampler=<function default_upsampler>, postprocessing=<function default_normalizer>)[source]#
从空间池化前的最后一个全连接层计算类激活映射。该实现基于
Zhou 等人,Learning Deep Features for Discriminative Localization. CVPR ‘16, https://arxiv.org/abs/1512.04150
示例
import torch # densenet 2d from monai.networks.nets import DenseNet121 from monai.visualize import CAM model_2d = DenseNet121(spatial_dims=2, in_channels=1, out_channels=3) cam = CAM(nn_module=model_2d, target_layers="class_layers.relu", fc_layers="class_layers.out") result = cam(x=torch.rand((1, 1, 48, 64))) # resnet 2d from monai.networks.nets import seresnet50 from monai.visualize import CAM model_2d = seresnet50(spatial_dims=2, in_channels=3, num_classes=4) cam = CAM(nn_module=model_2d, target_layers="layer4", fc_layers="last_linear") result = cam(x=torch.rand((2, 3, 48, 64)))
注意:为了帮助选择目标层,列出所有层可能会很有用
for name, _ in model.named_modules(): print(name)
- __init__(nn_module, target_layers, fc_layers='fc', upsampler=<function default_upsampler>, postprocessing=<function default_normalizer>)[source]#
- 参数:
nn_module (
Module) – 要可视化的模型target_layers (
str) – 用于生成特征图的模型层名称。fc_layers (
UnionType[str,Callable]) – 一个字符串或可调用对象,用于获取全连接权重,以便从目标层(不进行池化)计算激活映射,并在每个空间位置进行评估。upsampler (
Callable) – 用于对输出图像进行上采样的方法。默认为 N 维线性(双线性、三线性等),具体取决于输入的空间维度数。postprocessing (
Callable) – 应用于上采样输出图像的可调用对象。默认是将最小值=1和最大值=0进行归一化(即最大的输入将变为 0,最小的输入将变为 1)。
- class monai.visualize.class_activation_maps.GradCAM(nn_module, target_layers, upsampler=<function default_upsampler>, postprocessing=<function default_normalizer>, register_backward=True)[source]#
计算梯度加权类激活映射 (Grad-CAM)。该实现基于
Selvaraju 等人,Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization, https://arxiv.org/abs/1610.02391
示例
import torch # densenet 2d from monai.networks.nets import DenseNet121 from monai.visualize import GradCAM model_2d = DenseNet121(spatial_dims=2, in_channels=1, out_channels=3) cam = GradCAM(nn_module=model_2d, target_layers="class_layers.relu") result = cam(x=torch.rand((1, 1, 48, 64))) # resnet 2d from monai.networks.nets import seresnet50 from monai.visualize import GradCAM model_2d = seresnet50(spatial_dims=2, in_channels=3, num_classes=4) cam = GradCAM(nn_module=model_2d, target_layers="layer4") result = cam(x=torch.rand((2, 3, 48, 64)))
注意:为了帮助选择目标层,列出所有层可能会很有用
for name, _ in model.named_modules(): print(name)
- class monai.visualize.class_activation_maps.GradCAMpp(nn_module, target_layers, upsampler=<function default_upsampler>, postprocessing=<function default_normalizer>, register_backward=True)[source]#
计算梯度加权类激活映射 (Grad-CAM++)。该实现基于
Chattopadhyay 等人,Grad-CAM++: Improved Visual Explanations for Deep Convolutional Networks, https://arxiv.org/abs/1710.11063
- class monai.visualize.class_activation_maps.ModelWithHooks(nn_module, target_layer_names, register_forward=False, register_backward=False)[source]#
一个模型包装器,用于运行模型的前向/反向步骤并存储中间特征/梯度信息。
- __init__(nn_module, target_layer_names, register_forward=False, register_backward=False)[source]#
- 参数:
nn_module (
Module) – 要包装的模型。target_layer_names (
UnionType[str,Sequence[str]]) – 要缓存的层名称。register_forward (
bool) – 是否缓存与 target_layer_names 对应的前向传播输出。register_backward (
bool) – 是否缓存与 target_layer_names 对应的反向传播输出。
遮挡敏感度#
- class monai.visualize.occlusion_sensitivity.OcclusionSensitivity(nn_module, mask_size=16, n_batch=16, verbose=True, mode='gaussian', overlap=0.6, activate=True)[source]#
此类用于计算给定图像的模型预测的遮挡敏感度。遮挡敏感度是指随着图像的遮挡部分发生变化,给定预测的概率如何变化。这对于理解网络为何做出某些决策非常有用。
当图像的重要部分被遮挡时,正确分类图像的概率会降低。因此,更负的值意味着相应的遮挡体积在决策过程中更重要。
__call__方法将返回两个torch.Tensor:遮挡图和最可能类别的图像。如果使用了边界框,两张图像都会被裁剪,但体素大小始终与输入保持一致。遮挡图显示了当图像的相应部分被遮挡时的推断概率。因此,更负的值意味着该区域在决策过程中很重要。该图的形状将为
BCHW(D)N,其中N是网络要推断的类别数。因此,类别i的遮挡可以通过map[...,i]查看。最可能的类别是当图像的相应部分被遮挡时可能类别的图像(等同于
occ_map.argmax(dim=-1))。参见:R. R. Selvaraju 等人 Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization. https://doi.org/10.1109/ICCV.2017.74。
示例
# 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])
另请参阅
monai.visualize.occlusion_sensitivity.OcclusionSensitivity。
- __init__(nn_module, mask_size=16, n_batch=16, verbose=True, mode='gaussian', overlap=0.6, activate=True)[source]#
遮挡敏感度构造函数。
- 参数:
nn_module (
Module) – 用于推断的分类模型mask_size (
UnionType[int,Sequence]) – 要遮挡的框的大小,以中心体素为中心。如果给定一个数字,则将其用于所有维度。如果给定一个序列,则分别将其用于每个维度。n_batch (
int) – 推断批次中的图像数量。verbose (
bool) – 使用进度条(如果tqdm可用)。mode (
UnionType[str,float,Callable]) –应使用什么替换遮挡区域?如果给定一个浮点数,该值将在整个遮挡过程中使用。否则,可以提供
gaussian、mean_img和mean_patchgaussian:遮挡区域乘以 1 - 高斯核。通过这种方式,遮挡在中心处为 0,向边缘处保持不变,并在两者之间平滑变化。当使用高斯遮挡时,将使用加权平均值来组合重叠区域。这将在使用高斯(而不是 1-高斯)时完成,因为遮挡区域的权重更高。mean_patch:遮挡区域将被替换为该遮挡区域的平均值。mean_img:遮挡区域将被替换为整张图像的平均值。
overlap (
float) – 推断区域之间的重叠。应在范围 0<=x<1 内。activate (
UnionType[bool,Callable]) – 如果True,若 num_channels > 1 则进行 softmax 激活,否则进行sigmoid激活。如果False,则不进行任何激活。如果为callable,则对推断输出使用可调用对象。
- static constant_occlusion(x, val, mask_size)[source]#
用恒定值进行遮挡。乘法遮挡为零,加法遮挡为恒定值。
- 返回类型:
tuple[float,Tensor]
- static crop_meshgrid(grid, b_box, mask_size)[source]#
裁剪网格,以便我们仅对图像的子部分执行遮挡敏感度分析。
- 返回类型:
tuple[MetaTensor,SpatialCrop,Sequence]
- static gaussian_occlusion(x, mask_size, sigma=0.25)[source]#
对于高斯遮挡,乘法遮挡为 1-高斯,加法遮挡为零。经验表明,0.25 的默认 sigma 值可以提供合理的内核,详情请见:Project-MONAI/MONAI#5230。
- 返回类型:
tuple[Tensor,float]
- static predictor(cropped_grid, nn_module, x, mul, add, mask_size, occ_mode, activate, module_kwargs)[source]#
传递给滑动窗口推断器的预测函数。采用裁剪后的网格,引用输入图像中的坐标。我们结合
mask_size使用左上角的索引来确定图像的哪个区域被遮挡。遮挡是在原始图像x上执行的,使用cropped_region * mul + add。mul和add有时是预先计算的(例如恒定的高斯模糊),有时是动态计算的(例如遮挡补丁的平均值)。因此提供了occ_mode。最后,activate用于在每次调用模型后进行激活。- 参数:
cropped_grid (
Tensor) – 网格的子部分,每个体素引用输入图像的坐标。网格由OcclusionSensitivity类创建,子集的生成由sliding_window_inference决定。nn_module (
Module) – 在数据上调用的模块。x (
Tensor) – 最初传递给OcclusionSensitivity.__call__的图像。mul (
UnionType[Tensor,float]) – 遮挡区域将乘以该值。可以是torch.Tensor或float。add (
UnionType[Tensor,float]) – 乘法后,将其添加到遮挡区域。可以是torch.Tensor或float。mask_size (
Sequence) – 要遮挡的框的大小,以中心体素为中心。应为一个序列,每个空间维度一个值。occ_mode (
str) – 可能用于动态计算mul和add。activate (
UnionType[bool,Callable]) – 如果True,若 num_channels > 1 则进行 softmax 激活,否则进行sigmoid激活。如果False,则不进行任何激活。如果为callable,则对推断输出使用可调用对象。module_kwargs (
Mapping[str,Any]) – 推断时要传递给模块的关键字参数
- 返回类型:
Tensor
基于梯度的显著性图#
- class monai.visualize.gradient_based.GuidedBackpropGrad(model)[source]#
基于 Springenberg 和 Dosovitskiy 等人的研究 https://arxiv.org/abs/1412.6806,通过反向传播正梯度和输入(参见
_AutoGradReLU)来计算基于梯度的显著性图。另请参阅
Springenberg 和 Dosovitskiy 等人,Striving for Simplicity: The All Convolutional Net (https://arxiv.org/abs/1412.6806)
- class monai.visualize.gradient_based.GuidedBackpropSmoothGrad(model, stdev_spread=0.15, n_samples=25, magnitude=True, verbose=True)[source]#
基于
GuidedBackpropGrad和SmoothGrad计算基于梯度的显著性图。
- class monai.visualize.gradient_based.SmoothGrad(model, stdev_spread=0.15, n_samples=25, magnitude=True, verbose=True)[source]#
基于输入图像
x的n_samples(高斯加性)噪声版本的平均灵敏度图。另请参阅
Smilkov 等人,SmoothGrad: removing noise by adding noise https://arxiv.org/abs/1706.03825
- class monai.visualize.gradient_based.VanillaGrad(model)[source]#
给定输入图像
x,调用此类将执行前向传播,然后将除一个(由index定义)之外的所有激活设置为零,并反向传播到图像以获得基于梯度的显著性图。如果
index为 None,将使用输出 logits 的 argmax。另请参阅
Simonyan 等人,Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps (https://arxiv.org/abs/1312.6034)
工具#
- monai.visualize.utils.blend_images(image, label, alpha=0.5, cmap='hsv', rescale_arrays=True, transparent_background=True)[source]#
混合图像和标签。两者都应具有形状 CHW[D]。图像可以有 C==1 或 3 个通道(灰度或 RGB)。标签期望有 C==1。
- 参数:
image (
UnionType[ndarray,Tensor]) – 要与标签数据混合的输入图像。label (
UnionType[ndarray,Tensor]) – 要与图像数据混合的输入标签。alpha (
UnionType[float,ndarray,Tensor]) – 指定分配给标签的权重,0 表示完全透明,1 表示完全不透明。这可以作为单个值或与输入图像大小相同的数组/张量给出。cmap (
str) – 在 matplotlib 中指定色图,默认为 hsv,有关更多详细信息,请参阅:https://matplotlib.net.cn/2.0.2/users/colormaps.html。rescale_arrays (
bool) – 是否先将数组缩放到 [0, 1],默认为 True。transparent_background (
bool) – 如果为 true,标签字段中的任何零将不会被着色。
- 返回类型:
UnionType[ndarray,Tensor]
- monai.visualize.utils.matshow3d(volume, fig=None, title=None, figsize=(10, 10), frames_per_row=None, frame_dim=-3, channel_dim=None, vmin=None, vmax=None, every_n=1, interpolation='none', show=False, fill_value=nan, margin=1, dtype=<class 'numpy.float32'>, **kwargs)[source]#
将 3D 体积图形创建为图像网格。
- 参数:
volume (
UnionType[ndarray,Tensor]) – 要显示的 3D 体积。数据形状可以是 BCHWD、CHWD 或 HWD。更高维度的数组将被重塑为 (-1, H, W, [C]),C 取决于 channel_dim 参数。也可以传入一个通道优先 (C, H[, W, D]) 的数组列表,在这种情况下,它们将被显示为填充和堆叠的体积。fig (
Optional[Any,None]) – 要使用的 matplotlib 图形或坐标轴。如果为 None,将创建一个新图形。title (
Optional[str,None]) – 图形的标题。figsize (
tuple[int,int]) – 图形的大小。frames_per_row (
Optional[int,None]) – 每行显示的帧数。如果为 None,将使用 sqrt(firstdim)。frame_dim (
int) – 对于更高维度的数组,从 (-1, -2, -3) 中移至 -3 维度的哪个维度。维度和重塑为 (-1, H, W) 形状以构建帧,默认为 -3。channel_dim (
Optional[int,None]) – 如果不为 None,明确指定要转置到最后一个维度的通道维度,形状为 (-1, H, W, C)。这可用于绘制 RGB 彩色图像。如果为 None,通道维度将与 frame_dim 和 batch_dim 一起平展,形状为 (-1, H, W)。注意它只能支持 3D 输入图像。默认为 None。vmin (
Optional[float,None]) – matplotlib imshow 的 vmin。vmax (
Optional[float,None]) – matplotlib imshow 的 vmax。every_n (
int) – 对帧进行子采样的因子,以便仅显示每第 n 帧。interpolation (
str) – 用于 matplotlib matshow 的插值方法。show (
bool) – 如果为 True,则显示该图形。fill_value (
Any) – 用于网格空白部分的填充值。margin (
int) – 用于网格的边距。dtype (
UnionType[dtype,type,str,None]) – 输出堆叠帧的数据类型。kwargs (
Any) – 传递给 matplotlib matshow 和 imshow 的附加关键字参数。
另请参阅
示例
>>> import numpy as np >>> import matplotlib.pyplot as plt >>> from monai.visualize import matshow3d # create a figure of a 3D volume >>> volume = np.random.rand(10, 10, 10) >>> fig = plt.figure() >>> matshow3d(volume, fig=fig, title="3D Volume") >>> plt.show() # create a figure of a list of channel-first 3D volumes >>> volumes = [np.random.rand(1, 10, 10, 10), np.random.rand(1, 10, 10, 10)] >>> fig = plt.figure() >>> matshow3d(volumes, fig=fig, title="List of Volumes") >>> plt.show()
- 返回类型:
tuple[Any,ndarray]