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


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

文章插图
 

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

文章插图
 
在处理图像和图像数据时,CNN是最常用的架构 。卷积神经网络已经被证明在深度学习和计算机视觉领域提供了许多最先进的解决方案 。没有CNN,图像识别、目标检测、自动驾驶汽车就不可能实现 。
但当归结到CNN如何看待和识别他们所做的图像时,事情就变得更加棘手了 。
· CNN如何判断一张图片是猫还是狗?
· 在图像分类问题上,是什么让CNN比其他模型更强大?
· 他们在图像中看到了什么?
这是我第一次了解CNN时的一些问题 。问题会随着你的深入而增加 。
那时候我听说过过滤器和特性映射,但不知道它们是什么,它们的作用是什么 。后来我知道他们是什么,但不知道他们长什么样子,但现在我知道了 。在处理深度卷积网络时,过滤器和特征映射很重要 。滤镜是使特征被复制的东西,也是模型看到的东西 。
什么是CNN的滤镜和特性映射?过滤器是使用反向传播算法学习的一组权值 。如果你做了很多实际的深度学习编码,你可能知道它们也被称作核 。过滤器的尺寸可以是3×3,也可以是5×5,甚至7×7 。
过滤器在一个CNN层学习检测抽象概念,如人脸的边界,建筑物的边缘等 。通过叠加越来越多的CNN层,我们可以从一个CNN中得到更加抽象和深入的信息 。
使用Pytorch和Matplotlib可视化卷积神经网络的特征

文章插图
 

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

文章插图
 
特性映射是我们通过图像的像素值进行滤波后得到的结果 。这就是模型在图像中看到的这个过程叫做卷积运算 。将feature map可视化的原因是为了加深对CNN的了解 。
使用Pytorch和Matplotlib可视化卷积神经网络的特征

文章插图
 
选择模型我们将使用ResNet-50神经网络模型来可视化过滤器和特征图 。使用ResNet-50模型来可视化过滤器和特征图并不理想 。原因是resnet模型总的来说有点复杂 。遍历内部卷积层会变得非常困难 。但是在本篇文章中您将了解如何访问复杂体系结构的内部卷积层后,您将更加适应使用类似的或更复杂的体系结构 。
我使用的图片来自pexels 。这是我为了训练我的人脸识别分类器而收集的一幅图像 。
使用Pytorch和Matplotlib可视化卷积神经网络的特征

文章插图
 
模型结构乍一看,模型的结构可能令人生畏,但要得到我们想要的东西确实很容易 。通过了解如何提取这个模型的层,您将能够提取更复杂模型的层 。下面是模型结构 。
ResNet((conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)(layer1): Sequential((0): Bottleneck((conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)...(2): Bottleneck((conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))(fc): Linear(in_features=2048, out_features=1000, bias=True)


推荐阅读