零基础也能会:利用卷积神经网络(CNN)可视化特征图和滤波器
为让大家能够从零掌握深度学习的相关知识,学姐开启了pytorch构建深度学习模型系列知识整理。前面已经更新过两篇,错过的可要回去看一看哦——《用Pytorch理解深度学习模型中的张量维度》《AI入门必读|Pytorch神经网络设计的基本概念综述》,今天我们来学习第三篇。
咳咳,干货开始,不要眨眼!

初步认识CNN
卷积神经网络是一种特殊类型的人工神经网络,广泛应用于图像识别。这种架构的成功始于 2015年,当时凭借这种方法赢得ImageNet图像分类挑战。
你可能知道,这些方法在进行预测方面非常强大,但同时,它们很难理解。
比如说,有一些模型不可知的方法,如LIME和部分依赖图,可以应用于任何模型。但在这种情况下,应用专为神经网络开发的可解释方法更有意义。与ML模型不同的是,卷积神经网络从原始图像像素学习抽象特征。
在这篇文章中,通过逐步学习特征的可视化来说明卷积神经网络如何学习特征。在用Pythorch实现之前,首先会简单解释CNN是如何工作的,然后可视化CNN分类任务训练学习到的Feature map和Receptive fields(感受野)。
01 什么是CNN?

CNN由构建块组成:卷积层、池化层和全连接层。卷积层使用来自数据集的多个滤波器,来实现其主要功能——提取特征或所谓的特征图。
来自卷积操作的特征图的维数被池化层降低。最常用的池化操作是Maxpooling,它在特征图的每个滤波器补丁中选择最重要的像素值。因此,这两种类型的层对于执行特征提取很有用。
与卷积层和池化层不同的是,全连接层将提取的特征映射到最终输出中,例如,将MNIST 的图像分类为10位数字之一。
在数字图像中,二维网格存储像素值,可以被看作是一个数字数组;内核是一个小网格,通常大小为3x3,应用于图像的每个位置,随着进入更深的层次,这些功能会变得越来越复杂。
该模型的性能是使用损失函数获得的,损失函数是输出和目标标签之间的差异,通过在训练集上进行前向传播,并且使用梯度下降算法通过反向传播更新参数,例如权重和偏差。
02 在MNIST数据集上定义和训练CNN
首先导入库和数据集。torch是一个为一维或多维张量提供数据结构的模块。
重要的库有:
torchvision 包括流行的数据集,著名的模型架构和常见的图像转换。在本文的例子中,它提供了MNIST数据集。
torch.nn 用来构建卷积神经网络的类和函数。
torch.optim提供所有优化器,如Adam。
torch.nn.functional 用于导入函数,如dropout、卷积、pooling、非线性激活函数和loss函数。
下载训练和测试数据集,并将图像数据集转换为Tensor(张量),不需要对图像进行标准化,因为数据集已经包含灰度图像。在将训练数据集分为训练集和验证集之后,random_split为这两个集合提供了一个随机划分分区。
DataLoader用于为训练、验证和测试集创建数据加载器,这些数据加载器被分成小批。batchsize是模型训练期间一次迭代中使用的样本数。

定义CNN架构:
print CNN 快速预览一下:

可以看到有两个卷积层和两个完全连接的层,每个卷积层后面是ReLU激活函数和maxpooling层。view function()将数据重塑为一维数组,该数组将被传递给线性层;第二个全连接层,也称为输出层,将图像分类为 10 个数字之一。
定义用于训练CNN的构建块:
torch.device 使用GPU等硬件加速器训练模型
CNN network, 被移动到设备
交叉熵损失函数和Adam优化器
Now, 在训练集上训练网络并在验证集上对其进行评估:

训练代码可以分为两部分
前向传播:
我们将输入图像传递给带有model(images)的网络。
损失是通过调用criterion(outputs,labels)其中输出构成预测类和标签构成目标类来计算的。
反向传播:
梯度被清除,以确保我们不会用optimizer.zero_grad()累积其他值。
loss.backward()用于执行Back Propagation,并根据损失计算梯度。
optimizer.step()总是在梯度计算之后。它迭代所有参数并更新它们的值。
为训练集和验证集计算损失函数和准确性。
03 在测试集上评估模型
模型训练好后,我们可以评估测试集上的性能:

将测试代码分解来看:
torch.no_grad() 用来禁用梯度跟踪,我们不再需要计算梯度,因为模型已经训练好了。
将输入图像传递给网络。
通过添加loss.item()*images.size(0)来计算测试损失。
通过添加(predicted==labels).sum().item()来计算测试精度。
04 可视化滤波器
我们可以可视化学习到的滤波器,CNN 使用这些滤波器来卷积包含从前一层提取的特征的特征图。可以通过迭代模型的所有层来获得这些滤波器, list(model.children())。
如果该层是卷积层,我们可以将权重存储在model_weights列表中,该列表将包含在两个卷积层中使用的滤波器。

下面是找到的滤波器的形状:

现在, 可视化第一个卷积层的学习滤波器:

下面可视化第二个卷积层的滤波器:

05 可视化特征图
Feature Map,也称为Activation Map,是通过卷积操作得到的,并使用filter/kernel应用于输入数据。下面,定义一个函数来提取应用激活函数后得到的特征。
从训练数据集中,获取代表数字9的图像,并在第一个卷积层中可视化为该图像获得的特征图。

下面在第二个卷积层中为同一图像获得的特征图可视化:

END 总结
如果你能看到这里,那真的是很强了!至少在忍耐枯燥的学习这方面,已经慢慢转变为乐趣了!
如果你跟着练习了一遍,那大概率你已经掌握了使用Pytorch将CNN学习到的特征可视化。网络在其卷积层中学习新的和日益复杂的特征。从第一个卷积层到第二个卷积层,你可以看到这些特征的差异。在卷积层中走得越远,特征就越抽象。
学习难题,职业规划,缺少资料,打比赛组队来找学姐!

代码:
https://github.com/eugeniaring/Pytorch-tutorial/blob/main/CNN_mnist.ipynb
原文:
https://medium.com/dataseries/visualizing-the-feature-maps-and-filters-by-convolutional-neural-networks-e1462340518e
参考文档:
https://christophm.github.io/interpretable-ml-book/cnn-features.html#feature-visualization
https://insightsimaging.springeropen.com/articles/10.1007/s13244-018-0639-9
https://github.com/eugeniaring/Pytorch-tutorial/blob/main/CNN_mnist.ipynb
三连一下,鼓励学姐一下吧!如果文中有错误欢迎指出鸭!