Jammy@Jetson Orin - Tensorflow & Keras Get Started: 003 Implementing a CNN in TensorFlow & Keras
1. 源由
根据前面《Jammy@Jetson Orin - Tensorflow & Keras Get Started: Convolutional Neural Network - A Complete Guide》介绍的CNN神经网络算法,这里将学习如何使用Keras从头开始实现一个卷积神经网络(CNN):展示了一个类似于VGG-16结构的CNN架构。
虽然层数较少,通过学习如何建模这个架构,并在名为CIFAR-10的小数据集上对其进行训练。我们还将利用这个机会介绍一种称为Dropout的新层类型,这种类型通常用于模型中以减轻过拟合的影响。
2. 举例 - CIFAR-10 CNN
2.1 获取CIFAR-10数据
CIFAR-10数据集包含来自10个类别的60,000张彩色图像,每个类别有6,000张图像。其中包括50,000张训练图像和10,000张测试图像。
2.2 展示CIFAR-10图像
下面展示了几张样本图像,以及它们对应的类别名称。
2.3 数据预处理
将图像数据标准化到范围[0,1]内。在处理图像数据时,这是非常常见的做法,有助于模型更有效地训练。我们还将整数标签转换为独热编码标签,如之前的几篇章节中所做的那样。
描述模型实现和训练之前,将通过使用Python中的dataclasses模块,创建简单的DatasetConfig和TrainingConfig类来为训练过程配置参数。这样做的好处是有一个地方可以去做任何想要的更改。
2.4 业务逻辑 - Keras建模
在深入讨论编码细节之前,让我们首先看一下我们提议的模型的一般结构。
该模型的结构与VGG-16相似,但层数较少,输入图像尺寸要小得多,因此可训练参数大大减少。该模型包含三个卷积块,后面跟着一个全连接层和一个输出层。
卷积神经网络模型,具体如下:
- 定义了一个函数 cnn_model(),它有一个可选参数 input_shape,默认为 (32, 32, 3),表示输入图像的形状为 32x32 像素,具有 3 个通道(RGB 彩色图像)。
- 使用 Sequential() 创建了一个序列模型。
- 添加了第一个卷积块:包括两个卷积层和一个最大池化层。每个卷积层都有 32 个滤波器,滤波器大小为 3x3,使用 ReLU 激活函数,填充方式为“same”。最大池化层的池化窗口大小为 2x2。
- 添加了第二个卷积块:与第一个卷积块类似,但滤波器数量增加到了 64。
- 添加了第三个卷积块:同样类似,滤波器数量仍为 64。
- 添加了一个展平层,将卷积层的输出展平成一维向量。
- 添加了一个具有 512 个神经元的全连接隐藏层,使用 ReLU 激活函数。
- 添加了一个具有 10 个神经元的输出层,使用 softmax 激活函数,用于进行多类别分类,输出每个类别的概率。
2.4.1 定义模型
2.4.2 编译模型
- 优化器:在Keras中使用RMSProp优化器。
- 损失函数:分类问题的首选损失函数是交叉熵。但是,根据标签的编码方式,需要指定适当形式的交叉熵损失函数。
2.4.3 训练模型
- batch_size批量的数据集
- epochs迭代的次数
- validation_split训练集分割,训练集/验证集
2.4.4 检查迭代损失渐进曲线
基线模型的结果显示出模型出现了过拟合。注意到在大约十个周期的训练后,验证损失开始增加,而训练损失继续下降。这意味着网络学习了如何很好地对训练数据进行建模,但对未见过的测试数据的泛化能力不佳。准确率图表显示了类似的趋势,在大约十个周期后,验证准确率趋于平稳,而训练准确率在训练过程中继续接近100%。这是训练神经网络时常见的问题,可能有多种原因造成。其中一个原因是,模型可以拟合训练数据集的细微差别,特别是当训练数据集很小时。
2.5 正则化技术 - Dropout
为了帮助缓解这个问题,我们可以采用一个或多个正则化策略来帮助模型更好地泛化。正则化技术有助于限制模型的灵活性,以防止其过度拟合训练数据。一种方法称为Dropout,在Keras中已经内置了它。Dropout在Keras中被实现为一种特殊的层类型,在训练过程中随机丢弃一定比例的神经元。当Dropout用于卷积层时,通常是在最大池化层之后使用,并且会消除特征图中一定比例的神经元。当Dropout用于全连接层之后时,会丢弃全连接层中一定比例的神经元。
2.5.1 定义模型
在每个卷积块的末尾以及分类器中的密集层后添加了一个dropout层。
Dropout函数的输入参数是在训练过程中从前一层中随机丢弃的神经元的比例。
2.5.2 编译模型
2.5.3 训练模型
2.5.4 检查迭代损失渐进曲线
2.6 模型对比 CNN with vs withou Dropout
训练曲线与验证曲线非常接近。
2.7 模型保存&加载
2.8 使用模型进行预测
3. 准确性评估 - 混淆矩阵
混淆矩阵是模型在类别级别上性能的信息丰富的表示。它可以非常详细地了解模型在哪些方面表现良好,以及在哪些方面可能存在更多困难。
例如,有几件事情立即引人注目。十个类别中有两个类别往往被误分类。
- 猫的实际标签为3,有182个错误分类的样本狗。
- 狗的实际标签为5,有134个样本猫。
- 卡车的标签为9,有81个样本汽车。
- 船的实际标签为8,有66个样本飞机。
- etc.
所有这些观察结果都在直觉上有意义,考虑到涉及的类别的相似性。
4. 总结
在本篇文章中
- 学习了如何使用TensorFlow和Keras定义和训练一个简单的卷积神经网络
- 展示了模型对训练数据进行了过拟合
- 学习了如何使用dropout层来减少过拟合并提高模型在验证数据集上的性能
- 还介绍了如何将模型保存到文件系统并从中加载
最后,我们回顾了三种用于评估模型在测试数据集上的技术。
测试代码:003_Keras-Implement-Simple-CNN