本文使用Tensorflow2.0搭建CNN进行MNIST手写数字识别。Tensorflow2.0的使用方法参照Tensroflow官方教程
下面给出具体代码及运行结果:
#导入模块
import tensorflow as tf
#导入数据集
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
数据导入后需要进行预处理才能够输入模型进行训练和预测。
#Reshape
x_train4D = x_train.reshape(x_train.shape[0],28,28,1).astype('float32')
x_test4D = x_test.reshape(x_test.shape[0],28,28,1).astype('float32')
#像素标准化
x_train, x_test = x_train4D / 255.0, x_test4D / 255.0
导入的训练集的shape为(60000,28,28)。若是全连接神经网络,需要reshape为(60000,784);而卷积神经网络因为必须先进行卷积与池化运算,所以必须保持图像的维数。所以reshape转换为(60000,28,28,1),即60000张图像,每一张为28(宽)*28(高)*1(单色)。
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(filters=16, kernel_size=(5,5), padding='same',
input_shape=(28,28,1), activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(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(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(10,activation='softmax')
])
#打印模型
print(model.summary())
我们搭建了一个由两个卷积和池化层以及全连接层输出的小型CNN模型。其中,通过添加Dropout层避免过拟合,提高模型的泛化能力。最后,使用print将模型打印出来,如下图,可以清晰直观的看出模型的结构,且显示出该模型共有242062个参数。
#训练配置
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
#开始训练
model.fit(x=x_train, y=y_train, validation_split=0.2,
epochs=20, batch_size=300, verbose=2)
在训练配置中,我们使用’sparse_categorical_crossentropy’损失函数,使用’adam’优化器,以及’accuracy’(准确率)作为评估标准。之后我们将训练集和训练标签传给模型,并从中抽取80%作为训练样本,其余20%进行验证,进行20个训练周期,batch size为300的批训练。
“verbose=2”:显示训练过程。
训练结果过程及结果如下:
经过训练后,模型的准确率达到99.22%
对于复杂的问题,可以通过加深网络及调整模型超参数来进一步提高准确率。