[tensorflow2.0]学习笔记(一)mnist手写体数字识别

一、采用LeNet网络进行模型训练

采用卷积神经网络的方法进行训练,并将训练之后的权重保存为.h5格式的本地文件。

import tensorflow as tf
import tensorflow.keras as keras
import numpy as np
from tensorflow.keras import models, layers, optimizers
import matplotlib.pyplot as plt
import os
# 屏蔽tensorflow的WARNING
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
'''GPU按需分配,防止出现cudnn的报错'''
config = tf.compat.v1.ConfigProto(allow_soft_placement=True)
config.gpu_options.per_process_gpu_memory_fraction = 0.3
tf.compat.v1.keras.backend.set_session(tf.compat.v1.Session(config=config))
# Mnist数据集加载
(x_train_all, y_train_all), (x_test, y_test) = keras.datasets.mnist.load_data()
# Mnist数据集简单归一化
x_train_all, x_test = x_train_all / 255.0, x_test / 255.0
x_train, x_valid = x_train_all[:50000], x_train_all[50000:]  #验证集10000个
y_train, y_valid = y_train_all[:50000], y_train_all[50000:]
# 将图像扩展为为四个维度
img_rows, img_cols = 28, 28
if keras.backend.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_valid = x_valid.reshape(x_valid.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_valid = x_valid.reshape(x_valid.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
def show_single_image(img_arr, label):
plt.imshow(img_arr, cmap='binary')
plt.title('%i' % label)
plt.show()
image_id = 2
show_single_image(x_train[image_id], y_train[image_id])
# 将模型的各层堆叠起来,以搭建 tf.keras.Sequential 模型。为训练选择优化器和损失函数:
# layers.Flatten 压平层,方便全连接
# layers.Dense 全链接层 128 filters
# dropout 以一定的概率随机的使一部分神经元停止工作,达到防止过拟合的作用
# layers.Conv2D 卷积层
# layers.MaxPooling2D 以最大值的方式作为池化层
# 该网络为LeNet的网络结构
model = models.Sequential([layers.Conv2D(filters=6, kernel_size=3, strides=1, input_shape=(28, 28, 1)),
layers.MaxPooling2D(pool_size=2, strides=2),
layers.ReLU(),
layers.Conv2D(filters=16, kernel_size=3, strides=1),
layers.MaxPooling2D(pool_size=2, strides=2),
layers.ReLU(),
layers.Flatten(),
layers.Dense(120, activation='relu'),
layers.Dropout(0.5),
layers.Dense(84, activation='relu'),
layers.Dense(10, activation='softmax')
])
# 打印网络参数量
model.summary()
# 编译模型
model.compile(optimizer=optimizers.Adam(lr=0.0001), loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
print(len(model.layers))
# 训练模型,
history = model.fit(x_train, y_train, batch_size=10, epochs=20, validation_freq=1, validation_data=(x_valid, y_valid))
# 验证模型:
model.evaluate(x_test,  y_test, verbose=2)
history_dict = history.history         # history对象有一个history成员,它是一个字典,包含训练过程中的所有数据。
print(history_dict)
# 保存模型为h5文件
model.save('my_mnist_weights.h5')
# 绘制loss曲线
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(loss_values)+1)
plt.plot(epochs, loss_values, 'bo', label='Training loss')         # bo代表蓝色圆点
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')    # bo代表蓝色实线
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
# 绘制acc曲线
acc_values = history_dict['accuracy']
val_acc_values = history_dict['val_accuracy']
plt.plot(epochs, acc_values, 'ro', label='Training acc')           # bo代表蓝色圆点
plt.plot(epochs, val_acc_values, 'r', label='Validation acc')      # bo代表蓝色实线
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Acc')
plt.legend()
plt.show()

二、训练结果

三、测试自己的图片

测试的时候用到的图片要特别注意格式,可参考下方博客下载测试样本。

手写数字图片库MNIST百度网盘下载链接~

测试代码:

import tensorflow as tf
import matplotlib.pyplot as plt
import tensorflow.keras as keras
import skimage
import numpy as np
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
'''GPU按需分配'''
config = tf.compat.v1.ConfigProto(allow_soft_placement=True)
config.gpu_options.per_process_gpu_memory_fraction = 0.3
tf.compat.v1.keras.backend.set_session(tf.compat.v1.Session(config=config))
model = tf.keras.models.load_model('my_mnist_weights.h5')
def preprocess_image(image):
image = tf.image.decode_jpeg(image, channels=1)
image = tf.image.resize(image, [28, 28])
image /= 255.0  # normalize to [0,1] range
image = tf.reshape(image, [28, 28, 1])
return image
def load_and_preprocess_image(path):
image = tf.io.read_file(path)
return preprocess_image(image)
filepath = '6_951.jpg'
test_my_img = load_and_preprocess_image(filepath)
test_my_img = (np.expand_dims(test_my_img, 0))
my_result = model.predict(test_my_img)
print('自己的图片预测值 = %i ; 文件名 = ', (np.argmax(my_result), filepath))

测试的图片6_951.jpg如下图所示,单通道

测试结果为:

自己的图片预测值 = %i ; 文件名 = (6, ‘6_951.jpg’)

至此完成mnist手写体数字的模型训练、保存、调用模型进行预测。

本文地址:https://blog.csdn.net/qq_40921967/article/details/110421488