使用Pytorch和Matplotlib可视化卷积神经网络的特征(下)

简介: 使用Pytorch和Matplotlib可视化卷积神经网络的特征

如何使用

Extractor类中,模型参数接受模型,而DS_layer_name参数是可选的。DS_layer_name参数用于查找下采样层,通常在resnet层中名称为“downsample”,因此它保持为默认值。

extractor = Extractor(model = resnet, DS_layer_name = 'downsample')

extractor.activate())是激活程序。extractor.info()可以查看里面的方法

{'Down-sample layers name': 'downsample', 'Total CNN Layers': 49, 'Total Sequential Layers': 4, 'Total Downsampling Layers': 4, 'Total Linear Layers': 1, 'Total number of Bottleneck and Basicblock': 16, 'Total Execution time': '0.00137 sec'}

访问权重和层

extractor.CNN_layers -----> Gives all the CNN layers in a model
extractor.Linear_layers --> Gives all the Linear layers in a model
extractor.DS_layers ------> Gives all the Down-sample layers in a model if there are any
extractor.CNN_weights ----> Gives all the CNN layer's weights in a model
extractor.Linear_weights -> Gives all the Linear layer's weights in a model

没有任何编码,你可以得到CNN和线性层和他们的权值在几乎每个resnet模型。下面是类的方法

def activate(self):
         """Activates the algorithm"""
         start = time.time()
         self.__Layer_Extractor(self.model_children)
         self.__Verbose()
         self.__ex_time = str(round(time.time() - start, 5)) + ' sec'
def __Append(self, layer, Linear=False):
         """
       This function will append the layers weights and
       the layer itself to the appropriate variables
       params: layer: takes in CNN or Linear layer
       returns: None
       """
         if Linear:
             self.Linear_weights.append(layer.weight)
             self.Linear_layers.append(layer)
         else:
             self.CNN_weights.append(layer.weight)
             self.CNN_layers.append(layer)
def __Layer_Extractor(self, layers):
         """
       This function(algorithm) finds CNN and linear layer in a Sequential layer
       params: layers: takes in either CNN or Sequential or linear layer
       return: None
       """
         for x in range(len(layers)):
             if type(layers[x]) == nn.Sequential:
                 # Calling the fn to loop through the layer to get CNN layer
                 self.__Layer_Extractor(layers[x])
                 self.__no_sq_layers += 1
             if type(layers[x]) == nn.Conv2d:
                 self.__Append(layers[x])
             if type(layers[x]) == nn.Linear:
                 self.__Append(layers[x], True)
             # This statement makes sure to get the down-sampling layer in the model
             if self.DS_layer_name in layers[x]._modules.keys():
                 self.DS_layers.append(layers[x]._modules[self.DS_layer_name])
             # The below statement will loop throgh the containers and append it
             if isinstance(layers[x], (self.__bottleneck, self.__basicblock)):
                 self.__no_containers += 1
                 for child in layers[x].children():
                     if type(child) == nn.Conv2d:
                         self.__Append(child)

可视化

卷积层

在这里,我们将可视化卷积层过滤器。为了简单起见,我们将只可视化第一个卷积层的过滤器。

# Visualising the filters
plt.figure(figsize=(35, 35))
for index, filter in enumerate(extractor.CNN_weights[0]):
     plt.subplot(8, 8, index + 1)
     plt.imshow(filter[0, :, :].detach(), cmap='gray')
     plt.axis('off')
plt.show()

第一层的滤波器尺寸为7×7,有64个通道(隐藏层)。

640.png

来自训练好的resnet-50模型的7×7个过滤器

640.png

每个小方框的像素值在0到255之间。0是完全黑的255是白色的。范围可以是不同的,比如0到1或-1到1,以0为平均值。

特征映射

为了使特征映射形象化,首先需要将图像转换为张量图像。利用torchvision的变换,可以将图像归一化并转换为张量。

# Filter Map
img = cv.cvtColor(cv.imread('filtermap/5.png'), cv.COLOR_BGR2RGB)
#transforms is imported as t
img = t.Compose([
     t.ToPILImage(),
     t.Resize((128, 128)),
     # t.Grayscale(),
     t.ToTensor(),
     t.Normalize(0.5, 0.5)])(img).unsqueeze(0)
#LAST LINE
t.Normalize(0.5, 0.5)])(img).unsqueeze(0)

变换后的最后一行表示将变换应用于图像。您可以创建一个新变量,然后应用它,但是一定要更改变量名。unsqueze(0)是给张量img增加一个额外的维数。添加批处理维度是一个重要步骤。现在图像的大小不是[3,128,128],而是[1,3,128,128],这表示批处理中只有一个图像。

将图像输入每个卷积层

下面的代码将图像通过每个卷积层。

featuremaps = [extractor.CNN_layers [0] (img)]
len(extractor.CNN_layers):
featuremaps.append (extractor.CNN_layers [x] (featuremaps [1]))

我们将首先把图像作为输入,传递给第一个卷积层。在此之后,我们将使用for循环将最后一层的输出传递给下一层,直到到达最后一个卷积层。

  • 在第1行,我们将图像作为第一个卷积层的输入。
  • 然后我们使用for循环从第二层循环到最后一层卷积。
  • 我们将最后一层的输出作为下一个卷积层的输入(featuremaps[-1])。
  • 另外,我们将每个层的输出附加到featuremaps列表中。

特征的可视化

这是最后一步。我们将编写代码来可视化特征映射。注意,最后的cnn层有很多feature map,范围在512到2048之间。但是我们将只从每一层可视化64个特征图,否则将使输出真正地混乱。

# Visualising the featuremaps
for x in range(len(featuremaps)):
     plt.figure(figsize=(30, 30))
     layers = featuremaps[x][0, :, :, :].detach()
     for i, filter in enumerate(layers):
         if i == 64:
             break
         plt.subplot(8, 8, i + 1)
         plt.imshow(filter, cmap='gray')
         plt.axis('off')
     # plt.savefig('featuremap%s.png'%(x))
     plt.show()


  • 从第2行开始,我们遍历feature remaps。
  • 然后我们得到的层是featuremaps[x][0,:,:,:].detach()
  • 从第5行开始,我们遍历每个层中的过滤器。如果它是第64个特征图,我们就跳出了循环。
  • 在此之后,我们绘制feature map,并在必要时保存它们。

结果

可以看到,在创建图像的feature map时,不同的滤镜聚焦于不同的方面。

640.png

一些特征地图聚焦于图像的背景。另一些人则创建了图像的轮廓。一些滤镜创建的特征地图,背景是黑暗的,但图像的脸是明亮的。这是由于过滤器的相应权重。从上面的图像可以很清楚地看出,在深层,神经网络可以看到输入图像非常详细的特征图。

让我们看看其他一些特征。

640.png

640.png

ResNet-50模型的第20和第10卷积层的Feature map

640.png

640.png

ResNet-50模型第40和第30卷积层的Feature map

你可以观察到,当图像通过层的进展,细节从图像慢慢消失。它们看起来像噪音,但在这些特征地图中肯定有一种模式是人眼无法察觉的,但神经网络可以。

当图像到达最后的卷积层时,人类就不可能知道那是什么了。最后一层输出对于最后的全连接的神经元非常重要,这些神经元基本上构成了卷积神经网络的分类层。


本文代码:https://github.com/Rahul0128/Visualizing-Filters-and-Feature-Maps-in-Convolutional-Neural-Networks-using-PyTorch

目录
相关文章
|
9天前
|
编解码 异构计算
RT-DETR改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合
RT-DETR改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合
45 9
RT-DETR改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合
|
10天前
|
计算机视觉 Perl
RT-DETR改进策略【Backbone/主干网络】| 替换骨干网络为CVPR-2024 PKINet 获取多尺度纹理特征,适应尺度变化大的目标
RT-DETR改进策略【Backbone/主干网络】| 替换骨干网络为CVPR-2024 PKINet 获取多尺度纹理特征,适应尺度变化大的目标
39 10
RT-DETR改进策略【Backbone/主干网络】| 替换骨干网络为CVPR-2024 PKINet 获取多尺度纹理特征,适应尺度变化大的目标
|
10天前
|
机器学习/深度学习 编解码 计算机视觉
RT-DETR改进策略【Backbone/主干网络】| 2023 U-Net V2 替换骨干网络,加强细节特征的提取和融合
RT-DETR改进策略【Backbone/主干网络】| 2023 U-Net V2 替换骨干网络,加强细节特征的提取和融合
32 10
RT-DETR改进策略【Backbone/主干网络】| 2023 U-Net V2 替换骨干网络,加强细节特征的提取和融合
|
11天前
|
编解码 异构计算
YOLOv11改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合
YOLOv11改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合
37 7
YOLOv11改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合
|
2月前
|
机器学习/深度学习 网络架构
揭示Transformer重要缺陷!北大提出傅里叶分析神经网络FAN,填补周期性特征建模缺陷
近年来,神经网络在MLP和Transformer等模型上取得显著进展,但在处理周期性特征时存在缺陷。北京大学提出傅里叶分析网络(FAN),基于傅里叶分析建模周期性现象。FAN具有更少的参数、更好的周期性建模能力和广泛的应用范围,在符号公式表示、时间序列预测和语言建模等任务中表现出色。实验表明,FAN能更好地理解周期性特征,超越现有模型。论文链接:https://arxiv.org/pdf/2410.02675.pdf
129 68
|
13天前
|
计算机视觉 Perl
YOLOv11改进策略【Backbone/主干网络】| 替换骨干网络为CVPR-2024 PKINet 获取多尺度纹理特征,适应尺度变化大的目标
YOLOv11改进策略【Backbone/主干网络】| 替换骨干网络为CVPR-2024 PKINet 获取多尺度纹理特征,适应尺度变化大的目标
18 0
YOLOv11改进策略【Backbone/主干网络】| 替换骨干网络为CVPR-2024 PKINet 获取多尺度纹理特征,适应尺度变化大的目标
|
13天前
|
机器学习/深度学习 编解码 计算机视觉
YOLOv11改进策略【Backbone/主干网络】| 2023 U-Net V2 替换骨干网络,加强细节特征的提取和融合
YOLOv11改进策略【Backbone/主干网络】| 2023 U-Net V2 替换骨干网络,加强细节特征的提取和融合
35 0
YOLOv11改进策略【Backbone/主干网络】| 2023 U-Net V2 替换骨干网络,加强细节特征的提取和融合
|
5月前
|
机器学习/深度学习 PyTorch 算法框架/工具
CNN中的注意力机制综合指南:从理论到Pytorch代码实现
注意力机制已成为深度学习模型的关键组件,尤其在卷积神经网络(CNN)中发挥了重要作用。通过使模型关注输入数据中最相关的部分,注意力机制显著提升了CNN在图像分类、目标检测和语义分割等任务中的表现。本文将详细介绍CNN中的注意力机制,包括其基本概念、不同类型(如通道注意力、空间注意力和混合注意力)以及实际实现方法。此外,还将探讨注意力机制在多个计算机视觉任务中的应用效果及其面临的挑战。无论是图像分类还是医学图像分析,注意力机制都能显著提升模型性能,并在不断发展的深度学习领域中扮演重要角色。
184 10
|
7月前
|
编解码 Go 文件存储
【YOLOv8改进 - 特征融合NECK】 DAMO-YOLO之RepGFPN :实时目标检测的创新型特征金字塔网络
【YOLOv8改进 - 特征融合NECK】 DAMO-YOLO之RepGFPN :实时目标检测的创新型特征金字塔网络
|
4月前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLO11改进 - C3k2融合】C3k2融合YOLO-MS的MSBlock : 分层特征融合策略,轻量化网络结构
【YOLO11改进 - C3k2融合】C3k2融合YOLO-MS的MSBlock : 分层特征融合策略,轻量化网络结构

热门文章

最新文章

推荐镜像

更多