>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客**
>- **🍖 原作者:[K同学啊](https://mtyjkh.blog.csdn.net/)**
我的环境:
语言环境:python 3.11.5
编译器:Spyder
深度学习环境:Tensorflow 2.12.0
一、导入需要的包 & 加载数据
from tensorflow.keras import datasets, models, layers, losses
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
二、归一化
train_images, test_images = train_images / 255.0, test_images / 255.0
test_images.shape #看一眼形状,还可以加test_label, train的image和label
In [2]: test_images.shape
Out[2]: (10000, 32, 32, 3)
三、pyplot 可视化
class_names = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]
plt.Figure(figsize=(20, 10))
for i in range(20):
plt.subplot(5, 10, i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i], cmap=plt.cm.binary)
plt.xlabel(class_names[train_labels[i][0]])
#plt.show() #spyder里删了好像也不影响
输出图片:
四、构建cnn模型
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation = "relu", input_shape = (32, 32, 3)),
layers.MaxPooling2D(2, 2),
layers.Conv2D(64, (3, 3), activation = "relu"),
layers.MaxPooling2D(2, 2),
layers.Conv2D(128, (3, 3), activation = "relu"),
layers.Flatten(),
layers.Dense(128, activation = "relu"),
layers.Dense(10)
])
然后看一眼模型长啥样
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 30, 30, 32) 896
max_pooling2d (MaxPooling2D (None, 15, 15, 32) 0
)
conv2d_1 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_1 (MaxPooling (None, 6, 6, 64) 0
2D)
conv2d_2 (Conv2D) (None, 4, 4, 128) 73856
flatten (Flatten) (None, 2048) 0
dense (Dense) (None, 128) 262272
dense_1 (Dense) (None, 10) 1290
=================================================================
Total params: 356,810
Trainable params: 356,810
Non-trainable params: 0
_________________________________________________________________
五、编译
model.compile(
optimizer = "adam",
loss = losses.SparseCategoricalCrossentropy(from_logits = True),
metrics = ['accuracy']
)
p.s. 提升准确率的话这里其实也能改,但增加一下神经元的个数已经可以达到72%以上了,所以没改hhhh
六、训练模型
history = model.fit(
train_images,
train_labels,
epochs = 8,
validation_data = (test_images, test_labels)
)
p.s. 没有checkpoint和earlystopping,然后本来是10轮,在第8轮表现最好,这里epochs就用8了,没什么特定含义。
输出:
Epoch 1/8
1563/1563 [==============================] - 17s 11ms/step - loss: 1.4347 - accuracy: 0.4799 - val_loss: 1.1499 - val_accuracy: 0.5894
Epoch 2/8
1563/1563 [==============================] - 16s 10ms/step - loss: 1.0467 - accuracy: 0.6297 - val_loss: 0.9988 - val_accuracy: 0.6528
Epoch 3/8
1563/1563 [==============================] - 17s 11ms/step - loss: 0.8784 - accuracy: 0.6914 - val_loss: 0.8772 - val_accuracy: 0.6952
Epoch 4/8
1563/1563 [==============================] - 17s 11ms/step - loss: 0.7623 - accuracy: 0.7329 - val_loss: 0.8501 - val_accuracy: 0.7092
Epoch 5/8
1563/1563 [==============================] - 17s 11ms/step - loss: 0.6764 - accuracy: 0.7643 - val_loss: 0.8036 - val_accuracy: 0.7279
Epoch 6/8
1563/1563 [==============================] - 17s 11ms/step - loss: 0.6008 - accuracy: 0.7896 - val_loss: 0.8840 - val_accuracy: 0.7077
Epoch 7/8
1563/1563 [==============================] - 17s 11ms/step - loss: 0.5250 - accuracy: 0.8153 - val_loss: 0.8368 - val_accuracy: 0.7266
Epoch 8/8
1563/1563 [==============================] - 18s 11ms/step - loss: 0.4555 - accuracy: 0.8391 - val_loss: 0.9065 - val_accuracy: 0.7213
七、画个accuracy和loss
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.0])
plt.legend(loc = "lower right")
plt.show()
输出图片
八、测试模型
test_loss, test_acc = model.evaluate(
test_images,
test_labels,
verbose = 2
)
313/313 - 1s - loss: 0.9065 - accuracy: 0.7213 - 1s/epoch - 4ms/step
p.s. 这里val_accuracy已经达到72%了,任务完成!
九、拿出一张图来pred一下
pre = model.predict(test_images)
print(class_names[np.argmax(pre[2])])
plt.imshow(test_images[2])
In [2]: print(class_names[np.argmax(pre[2])])
Out[2]: ship
十、总结
彩色图片不同于灰度图片,由于RGB混合,图片会有三个维度,灰度图片只有一个维度,这是在模型的input shape里就体现出来的。然后要求里说要把准确率提升到72%,所以投机取巧了一下,只增加了第三个卷积层和全连接层的神经元就完成任务了,第二次已经了解简单cnn的程序和结构,希望之后的学习能深化理解。