# 实验四：深度学习实践
# 利用 Keras 构建 CNN 模型分类 CIFAR10 数据集，归一化训练集与测试集数据，
# 调整两层卷积层的参数，将训练集准确率提高到不小于 0.72，并打印模型概况。

# 导入外部库和 CIFAR10 数据集
import tensorflow as tf
import matplotlib.pyplot as plt
from sklearn import metrics

cifar10 = tf.keras.datasets.cifar10
(X_train, y_train), (X_test, y_test) = cifar10.load_data()

# 建立映射表
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

# 显示训练集前面 20 个图像和标签
plt.figure(figsize=(10, 9))
num = 20
for i in range(0, num):
    plt.subplot(4, 5, i + 1)
    plt.imshow(X_train[i])
    plt.xticks([])
    plt.yticks([])
    plt.title("True=" + str(class_names[y_train[i][0]]))
    plt.savefig('20.jpg')
plt.show()

# 归一化数字图像（空 1、空 2）
X_train_norm, X_test_norm = X_train / 255.0, X_test / 255.0

# 构建 Sequential 模型（空 3）
model = tf.keras.models.Sequential()

# 构造卷积神经网络
# 构建卷积层
model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
# 构建池化层
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
# 构建卷积层
model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu'))
# 构建池化层
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
# 构建 Dropout 层
model.add(tf.keras.layers.Dropout(rate=0.2))
# 构建全连接层
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(80, activation='relu'))
# 输出层：CIFAR10 共 10 个类别（空 4）
model.add(tf.keras.layers.Dense(10, activation='softmax'))

# 打印模型的概况（空 5）
print(model.summary())

# 模型编译
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 模型训练（空 6）
history = model.fit(X_train_norm, y_train, validation_split=0.1, epochs=20, verbose=1)

# 模型评估（空 7）
model.evaluate(X_test_norm, y_test, verbose=1)
