【项目04】卷积神经网络的结构设计与实现

作者:欧新宇(Xinyu OU)
开发平台:Paddle 2.1
运行环境:Intel Core i7-7700K CPU 4.2GHz, nVidia GeForce GTX 1080 Ti

本教案所涉及的数据集仅用于教学和交流使用,请勿用作商用。

最后更新:2021-08-01


随着网络的加深,卷积神经网络的设计变得越来越复杂。但是,仔细观察可以发现有一些层的结构是规律的,例如Resnet结构,Inception结构等。下面我们将从最简单的**LeNet-5**和**AlexNet**开始,简要说明如何在Paddle中进行CNN网络结构的设计与实现。

特别注意:本例基于paddle.fluid库进行设计,虽然这种设计方法在目前的 "1+X"计算机视觉证书(中级) 中依然被使用,但需要注意的是,根据百度的规划paddle.fluid将在后期的版本中被移除。

0. 知识准备

在设计卷积神经网络的时候,常见类包括卷积层Conv2D,池化层Pool2D,全连接层Linear。

class paddle.fluid.dygraph.Conv2D(num_channels, num_filters, filter_size, stride=1, padding=0, dilation=1, groups=None, param_attr=None, bias_attr=None, use_cudnn=True, act=None, dtype='float32')
class paddle.fluid.dygraph.Pool2D(pool_size=-1, pool_type='max', pool_stride=1, pool_padding=0, global_pooling=False, use_cudnn=True, ceil_mode=False, exclusive=True)
class paddle.fluid.dygraph.Linear(input_dim, output_dim, param_attr=None, bias_attr=None, act=None, dtype='float32')

【知识点】

1. LeNet-5模型

下面以LeNet-5为例进行网络拓扑结构的设计:

1.1 网络拓扑结构图及网络参数配置表

Handout0601

Layer Input Kernel_num Kernel_size Stride Padding PoolingType Output Parameters
Input 1×32×32
Conv1 1×32×32 6 1×5×5 1 0 6×28×28 (1×5×5+1)×6=156
Pool1 6×28×28 6 6×2×2 2 0 max 6×14×14 0
Conv2 6×14×14 16 6×5×5 1 0 16×10×10 (6×5×5+1)×16=2416
Pool2 16×10×10 16 16×2×2 2 0 max 16×5×5 0
Conv3 16×5×5 120 16×5×5 1 0 120×1×1 (16×5×5+1)×120=48120
FC1 (120×1×1)×1 84×1 (120+1)×84=10164
FC2 84×1 10×1 (84+1)×10=850
Output 10×1
Total = 61706

Conv: Output_size = (Input_size - Kernel_size + 2*Padding)/Stride + 1
Pool: Output_size = Input_size/Stride

1.2 定义神经网络类

1.3 网络结构测试

2. AlexNet模型

AlexNet模型[1],由多伦多大学的Geffery Hinton教授的学生Krizhevsky Alex提出。

[1] Alex Krizhevsky, Ilya Sutskever, Geoffrey E. Hinton. ImageNet classification with deep convolutional neural networks. International Conference on Neural Information Processing Systems. Curran Associates Inc. 2012:1097-1105.

2.1 网络拓扑结构图及网络参数配置表

Ch04assign001

需要注意的是,在大多数深度学习工具包中,Alexnet的输入尺度会被Crop为$3×227×227$。如果按照原始论文中$3×224×224$的尺度进行输入,需要适当调节网络的参数。

Layer Input Kernel_num Kernel_size Stride Padding PoolingType Output Parameters
Input 3×227×227
Conv1 3×227×227 96 3×11×11 4 0 96×55×55 (3×11×11+1)×96=34944
Pool1 96×55×55 96 96×3×3 2 0 max 96×27×27 0
Conv2 96×27×27 256 96×5×5 1 2 256×27×27 (96×5×5+1)×256=614656
Pool2 256×27×27 256 256×3×3 2 0 max 256×13×13 0
Conv3 256×13×13 384 256×3×3 1 1 384×13×13 (256×3×3+1)×384=885120
Conv4 384×13×13 384 384×3×3 1 1 384×13×13 (384×3×3+1)×384=1327488
Conv5 384×13×13 256 384×3×3 1 1 256×13×13 (384×3×3+1)×256=884992
Pool5 256×13×13 256 256×3×3 2 0 max 256×6×6 0
FC6 (256×6×6)×1 4096×1 (9216+1)×4096=37752832
FC7 4096×1 4096×1 (4096+1)×4096=16781312
FC8 4096×1 1000×1 (4096+1)×1000=4097000
Output 1000×1
Total = 62378344

其中, 卷积层参数:3747200,占总参数的6%; 全连接层参数:58631144, 占总参数94%。

2.2 标准网络结构设计

2.2.1 定义神经网络类

2.2.2 网络结构测试

2.2.3 测试前向传输

2.3 模块化网络结构设计

从Alexnet开始,包括VGG,GoogLeNet,Resnet等模型都是层次较深的模型,如果按照逐层的方式进行设计,代码会变得非常繁琐。因此,我们可以考虑将相同结构的模型进行汇总和合成,例如Alexnet中,卷积层+激活+池化层就是一个完整的结构体。