CNN网络结构——池化层和全连接层

池化层

为什么引入池化层

通常,卷积层的超参数设置为:输出特征图的空间尺寸等于输入特征图的空间尺寸。这样如果卷积网络里面只有卷积层,特征图空间尺寸就永远不变。虽然卷积层的超参数数量与特征图空间尺寸无关,但这样会带来一些缺点。

  1. 空间尺寸不变,卷积层的运算量会一直很大,非常消耗资源。
  2. 卷积网络结构最后是通过全连接层输出分值向量的,如果空间尺寸一直不变,则全连接层的权重数量会非常巨大,导致过拟合。
  3. 前面几层的卷积层的输出存在大量冗余,如果空间尺寸不变,则冗余会一直存在,因此需要一种技巧来减小空间尺寸。

概述

池化是一种最常用的减小空间尺寸的技巧,它可以对输入的每一个特征图独立地降低其空间尺寸,而保持深度维度不变。
首先对特征图的每个局部窗口数据进行融合,得到一个输出数据,然后采用大于1的步长扫描特征图。最常见的局部窗口尺寸是2×2,有时也会采用3×3,步长是2会去除75%的神经元,步长如果采用3,则会去除88.89%的神经元,这过于剧烈,实践中不会采用。
池化层方法:

  1. 取平均
  2. 取最大值(常用)

下图展示了池化层操作示意图,输入特征图尺寸4×4×3被降采样到了2×2×3,采取的滤波器尺寸是2,步长为2。采用最大值池化,2×2的局部区域选取最大值。

池化层中很少使用0填充,因为本身就是为了减少图像尺寸。
卷积层同样可以达到池化层的效果来减少图像尺寸,通过调大步长即可。

为什么采用最大值方法

这是因为卷积层后接ReLU激活,ReLU激活函数把负值都变为0,正值不变,所以神经元的激活值越大,说明该神经元对输入局部窗口数据的反应越激烈,提取的特征越好。用最大值代表局部窗口的所有神经元,是很合理的。最大值操作还能保持图像的平移不变性,同时适应图像的微小变形和小角度旋转。

实现过程

池化层将每个局部窗口的数据转化为小矩阵,按行堆叠成大矩阵,然后每行取最大值得到大的列向量,最后转化为3D特征图。

  1. 输入3D特征图转化为矩阵X:局部区域转化为小矩阵。比如,输入是56×56×96,局部窗口尺寸为2×2,步长为2进行池化,取输入中的2×2×96局部数据块,将其转化为尺寸为96×4的小矩阵,注意是将96维的深度向量拉伸为一个列向量,共有4个深度向量。以步长为2扫描每一个局部窗口,所以输出的宽高均为(56-2)//2+1=28,共有28×28=784个局部窗口,784×96=75264个行向量,输出矩阵X的尺寸是75264×4。
  1. 最大值池化:提取大矩阵每行的最大值,matric_data. max(axis=1,keepdims=True),即得到每个局部窗口的最大值。在本例中,这个操作的输出是大列向量 [75264×1]。
  1. 输出新3D特征图28×28×96,大列向量的每96个元素构成输出3D特征图的一个深度向量。

全连接层

概述

如果卷积网络输入是224×224×3的图像,经过一系列的卷积层和池化层(因为卷积层增加深度维度,池化层减小空间尺寸),尺寸变为7×7×512,之后需要输出类别分值向量,计算损失函数。假设类别数量是1000(ImageNet是1000类),则分值向量可表示为特征图1×1×1000。如何将7×7×512的特征图转化为1×1×1000的特征图呢?最常用的技巧是全连接方式,即输出1×1×1000特征图的每个神经元(共1000个神经元)与输入的所有神经元连接,而不是局部连接。每个神经元需要权重的数量为7×7×512=25088,共有1000个神经元,所以全连接层的权重总数为:25088×1000=25088000,参数如此之多,很容易造成过拟合,这是全连接方式的主要缺点。

全连接层的实现方式有两种。一种方式是把输入3D特征图拉伸为1D向量,然后采用常规神经网络的方法进行矩阵乘法;另一种方式是把全连接层转化成卷积层,这种方法更常用,尤其是在物体检测中。

全连接转为卷积

全连接层和卷积层中的神经元都是计算点积和非线性激活,函数形式是一样的,唯一的差别在于卷积层中的神经元只与输入数据中的一个局部区域连接,并且采用参数共享;而全连接层中的神经元与输入数据中的全部区域都连接,并且参数各不相同。因此,两者是可能相互转化的。

  • 卷积层转换为全连接层

将不是局部区域的权重全部设为0即可。

  • 全连接层转化为卷积层

比如,一个全连接层,输入特征图是7×7×512,输出特征图是1×1×1000,这个全连接层可以等效为一个卷积层:F=7, P=0,S=1, K=1000。即将卷积核的尺寸设置为和输入特征图的空间尺寸一致,不需要0填充,也不需要滑动卷积窗口,所以输出空间尺寸为1,只有一个单独的深度向量,所以输出变成1×1×1000。

(batch,in_height,in_width,in_depth) = (8,32,48,16)
size = in_depth*in_height,in_width  #一张图片拉伸为1D的大小
in_data = np,random.randn(batch,in_height,in_width,in_depth)
matrice_data = np.zeros((batch,size))
for i in range(batch):
    matrice_data[i] = in_data[i].ravel()   #拉伸为一维
out_depth = 10 #最后分成10类
kerns = np.random.randn(size,out_depth)
bians = np.random.randn(1,out_depth)
filter_data = np.dot(matrice_data,kerns) + bians
out_data = np.maximum(0,filter_data)  #Relu激活

卷积网络的结构总结

卷积网络的3种基本模块:卷积层(CONV)、池化层(POOL,默认最大值池化)和全连接层(FC)。卷积层和全连接层后面都需紧接ReLU激活层,但必须注意的是,最后一个全连接层后面不需接ReLU激活层。

层的组合模式

卷积网络最基本的结构是:先堆叠一个或多个卷积层进行特征提取,然后接一个池化层进行空间尺寸缩小,之后重复此模式,直到空间尺寸足够小(如7×7和5×5),最后接多个全连接层,其中最后一个全连接层输出类别分值。

  • 小技巧
  1. 输入图像的空间尺寸常用的是32(CIFAR-10)、64、96(STL-10)、224(ImageNet)、384和512,这些尺寸能被2整除很多次。
  2. 卷积层使用小尺寸卷积核(3×3),步长S=1,如果必须使用大的卷积核(5×5或者7×7),通常只用在第一个卷积层中,其输入是原始图像,且仅使用一次。
  3. 池化层对特征图进行空间降采样,最常用的是2×2感受野的最大值池化,步长为2,另一个不常用的是3×3感受野,步长为2。
### 绘制卷积神经网络结构图的方法 为了有效地展示卷积神经网络(CNN)的架构,包括卷积层、池化层以及全连接层,可以通过图形工具或编程库来创建可视化的表示形式。以下是几种方法: #### 使用绘图软件手动绘制 对于初学者来说,最简单的方式可能是通过像Microsoft Visio、Adobe Illustrator这样的矢量图形编辑器手工画出每一层及其之间的联系。 #### 利用Python库自动化生成图表 更高效的做法是采用专门用于机器学习模型可视化的Python包,比如`matplotlib`配合`networkx`,或者是专门为深度学习设计的`plot_model()`函数(来自Keras API),还有其他一些流行的选项如TensorBoard中的Graph Visualization功能。 下面是一个简单的例子,展示了如何使用MatplotlibNetworkX组合起来制作一个基本版本的CNN结构图: ```python import matplotlib.pyplot as plt import networkx as nx def draw_cnn_structure(): G = nx.DiGraph() # Add nodes with labels representing different layers of a CNN. node_labels = { 'input': "Input\nLayer", 'conv1': "Convolutional\nLayer 1", 'pool1': "Pooling\nLayer 1", 'fc': "Fully Connected\nLayer" } for label in node_labels.keys(): G.add_node(label) edges = [ ('input', 'conv1'), ('conv1', 'pool1'), ('pool1', 'fc') ] G.add_edges_from(edges) pos = {'input': (0, 0), 'conv1': (-1,-2),'pool1':(-2,-4), 'fc':(0,-6)} fig, ax = plt.subplots(figsize=(8, 6)) nx.draw_networkx_nodes(G, pos, node_size=7000,node_color='lightblue') nx.draw_networkx_edges(G, pos, width=2,alpha=0.5,edge_color='black') nx.draw_networkx_labels(G, pos,labels=node_labels, font_size=12) plt.title('Simplified Structure Diagram of Convolutional Neural Network') plt.axis('off') plt.show() draw_cnn_structure() ``` 这段代码会生成一张简化版的CNN结构图,其中包含了输入层、单个卷积层、池化层以及最终的全连接层。当然,在实际应用中可能还需要考虑更多细节,例如多个卷积/池化单元堆叠的情况,或者加入批标准化(batch normalization)等额外组件[^1]。 此外,如果想要更加精确地反映特定CNN的设计,则可以根据具体需求调整上述模板,增加更多的节点代表各个子模块,并设置合适的边权重以体现数据流方向强度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值