3 利用TensorFlow进行手写数字识别
3.1 实验介绍
3.2 实验目的
- 掌握TensorFlow开发的基本流程
- 熟悉神经网络模型开发的基本要素:数据集、网络模型构建、模型训练、模型评估
3.3 实验步骤
3.3.1 项目描述和数据集获取
3.3.1.1 项目描述
3.3.1.2 数据获取以及数据处理
import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,optimizers,datasets
from matplotlib import pyplot as plt
import numpy as np
(x_train_raw, y_train_raw), (x_test_raw, y_test_raw) = datasets.mnist.load_data()
print(y_train_raw[0])
print(x_train_raw.shape, y_train_raw.shape)
print(x_test_raw.shape, y_test_raw.shape)
num_classes = 10
y_train = keras.utils.to_categorical(y_train_raw, num_classes)
y_test = keras.utils.to_categorical(y_test_raw, num_classes)
print(y_train[0], y_train.shape)
5
(60000, 28, 28) (60000,)
(10000, 28, 28) (10000,)
[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.] (60000, 10)
3.3.2 数据集预处理及可视化
plt.figure()
for i in range(9):
x_item = x_train_raw[i]
y_item = y_train[i]
plt.subplot(3, 3, i+1)
plt.imshow(x_item)
plt.axis('off')
plt.show()
x_train = x_train_raw.reshape(60000, 784)
x_test = x_test_raw.reshape(10000, 784)
x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
3.3.3 DNN模型
3.3.3.1 DNN模型构建
model = keras.Sequential()
model.add(layers.Dense(512, activation='relu', input_dim=784))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(num_classes, activation='softmax'))
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 512) 401920
_________________________________________________________________
dense_2 (Dense) (None, 256) 131328
_________________________________________________________________
dense_3 (Dense) (None, 128) 32896
_________________________________________________________________
dense_4 (Dense) (None, 10) 1290
=================================================================
Total params: 567,434
Trainable params: 567,434
Non-trainable params: 0
_________________________________________________________________
3.3.3.2 DNN模型编译
model.compile(optimizer=optimizers.Adam(0.001),
loss=keras.losses.categorical_crossentropy,
metrics=['accuracy'])
3.3.3.3 DNN模型训练
model.fit(x_train, y_train, batch_size=128,
epochs=10, verbose=1)
Epoch 1/10
469/469 [==============================] - 4s 8ms/step - loss: 0.2243 - accuracy: 0.9330
Epoch 2/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0836 - accuracy: 0.9740
Epoch 3/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0558 - accuracy: 0.9821
Epoch 4/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0403 - accuracy: 0.9870
Epoch 5/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0304 - accuracy: 0.9900
Epoch 6/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0261 - accuracy: 0.9916
Epoch 7/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0193 - accuracy: 0.9938
Epoch 8/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0200 - accuracy: 0.9934
Epoch 9/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0211 - accuracy: 0.9930
Epoch 10/10
469/469 [==============================] - 3s 7ms/step - loss: 0.0122 - accuracy: 0.9961
<tensorflow.python.keras.callbacks.History at 0x13143ba5cd0>
3.3.3.4 DNN模型评估
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
Test loss: 0.0889819785952568
Test accuracy: 0.9783999919891357
3.3.3.5 保存模型
logdir = './mnist_model'
if not os.path.exists(logdir):
os.mkdir(logdir)
model.save(logdir + '/final_DNN_model.h5')
3.3.4 CNN模型
3.3.4.1 CNN模型构建
import tensorflow as tf
from tensorflow import keras
import numpy as np
model = keras.Sequential()
model.add(keras.layers.Conv2D(filters=32, kernel_size=5, strides=(1,1),
padding='same', activation=tf.nn.relu,
input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2), padding='valid'))
model.add(keras.layers.Conv2D(filters=64, kernel_size=3, strides=(1,1),
padding='same', activation=tf.nn.relu))
model.add(keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2), padding='valid'))
model.add(keras.layers.Dropout(0.25))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(units=128, activation=tf.nn.relu))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(units=10, activation=tf.nn.softmax))
model.summary()
3.3.4.2 CNN模型编译和训练
X_train = x_train.reshape(60000, 28, 28, 1)
X_test = x_test.reshape(10000, 28, 28, 1)
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_train, y_train, epochs=5, batch_size=128)
Epoch 1/5
469/469 [==============================] - 34s 72ms/step - loss: 0.2759 - accuracy: 0.9143
Epoch 2/5
469/469 [==============================] - 33s 71ms/step - loss: 0.0907 - accuracy: 0.9738
Epoch 3/5
469/469 [==============================] - 33s 71ms/step - loss: 0.0671 - accuracy: 0.9794
Epoch 4/5
469/469 [==============================] - 33s 71ms/step - loss: 0.0567 - accuracy: 0.9833
Epoch 5/5
469/469 [==============================] - 33s 71ms/step - loss: 0.0472 - accuracy: 0.9858
<tensorflow.python.keras.callbacks.History at 0x1314fffe250>
3.3.4.3 CNN模型验证
test_loss, test_acc = model.evaluate(X_test, y_test)
print('Test Accuracy %.4f' %test_acc)
313/313 [==============================] - 3s 10ms/step - loss: 0.0219 - accuracy: 0.9923
Test Accuracy 0.9923
3.3.4.4 CNN模型保存
logdir = './mnist_model'
if not os.path.exists(logdir):
os.mkdir(logdir)
model.save(logdir + '/final_CNN_model.h5')
3.3.5 预测结果可视化
from tensorflow.keras.models import load_model
new_model = load_model(logdir + '/final_CNN_model.h5')
new_model.summary()
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 28, 28, 32) 832
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 14, 14, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 14, 14, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 7, 7, 64) 0
_________________________________________________________________
dropout (Dropout) (None, 7, 7, 64) 0
_________________________________________________________________
flatten (Flatten) (None, 3136) 0
_________________________________________________________________
dense_5 (Dense) (None, 128) 401536
_________________________________________________________________
dropout_1 (Dropout) (None, 128) 0
_________________________________________________________________
dense_6 (Dense) (None, 10) 1290
=================================================================
Total params: 422,154
Trainable params: 422,154
Non-trainable params: 0
_________________________________________________________________
import matplotlib.pyplot as plt
%matplotlib inline
def res_Visual(n):
final_opt_a = new_model.predict_classes(X_test[0:n])
fig, ax = plt.subplots(nrows=int(n/5), ncols=5)
ax = ax.flatten()
print('前{}张图片预测结果为:'.format(n))
for i in range(n):
print(final_opt_a[i], end=',')
if int((i+1)%5) == 0:
print('\t')
img = X_test[i].reshape(28, 28)
plt.axis('off')
ax[i].imshow(img, cmap='Greys', interpolation='nearest')
ax[i].axis('off')
res_Visual(20)
WARNING:tensorflow:From <ipython-input-36-eb12790dfd7d>:7: Sequential.predict_classes (from tensorflow.python.keras.engine.sequential) is deprecated and will be removed after 2021-01-01.
Instructions for updating:
Please use instead:* `np.argmax(model.predict(x), axis=-1)`, if your model does multi-class classification (e.g. if it uses a `softmax` last-layer activation).* `(model.predict(x) > 0.5).astype("int32")`, if your model does binary classification (e.g. if it uses a `sigmoid` last-layer activation).
前20张图片预测结果为:
7,2,1,0,4,
1,4,9,5,9,
0,6,9,0,1,
5,9,7,3,4,
|