基于Tensorflow2的卷积神经网络MNIST手写数字识别

基于Tensorflow2的卷积神经网络MNIST手写数字识别

文章目录

  • 基于Tensorflow2的卷积神经网络MNIST手写数字识别
    • 1. 导包
    • 2. 数据处理
    • 3. 创建模型
    • 4.模型训练与评估

1. 导包

import numpy as np
import tensorflow as tf 
# 导入数据集
import tensorflow.keras.datasets.mnist as mnist
# 绘图用
import matplotlib.pyplot as plt 
%matplotlib inline   

2. 数据处理

  • 归一化处理,使数据处于0-1之间
  • 因在卷积计算中输入的数据是一个4维的数据,使用tf.expand_dims对数据进行维度扩展,使其为(60000,28,28,1)六万张28*28的单通道照片(第4维是channel通道)
  • 将标签0-9进行one-hot独热编码处理,比如图像数字5的标签5处理成[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
  • 使用tf.data.Dataset.from_tensor_slices((x_train,y_train)).batch(bacth_size)创建Dataset,指定batch大小
  • 使用shuffle 打乱数据之间的顺序
(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)

3. 创建模型

注意输入的初始化使用的是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

4.模型训练与评估

优化器为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的深度学习实践》王晓华

你可能感兴趣的:(TensorFlow2,Python,python,tensorflow,分类,深度学习)