import warnings
warnings.simplefilter(action='ignore')
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train_flatten = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32')
x_test_flatten = x_test.reshape(x_test.shape[0], 28, 28, 1).astype('float32')
x_train_normalize = x_train_flatten / 255.0
x_test_normalize = x_test_flatten / 255.0
y_train_one_hot = tf.keras.utils.to_categorical(y_train)
y_test_one_hot = tf.keras.utils.to_categorical(y_test)
model = tf.keras.models.Sequential([
# 卷积层1与池化层1
tf.keras.layers.Conv2D(input_shape=(28, 28, 1), filters=16, kernel_size=(5, 5), padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
# 卷积层2与池化层2
tf.keras.layers.Conv2D(filters=36, kernel_size=(5, 5), padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
tf.keras.layers.Dropout(0.25),
# 平坦层
tf.keras.layers.Flatten(),
# 隐藏层(128个神经元)
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.5),
# 输出层
tf.keras.layers.Dense(10, activation='softmax')
])
print(model.summary())
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 28, 28, 16) 416 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 14, 14, 16) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 14, 14, 36) 14436 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 7, 7, 36) 0 _________________________________________________________________ dropout (Dropout) (None, 7, 7, 36) 0 _________________________________________________________________ flatten (Flatten) (None, 1764) 0 _________________________________________________________________ dense (Dense) (None, 128) 225920 _________________________________________________________________ dropout_1 (Dropout) (None, 128) 0 _________________________________________________________________ dense_1 (Dense) (None, 10) 1290 ================================================================= Total params: 242,062 Trainable params: 242,062 Non-trainable params: 0 _________________________________________________________________ None
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
train_history = model.fit(x=x_train_normalize, y=y_train_one_hot, validation_split=0.2,
epochs=20, batch_size=300, verbose=2)
Train on 48000 samples, validate on 12000 samples Epoch 1/20 - 57s - loss: 0.4985 - acc: 0.8430 - val_loss: 0.0989 - val_acc: 0.9692 Epoch 2/20 - 53s - loss: 0.1389 - acc: 0.9587 - val_loss: 0.0664 - val_acc: 0.9793 Epoch 3/20 - 52s - loss: 0.1027 - acc: 0.9690 - val_loss: 0.0539 - val_acc: 0.9829 Epoch 4/20 - 52s - loss: 0.0846 - acc: 0.9740 - val_loss: 0.0556 - val_acc: 0.9834 Epoch 5/20 - 53s - loss: 0.0696 - acc: 0.9793 - val_loss: 0.0438 - val_acc: 0.9876 Epoch 6/20 - 52s - loss: 0.0625 - acc: 0.9811 - val_loss: 0.0379 - val_acc: 0.9886 Epoch 7/20 - 51s - loss: 0.0554 - acc: 0.9832 - val_loss: 0.0377 - val_acc: 0.9894 Epoch 8/20 - 51s - loss: 0.0497 - acc: 0.9849 - val_loss: 0.0346 - val_acc: 0.9900 Epoch 9/20 - 52s - loss: 0.0457 - acc: 0.9867 - val_loss: 0.0394 - val_acc: 0.9889 Epoch 10/20 - 51s - loss: 0.0410 - acc: 0.9872 - val_loss: 0.0357 - val_acc: 0.9889 Epoch 11/20 - 51s - loss: 0.0382 - acc: 0.9877 - val_loss: 0.0344 - val_acc: 0.9909 Epoch 12/20 - 52s - loss: 0.0376 - acc: 0.9880 - val_loss: 0.0319 - val_acc: 0.9913 Epoch 13/20 - 51s - loss: 0.0364 - acc: 0.9881 - val_loss: 0.0309 - val_acc: 0.9908 Epoch 14/20 - 51s - loss: 0.0338 - acc: 0.9895 - val_loss: 0.0320 - val_acc: 0.9902 Epoch 15/20 - 52s - loss: 0.0315 - acc: 0.9898 - val_loss: 0.0292 - val_acc: 0.9918 Epoch 16/20 - 51s - loss: 0.0291 - acc: 0.9905 - val_loss: 0.0308 - val_acc: 0.9922 Epoch 17/20 - 51s - loss: 0.0266 - acc: 0.9912 - val_loss: 0.0303 - val_acc: 0.9916 Epoch 18/20 - 51s - loss: 0.0247 - acc: 0.9919 - val_loss: 0.0316 - val_acc: 0.9919 Epoch 19/20 - 51s - loss: 0.0249 - acc: 0.9920 - val_loss: 0.0303 - val_acc: 0.9916 Epoch 20/20 - 51s - loss: 0.0254 - acc: 0.9921 - val_loss: 0.0352 - val_acc: 0.9909
def show_train_history(train_history, train, validation):
plt.plot(train_history.history[train])
plt.plot(train_history.history[validation])
plt.title('Train History')
plt.xlabel('Epoch')
plt.ylabel(train)
plt.legend(['train', 'validation'], loc='upper left')
plt.show()
show_train_history(train_history, 'acc', 'val_acc')
show_train_history(train_history, 'loss', 'val_loss')
scores = model.evaluate(x_test_normalize, y_test_one_hot)
print()
print('accuracy:', scores[1])
10000/10000 [==============================] - 5s 452us/step accuracy: 0.9923
predictions = model.predict_classes(x_test_normalize)
predictions
array([7, 2, 1, ..., 4, 5, 6])
def plot_images_labels_prediction(images, labels, predictions, idx, num=10):
"""
images: 数字图像数组
labels: 真实值数组
predictions: 预测结果数据
idx: 开始显示的数据index
num: 要显示的数据项数, 默认为10, 不超过25
"""
fig = plt.gcf()
fig.set_size_inches(12, 14)
if num > 25:
num = 25
for i in range(0, num):
ax = plt.subplot(5, 5, i+1)
ax.imshow(images[idx], cmap='binary')
title = 'lable=' + str(labels[idx])
if len(predictions) > 0:
title += ',predict=' + str(predictions[idx])
ax.set_title(title, fontsize=10)
ax.set_xticks([])
ax.set_yticks([])
idx += 1
plt.show()
plot_images_labels_prediction(x_test, y_test, predictions, idx=0, num=10)
pd.crosstab(y_test, predictions, rownames=['label'], colnames=['predict'])
predict | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
label | ||||||||||
0 | 976 | 1 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 0 |
1 | 0 | 1134 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 2 | 0 | 1025 | 0 | 1 | 0 | 0 | 3 | 1 | 0 |
3 | 0 | 0 | 0 | 1004 | 0 | 2 | 0 | 1 | 3 | 0 |
4 | 0 | 0 | 0 | 0 | 980 | 0 | 0 | 0 | 0 | 2 |
5 | 1 | 0 | 0 | 6 | 0 | 883 | 1 | 0 | 0 | 1 |
6 | 4 | 3 | 0 | 0 | 2 | 1 | 948 | 0 | 0 | 0 |
7 | 0 | 1 | 2 | 0 | 0 | 0 | 0 | 1023 | 1 | 1 |
8 | 2 | 1 | 3 | 0 | 1 | 1 | 3 | 2 | 958 | 3 |
9 | 3 | 2 | 0 | 0 | 9 | 1 | 0 | 2 | 0 | 992 |
df = pd.DataFrame({'label': y_test, 'predict': predictions})
df[:2]
label | predict | |
---|---|---|
0 | 7 | 7 |
1 | 2 | 2 |
df[(df.label==5)&(df.predict==2)]
label | predict |
---|
plot_images_labels_prediction(x_test, y_test, predictions, idx=340, num=1)
plot_images_labels_prediction(x_test, y_test, predictions, idx=1289, num=1)