import numpy as np
import tensorflow as tf
# 导入数据集
import tensorflow.keras.datasets.mnist as mnist
# 绘图用
import matplotlib.pyplot as plt
%matplotlib inline
tf.expand_dims
对数据进行维度扩展,使其为(60000,28,28,1)
六万张28*28的单通道照片(第4维是channel通道)5
处理成[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0 # 归一化
# 数据
x_train = tf.expand_dims(x_train,-1) # 卷积的输入一般是一个四维的数据,还需要一个“通道“ ,因此在最后扩展一个维度
x_test = tf.expand_dims(x_test,-1)
# 标签
y_train = np.float32(tf.keras.utils.to_categorical(y_train,num_classes=10)) # one-hot处理
y_test = np.float32(tf.keras.utils.to_categorical(y_test,num_classes=10))
使用plt.imshow(x_train[0])可查看图片
bacth_size = 512
# 创建tf Dataset数据集,进行数据打包,方便地组合成train和label的配对数据集
train_dataset = tf.data.Dataset.from_tensor_slices((x_train,y_train)).batch(bacth_size).shuffle(bacth_size * 10)
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(bacth_size)
注意输入的初始化使用的是Input类,这里更具输入的数据大小将输入的数据维度做成[28,28,1],其中batch_size不需要设置,Tensorflow会根据Dataset中的设置自行处理。
因数字识别为多分类问题(10个数字),所以最后的Dense层输出维度为10
# 模型创建,采用函数式进行编程
input_xs = tf.keras.Input([28,28,1])
conv = tf.keras.layers.Conv2D(32,3,padding="SAME", activation=tf.nn.relu)(input_xs)# 卷积层 filters=32 kernel_size=3
# batch_normalization批标准化,作为正则化的工具也被作为各个层之间的连接而使用。
conv = tf.keras.layers.BatchNormalization()(conv)
conv = tf.keras.layers.Conv2D(64,3,padding="SAME", activation='relu')(conv)# 卷积层
conv = tf.keras.layers.MaxPool2D(strides=[1,1])(conv) # 池化层
conv = tf.keras.layers.Conv2D(128,3,padding="SAME", activation='relu')(conv)# 卷积层
flat = tf.keras.layers.Flatten()(conv) # 将数据展平成一维,进行特征值的平整化
dense = tf.keras.layers.Dense(256, activation=tf.nn.relu)(flat) # 全连接层
logits = tf.keras.layers.Dense(10, activation='softmax')(dense) # 全连接层 也可以写成activation=tf.nn.softmax
model = tf.keras.Model(inputs=input_xs, outputs=logits) # 创建模型model
# print(model.summary())
使用print(model.summary())
打印模型信息:
Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 28, 28, 1)] 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 28, 28, 32) 320
_________________________________________________________________
batch_normalization_1 (Batch (None, 28, 28, 32) 128
_________________________________________________________________
conv2d_4 (Conv2D) (None, 28, 28, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 27, 27, 64) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, 27, 27, 128) 73856
_________________________________________________________________
flatten_1 (Flatten) (None, 93312) 0
_________________________________________________________________
dense_2 (Dense) (None, 256) 23888128
_________________________________________________________________
dense_3 (Dense) (None, 10) 2570
=================================================================
Total params: 23,983,498
Trainable params: 23,983,434
Non-trainable params: 64
_________________________________________________________________
None
优化器为Adam,损失函数为categorical_crossentropy
其他损失函数可参考:https://keras.io/zh/losses/
metrics评价函数可参考:https://keras.io/zh/metrics/#categorical_accuracy
# 模型编译 也可以optimizer=tf.optimizers.Adam(1e-3), loss=tf.losses.categorical_crossentropy, metrics = ['accuracy']
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['acc'])
# 模型训练5个epochs
model.fit(train_dataset, epochs=5)
# 模型保存本地
# model.save("./saver/MyTfModelForMnist.h5")
# 模型在测试集上的评估
score = model.evaluate(test_dataset)
print("测试集准确率:",score) # 输出 [损失率,准确率]
输出:
Epoch 1/5
118/118 [==============================] - 6s 45ms/step - loss: 0.4679 - acc: 0.9165
Epoch 2/5
118/118 [==============================] - 6s 45ms/step - loss: 0.0456 - acc: 0.9860
Epoch 3/5
118/118 [==============================] - 6s 45ms/step - loss: 0.0253 - acc: 0.9918
Epoch 4/5
118/118 [==============================] - 6s 46ms/step - loss: 0.0165 - acc: 0.9945
Epoch 5/5
118/118 [==============================] - 5s 45ms/step - loss: 0.0150 - acc: 0.9950
20/20 [==============================] - 1s 16ms/step - loss: 0.0379 - acc: 0.9876
测试集准确率: [0.03789792209863663, 0.9876000285148621]
最终准确率可达98.7%
参考文献:《Keras实战:基于Tensorflow2.2的深度学习实践》王晓华