import numpy as np
import pandas as pd
from keras.datasets import mnist
# X_train_image: 训练集特征 —— 图片
# y_train_label: 训练集标签 —— 数字
# X_test_image: 测试集特征 —— 图片
# X_test_label: 测试集标签 —— 数字
(X_train_image, y_train_label), (X_test_image, y_test_label) = mnist.load_data()
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11490434/11490434 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step
print("数据集张量形状:", X_train_image.shape)
print("第一个数据样本:\n", X_train_image[0])
数据集张量形状: (60000, 28, 28)
第一个数据样本:
[[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126 136
175 26 166 255 247 127 0 0 0 0]
[ 0 0 0 0 0 0 0 0 30 36 94 154 170 253 253 253 253 253
225 172 253 242 195 64 0 0 0 0]
[ 0 0 0 0 0 0 0 49 238 253 253 253 253 253 253 253 253 251
93 82 82 56 39 0 0 0 0 0]
[ 0 0 0 0 0 0 0 18 219 253 253 253 253 253 198 182 247 241
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 80 156 107 253 253 205 11 0 43 154
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 14 1 154 253 90 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 139 253 190 2 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 11 190 253 70 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 35 241 225 160 108 1
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 81 240 253 253 119
25 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 45 186 253 253
150 27 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 93 252
253 187 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 249
253 249 64 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 46 130 183 253
253 207 2 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 39 148 229 253 253 253
250 182 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 24 114 221 253 253 253 253 201
78 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 23 66 213 253 253 253 253 198 81 2
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 18 171 219 253 253 253 253 195 80 9 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 55 172 226 253 253 253 253 244 133 11 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 136 253 253 253 212 135 132 16 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]]
# 导入 One-hot 编码工具
from tensorflow.keras.utils import to_categorical
# 给训练标签增加一个维度
X_train = X_train_image.reshape(60000, 28, 28, 1)
# 给测试标签增加一个维度
X_test = X_test_image.reshape(10000, 28, 28, 1)
# 将训练特征转换为 One-hot 编码
y_train = to_categorical(y_train_label, 10)
# 将测试特征转换为 One-hot 编码
y_test = to_categorical(y_test_label, 10)
print("训练集张量形状:", X_train.shape)
print("第一个数据标签:", y_train[0])
训练集张量形状: (60000, 28, 28, 1)
第一个数据标签: [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
from keras import models
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
# 用序贯方式建立模型
model = models.Sequential()
# 添加 Conv2D 层,并指定输入数据样本张量类型
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
# 添加 MaxPooling2D 层
model.add(MaxPooling2D(pool_size=(2, 2)))
# 添加 Conv2D 层
model.add(Conv2D(64, (3, 3), activation='relu'))
# 添加 MaxPooling2D 层
model.add(MaxPooling2D(pool_size=(2, 2)))
# 添加 Dropout 层
model.add(Dropout(0.25 ))
# 展平
model.add(Flatten())
# 添加全连接层
model.add(Dense(128, activation='relu'))
# 添加 Dropout 层
model.add(Dropout(0.5))
# Softmax 分类激活,输出10 维分类码
model.add(Dense(10, activation='softmax'))
# 编译模型
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
/usr/local/lib/python3.10/dist-packages/keras/src/layers/convolutional/base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
# 把训练集预留30%的数据作为验证集
model.fit(X_train, y_train, validation_split=0.3, epochs=5, batch_size=128)
Epoch 1/5
329/329 ━━━━━━━━━━━━━━━━━━━━ 20s 57ms/step - accuracy: 0.6423 - loss: 5.6165 - val_accuracy: 0.9411 - val_loss: 0.2084
Epoch 2/5
329/329 ━━━━━━━━━━━━━━━━━━━━ 19s 59ms/step - accuracy: 0.9366 - loss: 0.2279 - val_accuracy: 0.9760 - val_loss: 0.0880
Epoch 3/5
329/329 ━━━━━━━━━━━━━━━━━━━━ 18s 54ms/step - accuracy: 0.9592 - loss: 0.1534 - val_accuracy: 0.9762 - val_loss: 0.0867
Epoch 4/5
329/329 ━━━━━━━━━━━━━━━━━━━━ 19s 58ms/step - accuracy: 0.9670 - loss: 0.1174 - val_accuracy: 0.9842 - val_loss: 0.0574
Epoch 5/5
329/329 ━━━━━━━━━━━━━━━━━━━━ 18s 55ms/step - accuracy: 0.9722 - loss: 0.1047 - val_accuracy: 0.9799 - val_loss: 0.0685
<keras.src.callbacks.history.History at 0x7f89aa4d2c20>
score = model.evaluate(X_test, y_test)
print('测试集预测准确率:', score[1])
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 7ms/step - accuracy: 0.9770 - loss: 0.0714
测试集预测准确率: 0.9829000234603882
# 预测测试集第一个数据
pred = model.predict(X_test[0].reshape(1, 28, 28, 1))
# 把 One-hot 编码转换为数字
print(pred[0], "转换一下格式得到:", pred.argmax())
# 导入绘图工具包
import matplotlib.pyplot as plt
plt.imshow(X_test[0].reshape(28, 28), cmap='Greys')
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step
[2.40477445e-16 1.76930497e-12 2.10598664e-10 5.55166912e-10
1.72731120e-15 6.29082518e-15 2.57499564e-20 1.00000000e+00
5.61026784e-14 1.11066635e-10] 转换一下格式得到: 7
