准备作业
这儿用到的是:
- tensorflow-cpu 2.4 版别
- python 3.8 版别
- anaconda 自带的 jupyter notebook
本文大纲
- 加载、展示、处理 CIFAR 图画数据
- 建立 CNN 模型架构
- 编译、练习模型
- 测验模型
加载、展示、处理 CIFAR 图画数据
(1)这儿国内下载数据可能会报错,所以需求提早在这儿下载好数据 www.cs.toronto.edu/~kriz/cifar… ,然后将压缩包名字改成 cifar-10-batches-py.tar.gz ,然后放到途径:你的主目录/.keras/datasets 下。
(2)CIFAR10 数据集包含 10 个种类,共 60000 张彩色图片,每类图片有 6000 张。此数据会集 50000 张图片被作为练习集,剩下 10000 张图片作为测验集。每个种类的图片集之间相互独立。
(3)咱们首要经过 datasets 读取到 CIFAR10 数据集,成果分成了两部分,练习集和测验集,每份数据会集有图片及其对应的标签。咱们首要对所有图片数据进行归一化处理,这么做的好处有两点,一是能够使数据有相同的散布,确保不同的图画经过 CNN 后提取的特征的散布基本上趋于一致,梯度下降就很快,从而加速模型收敛,别的可能在必定程度上提高模型的精度。
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
from tensorflow.keras import regularizers
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
train_images, test_images = train_images / 255.0, test_images / 255.0
(4)本数据会集的 10 中分类分别是 [‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’],在这儿咱们随意展现出来了 4 张图片,虽然有点模糊,但是大体是能够区分出来所属类别。
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
plt.figure(figsize=(4,4))
for i in range(100,104):
plt.subplot(2,2,i+1-100)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i])
plt.xlabel(class_names[train_labels[i][0]])
plt.show()
建立 CNN 模型架构
这儿首要是介绍模型架构组成,首要三个特征提取块,每个块中有卷积层、批正则化层、最大池化层,别的最终参加了 Dropout 层、全衔接层、分类输出层,每个特征提取块的详细情况都一样,以第一个特征提取块为例说明如下:
-
第一层首要是接纳巨细为 (32, 32, 3) 的图片,这儿的前两个维度是每张图片的长款像素数量,第三个维度是每个像素点的三个色彩通道,这儿首要运用了 64 个巨细都为 (3, 3) 的卷积核来完结图画的特征提取作业,总共的可练习参数有个。
-
第二层首要是过了防止过拟合设置批正则化,它先对数据做平移和伸缩改换,将数据伸缩到固定区间规模,其次能够加速模型练习时的收敛速度,使得模型练习进程愈加稳定,避免梯度爆破或者梯度消失,别的还能起到必定的正则化效果,现在几乎不必 Dropout 。其实这儿我有个问题,看下面的模型架构图中每个批正则化都有参数,这个是怎样算出来的呢?还有为什么不行练习的参数有 512 个?有知道的讨教教我。
-
第三层首要是进行了二维的最大池化操作,池化窗口巨细为 (2, 2), 池化层能够有效的缩小特征矩阵的尺度,从而削减最终衔接层的中的参数数量。所以参加池化层也能够加速计算速度和防止过拟合的效果。
-
后面运用了 Flatten 将每张图片的多维特征,压缩成一个长维度的特征,咱们在进行全衔接层之前还参加了 Dropout 就是为了防止过拟合,最终参加分类输出层进行类型 logit 的猜测。
model = models.Sequential([ layers.Conv2D(64, (3, 3), activation='relu', input_shape=(32, 32, 3)), layers.BatchNormalization(), layers.MaxPooling2D((2, 2)), layers.Conv2D(128, (3, 3), activation='relu'), layers.BatchNormalization(), layers.MaxPooling2D((2, 2)), layers.Conv2D(64, (3, 3), activation='relu'), layers.BatchNormalization(), layers.MaxPooling2D((2, 2)), layers.Flatten(), layers.Dropout(0.5), layers.Dense(32, activation='relu'), layers.Dense(10) ]) model.summary()
成果打印:
Model: "sequential_6"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_21 (Conv2D) (None, 30, 30, 64) 1792
batch_normalization_3 (Batc (None, 30, 30, 64) 256
hNormalization)
max_pooling2d_17 (MaxPoolin (None, 15, 15, 64) 0
g2D)
conv2d_22 (Conv2D) (None, 13, 13, 128) 73856
batch_normalization_4 (Batc (None, 13, 13, 128) 512
hNormalization)
max_pooling2d_18 (MaxPoolin (None, 6, 6, 128) 0
g2D)
conv2d_23 (Conv2D) (None, 4, 4, 64) 73792
batch_normalization_5 (Batc (None, 4, 4, 64) 256
hNormalization)
max_pooling2d_19 (MaxPoolin (None, 2, 2, 64) 0
g2D)
flatten_5 (Flatten) (None, 256) 0
dropout_7 (Dropout) (None, 256) 0
dense_10 (Dense) (None, 32) 8224
dense_11 (Dense) (None, 10) 330
=================================================================
Total params: 159,018
Trainable params: 158,506
Non-trainable params: 512
编译、练习模型
这儿就是运用练习集和测验集进行模型的练习和验证,速度还是有点慢的,经过打印的成果咱们能够看到,最终 accuracy 和 val_accuracy 都在正常进行,基本没有呈现过拟合或者欠拟合的危险,仅仅模型的结构还是很单薄,所以最终的准确率只要 75% 上下,如果用其它专业的大模型,准确率应该在 98% 以上。
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels))
成果打印:
Epoch 1/10
1563/1563 [==============================] - 110s 70ms/step - loss: 1.5976 - accuracy: 0.4294 - val_loss: 1.4839 - val_accuracy: 0.4570
Epoch 2/10
1563/1563 [==============================] - 110s 71ms/step - loss: 1.2001 - accuracy: 0.5744 - val_loss: 1.3931 - val_accuracy: 0.5108
......
Epoch 9/10
1563/1563 [==============================] - 114s 73ms/step - loss: 0.7181 - accuracy: 0.7515 - val_loss: 0.7916 - val_accuracy: 0.7275
Epoch 10/10
1563/1563 [==============================] - 112s 71ms/step - loss: 0.6840 - accuracy: 0.7612 - val_loss: 0.7671 - val_accuracy: 0.7367
这儿首要展现的是整个练习进程中的,练习集和验证集各自准确率的发展趋势,一般咱们能够从图中的曲线能够得知练习的整体情况,如果不符合预期能够进行数据或者模型或者参数的调整,如果符合预期,则能够进行下一步的推理或者猜测。
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0.5, 1])
plt.legend(loc='lower right')
plt.show()
测验模型
运用测验集进行模型的测验作业,由于之前验证集和测验集用的是同一份数据,所以最终的准确率必定和练习进程的最终的 val_accuracy 是一样的。那么到这儿为止,运用卷积神经网络进行 CIFAR 图画的分类使命就告一段落了。
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(test_acc)
成果打印:
313/313 - 5s - loss: 0.7671 - accuracy: 0.7367 - 5s/epoch - 15ms/step
0.7366999983787537