第04讲 卷积神经网络

作者:欧新宇(Xinyu OU)

本文档所展示的测试结果,均运行于:Intel Core i7-7700K CPU 4.2GHz, nVidia GeForce GTX 1080 Ti


建设中...

第四部分 我的第一个卷积神经网络(CNN)

4.1 网络模型的设计与分析

在设计卷积神经网络的时候,常见类包括卷积层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')

【知识点】

4.1.1 模型一 (LeNet-5)

- 网络拓扑结构图

Ch04assign001

- 网络参数配置表

Layer Input Kernels_num Kernels_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

- 定义神经网络类

- 输出网络各层的超参数

4.1.2 模型二 (MNIST)

LeNet-5的原始属于是32×32,但是由于MNIST数据集的样本为28×28,因此需要对LeNet-5进行一定的调整。此次我们暂定调整后的网络名称为MNIST。

- 网络拓扑结构图

Ch04assign001LeNetA

- 网络参数配置表

Layer Input Kernels_num Kernels_size Stride Padding PoolingType Output Parameters
Input 1×28×28 1×28×28
Conv1 1×28×28 6 1×5×5 1 0 6×24×24 (1×5×5+1)×6=156
Pool1 6×24×24 6 6×2×2 2 0 Max 6×12×12 0
Conv2 6×12×12 16 6×5×5 1 0 16×8×8 (6×5×5+1)×16=2416
Pool2 16×8×8 16 16×2×2 2 0 Max 16×4×4 0
Conv3 16×4×4 120 16×4×4 1 0 120×1×1 (16×4×4+1)×120=30720
FC1 (120×1×1)×1 120×1 (120+1)×64=7744
FC2 120×1 84×1 (84+1)×10=650
Output 84×1 10×1
Total = 41686

- 定义神经网络类

- 输出网络各层的超参数

4.1.3 模型三 (CIFAR10)

- 网络拓扑结构图

Ch04assign002CIFAR10

- 网络参数配置表

Layer Input Kernels_num Kernels_size Stride Padding PoolingType Output Parameters
Input 3×32×32 3×32×32
Conv1 3×32×32 32 3×5×5 1 0 32×28×28 (3×5×5+1)×32=2432
Pool1 32×28×28 32 32×2×2 2 0 Max 32×14×14 0
Conv2 32×14×14 32 32×5×5 1 0 32×10×10 (32×5×5+1)×32=25632
Pool2 32×10×10 32 32×2×2 2 0 Avg 32×5×5 0
Conv3 32×5×5 64 32×4×4 1 0 64×2×2 (32×4×4+1)×64=32832
Pool3 64×2×2 64 64×2×2 2 0 Avg 64×1×1 0
FC1 (64×1×1)×1 64×1 (64+1)×64=4160
FC2 64×1 64×10 (64+1)×10=650
Output 10×1
Total = 65706

- 定义神经网络类

- 输出网络各层的超参数

4.1.4 模型四 (Alexnet)

- 网络拓扑结构图

Ch04assign001

需要注意的是,在Alexnet中实际输入的尺度会被Crop为$3×227×227$

- 网络参数配置表

Layer Input Kernels_num Kernels_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%。

- 定义神经网络类

4.2 数据准备(数据输入及预处理)

数据载入分为两个阶段,首先是数据载入,其次是对载入的数据进行预处理。

  1. 从paddle.dataset类中载入数据
  2. 从图片集中获取数据

4.2.1 从paddle.dataset类中载入数据

直接从paddle.dataset中载入数据是比较简单的,paddle写好了所有的载入代码和预处理代码。因此,通常使用该方法进行载入,不需要再进行预处理了。

4.2.2 从图片集中获取数据

拿到样本后,首先需要做以下几件事:

  1. 对样本进行一定的处理,删除部分无用的数据或者噪声数据
  2. 对合适的数据进行编号,生成数据列表
  3. 对训练和测试数据进行预处理
  4. 生成数据提供器
- 生成数据列表
- 对数据进行预处理
- 生成数据提供器
train_reader = paddle.batch(paddle.reader.shuffle(reader=data_reader(train_list), buf_size=512), batch_size=128, drop_last=False)
test_reader = paddle.batch(paddle.reader.shuffle(reader=data_reader(test_list), buf_size=512), batch_size=128, drop_last=False)

4.2.3 查看数据集中的数据

- 以单个样本的形式进行查看

VehicleLicese数据集是从图片进行采集,因此获取到的batchdata是以文件路径的形式存在, 因此需要进行预处理,手动将样本路径转换为$样本数组=[图像, 标签]$;而mnist和cifar直接从paddle.dataset中获取,因此获取到的batchdata是以数组的形式存在。

- 以batch的形式进行查看

以batch形式进行查看,需要使用enumerate()进行枚举, 每次从总数据中取一个batch进行处理. 此处仅做简化显示,详细使用可以参考单样本查看来显示图像.

4.3 函数化的编程方法(模型训练)

  1. 定义测试函数:def test(model)
  2. 定义训练函数:def train(model)
  3. 执行训练: train(model)
  4. 执行测试: test(model)

4.4 模型预测(应用)

  1. 导入依赖、全局参数配置
  2. 载入数据: 数据获取、数据预处理
  3. 模型载入: 模型参数载入、模型定义
  4. 执行预测: 输出预测结果