CNN 特征图可视化
项目描述
FeatureMapVisualizer - 基于 CNN 的模型的深度可视化工具
概述
FeatureMapVisualizer 允许使用基于 CNN 的图像分类模型的单个特征图进行可视化,以深入了解其预测。它提供了以下可视化技术:
- 查找每个类最活跃的特征图
- 可视化顶部特征图捕获的模式
- 在一张图像上可视化不同特征图的激活
- 可视化一个特征图在不同图像上的激活
- 可视化不同特征图在不同图像上的激活
- 绘制每个类的顶级特征图的激活总和
用法
在这里,我将描述如何为自己的项目获取和使用 FeatureMapVisualizer。
在做了
要下载 FeatureMapVisualizer,要么 fork 这个 github repo,要么简单地通过 pip 使用 PyPi。
$ pip install FeatureMapVisualizer
使用它
Scrapeasy 的编程考虑到了易用性。一、从 Scrapeasy 导入网站和页面
from FeatureMapVisualizer import visualizer
你准备好了!可视化类包含上面提到的所有可视化方法。我将在下面向您展示每种方法的示例代码。
定义特征图可视化器类
首先,让我们定义 Feature Map Visualizer 类。
FV = visualizer.FeatureMapVisualizer(model, model_type="resnet")
[Pre-Viz]查找每个类的最活跃(顶部)特征图
ResNet50 在最后一个卷积层中有 2,048 个特征图,而 vgg16 有 512 个。流行的可视化工具(如Grad-CAM)着眼于这些特征图的平均值。但是每个单独的特征图都必须学习类的不同特征,那么为什么不看具体的呢?所以这个函数可以让我们找出模型最后一个卷积层中的哪些特定特征图在模型看到特定类别的图像时被激活最多。然后我们可以在可视化时专注于那些特征图。
top_feature_map_dict = FV.find_unique_filters(
layer = 12,
train_dir = "my_folder/train/",
classes = ["cat", "dog"],
n_imgs_dict = [{"cat":1955, "dog":1857}],
n_each_img = 25,
n_each_class = 25,
)
让我们看看每个参数:
layer: (int) 要研究的模型卷积层的索引 *查看最后一个卷积层中的特征图(对特定形状而不是高级纹理最敏感),-2用于 resnet 或12vgg16train_dir: (str) 包含训练数据的文件夹的地址,末尾包含“/”classes: (list of strs) 字符串中包含(至少两个)类名的列表n_imgs_dict: (dict) key : 类名 (str), value : 该类的训练图像数 (int)n_each_img(可选) :(int)为每个图像保存的顶级特征图,默认值 = 25n_each_class(可选) :(int)#为每个类保存的顶级特征图,默认值=25
作为输出,您将获得一个形式的字典:
{'cat': [452, 312, 327, 12, 114],
'dog': [115, 23, 135, 203, 350, 132]}
它表示对每个类最敏感的特征图的索引。
Viz #1 -可视化顶部特征图捕获的模式
在缩小了每个类的专门特征图的范围后,我调查了每个单独的顶部特征图捕获了哪些突出的形状或对象部分。受这篇文章的启发,想法是首先生成一个小的随机图像(我使用 33 x 33 像素),然后在最大化所选特征图激活的方向上迭代调整其像素。这是通过最小化等于特征图激活总和的负数的损失来完成的。
layer = -2 # last convolutional layer for ResNet50
filter = 452 # top #1 feature map for cat class
img, img_name = FV.visualize_patterns(
layer = layer,
filter_n = filter,
init_size=33,
lr = 0.2,
opt_steps = 20,
upscaling_steps = 20,
upscaling_factor = 1.2,
print_loss = False,
plot = True,
)
plt.figure(figsize=(15,15))
plt.imshow(np.array(Image.open(img_name)))
plt.show()
参数:
layer: (int) 用于研究特征图的卷积层索引 *对于最后一个卷积层,-2用于 resent50 或12vgg16。filter_n:(int)要在图层中调查的特征图的索引init_size(可选) :(int)方形随机图像的初始长度,默认=33lr(可选) : (float) 像素优化的学习率,默认=0.2opt_steps(可选) : (int) 优化步骤数,默认=20upscaling_steps(optional) : (int) # upscaling steps, default=20upscaling_factor(可选) : (float) >1, upscale factor, default=1.2print_loss(可选) : (bool) 如果为 True,则在每次优化迭代时记录信息,默认 = False *如果所有迭代的激活为 0,则存在问题。plot(可选) : (bool) ifTrue,在每次优化迭代时绘制生成的图像,默认=True
您可以在此处查看生成图像的示例。
Viz #2 -在一张图像上可视化不同特征图的激活
在这里,我们找到了对单个图像的激活最大化的特征图,并通过将其激活图覆盖在图像顶部来突出显示每个特征图在图像中参与度最高的区域。如前所述,Grad-CAM回答了一个类似的问题,即整个最后一个卷积层正在关注图像的哪些部分,但它并没有像查看每个单独的特征图那样具体。
layer = -2
activations_list_cat = FV.one_image_N_top_feature_maps(
layer,
img_path="my_folder/test/cat/cat_1.jpg",
n=60,
n_plots_horiz=6,
n_plots_vert=10,
plot_w=50,
plot_h=30,
)
layer: (int) 用于研究特征图的卷积层索引 *对于 LAST 卷积层,-2用于 resent50 和12vgg16。img_path: (str) 要调查的图像路径plot(可选) : (bool) 如果为真,则在图像上绘制前 N 个特征图的激活图,默认 = True /// 必须是:n_plots_horiz * n_plots_vert = n ///n(可选) :(int)要绘制的顶部特征图的数量,默认值 = 100n_plots_horiz(可选) :(int)要水平绘制的特征图数量,默认值=10n_plots_vert(可选) :(int)要垂直绘制的特征图数量,默认=10 /// 推荐:(n_plots_horiz/n_plots_vert)=(plot_h/plot_w)///plot_h(可选) :(int)绘图的高度,默认=50plot_w(可选) :(int)绘图的宽度,默认值=50print_logits(可选) :(布尔)如果为真,则打印图像的模型logits(输出),默认=imagenet(可选) : (bool) 如果为 True,print_logits 将打印对应的 imagenet 标签的 logits,默认 = Falseplot_overlay(可选) : (bool) ifTrue,将顶部特征图叠加在图像之上并绘制叠加图像;ifFalse,仅绘制原始特征图,默认=True
您可以在此处查看生成的可视化示例。
Viz #3 -可视化一个特征图在不同图像上的激活
对于此可视化,当您传递要调查的特征图的索引 ( filter_idx) 时,它会为 中最多 100 个图像绘制其激活图dataloader。
activations_list_dog = FV.one_feature_map_N_images(
layer = -2,
dataloader = dog_test_dataloader,
filter_idx = 1239,
plot=True,
max_n_imgs_to_plot = 100,
plot_overlay = True,
normalize = True,
folder = "viz3/dog",
class_name = "dog",
)
layer: (int) 用于研究特征图的卷积层索引 *对于 LAST 卷积层,-2用于 resent50 和12vgg16。dataloader:(torch.utils.data.dataloader 对象)包含要绘制的图像的数据加载器(通常是单个类的图像)filter_idx:(int)要在图层中调查的特征图的索引plot(可选) :(布尔)如果为真,则在数据加载器中的图像上绘制特征图的激活图,默认=真max_n_imgs_to_plot(可选) :(int)要绘制的最大图像数,默认值 = 100plot_overlay(可选) : (bool) ifTrue,将顶部特征图叠加在图像之上并绘制叠加图像;ifFalse,仅绘制原始特征图,默认=Truenormalize(可选) : (bool) 如果为真,则通过除以最大值来归一化掩码特征图,默认=真folder(可选) : (str) 保存图像的文件夹名称(仅当您要保存可视化时),默认 =“”class_name(可选) :(str)图像所属类的名称,默认=“”
您可以在此处查看生成的可视化示例。
Viz #4 -可视化不同特征图在不同图像上的激活
此可视化与 Viz #3 相同,只是您传递了要一起研究的多个特征图filter_idxs的索引 ( )。它绘制了所有这些特征图的激活图dataloader之和。
activations_list_dog = FV.M_feature_map_N_images(
layer = -2,
dataloader = dog_test_dataloader,
filter_idxs = top_feature_map_dict['dog'],
plot = True,
max_n_imgs_to_plot = 100,
plot_overlay = True,
)
layer: (int) 用于研究特征图的卷积层索引 *对于 LAST 卷积层,-2用于 resent50 和12vgg16。dataloader:(torch.utils.data.dataloader 对象)包含要绘制的图像的数据加载器(通常是单个类的图像)filter_idxs:(整数列表)要在图层中调查的特征图索引plot(可选) :(布尔)如果为真,则在数据加载器中的图像上绘制特征图的激活图,默认=真max_n_imgs_to_plot(可选) :(int)要绘制的最大图像数,默认值 = 100plot_overlay(可选) : (bool) ifTrue,将顶部特征图叠加在图像之上并绘制叠加图像;ifFalse,仅绘制原始特征图,默认=True
Viz #5 -绘制每个类的顶级特征图的激活总和
在这里,对于每个类别,所有类别的顶级特征图(在Pre-Viz部分中找到)的激活被添加到每个测试图像中,并绘制在同一张图上,用不同的颜色代表不同的类别。
sum_dicts = FV.sum_top_feature_maps_by_class(
layer = -2,
transform = transform,
img_dir = "xray_sh",
top_feature_maps_dict = {"cat":[1,3,9], "dog":[2,7]},
plot = True,
)
layer: (int) 用于研究特征图的卷积层索引 *对于 LAST 卷积层,-2用于 resent50 和12vgg16。transform: (torchvision.transforms object) 应用于每个测试图像的变换img_dir: (str) 包含图像文件夹的文件夹地址 *图像文件夹的名称必须与目标类名称相同。 /// 您必须通过top_feature_maps_dict或全部通过train_dir,classes和n_imgs_dict. ///top_feature_maps_dict(有条件可选):(dict)(键,值)=(类名,该类的顶级特征图列表)例如 {"cat":[1,3,5], "dog":[2,4, 8]},默认=无train_dir(有条件地可选):(str)包含训练数据的文件夹的地址,包括末尾的“/”,例如“train_data/”,默认=无classes(有条件可选):(strs 列表)包含(至少两个)字符串中的类名的列表,例如 ["cat", "dog"], default=Nonen_imgs_dict(有条件可选):(dict)键:类名(str),值:该类的训练图像数(int)例如{“dog”:955,“cat”:1857},默认=无plot(可选):(布尔)如果为真,则显示图,默认=真
您可以在此处查看生成的可视化示例。
执照
麻省理工学院许可证
版权所有 (c) 2022 Jahyun Shin
特此免费授予任何人获得本软件和相关文档文件(“软件”)的副本,以不受限制地处理本软件,包括但不限于使用、复制、修改、合并的权利、发布、分发、再许可和/或出售本软件的副本,并允许向其提供本软件的人这样做,但须符合以下条件:
上述版权声明和本许可声明应包含在本软件的所有副本或大部分内容中。
本软件按“原样”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性、特定用途适用性和非侵权保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任承担任何责任,无论是在合同、侵权或其他方面,由本软件或本软件的使用或其他交易引起或与之相关。软件。
雇用我!:LinkedIn