基于tensorflow2.x实现bp神经网络,实践mnist手写数字识别(代码片段)

小毕超 小毕超     2022-12-23     446

关键词:

一、MNIST 数据集

MNIST 是一个非常有名的手写数字识别数据集,在很多资料中都会被用作深度学习的入门样例。在 Tensorflow 2.x 中该数据集已被封装在了 tf.keras.datasets 工具包下,如果没有指定数据集的位置,并先前也没有使用过,会自动联网下载该,使该数据集使用起来更加方便,它包括了 70000 张图片数据,大小统一是 28x28的长宽,其中 60000 张作为训练数据,10000张作为测试数据,每一张图片都代表 0~9 中的一个数字,可以通过下面程序对该数据进行可视化预览:

import tensorflow as tf
import matplotlib.pyplot as plt

keras = tf.keras
mnist = tf.keras.datasets.mnist
plt.rcParams['font.sans-serif'] = ['SimHei']

# 加载 fashion_mnist 数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()

print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)

for i in range(10):
    image = x_test[i]
    label = y_test[i]
    plt.imshow(image, cmap=plt.cm.gray)
    plt.title(label=('标签值: ' + str(label)))
    plt.show()

运行后可以看下如下的图片示例:

二、搭建多层BP神经网络模型

本文基于 Tensorflow 2.x 构建 BP 神经网络,在 Tensorflow 2.x 中官方更推荐的上层API工具为 Keras ,本文也是使用 Keras 进行实验测试。

设计模型结构如下所示:

通过 Keras 建立模型结构,具体的解释都写在了注释中:

import tensorflow as tf

keras = tf.keras
mnist = tf.keras.datasets.mnist

# 定义模型类
class mnistModel():
    # 初始化结构
    def __init__(self, checkpoint_path, log_path, model_path):
        # checkpoint 权重保存地址
        self.checkpoint_path = checkpoint_path
        # 训练日志保存地址
        self.log_path = log_path
        # 训练模型保存地址:
        self.model_path = model_path
        # 初始化模型结构
        self.model = tf.keras.models.Sequential([
            # 输入层,平坦层,输入 (None, 784)
            tf.keras.layers.Flatten(input_shape=(28, 28)),
            # 隐藏层 一 ,输出 (None, 64)
            tf.keras.layers.Dense(64,
                                  kernel_initializer=keras.initializers.truncated_normal(stddev=0.05),
                                  activation=tf.nn.relu,
                                  kernel_regularizer=keras.regularizers.l2(0.001)),
            # 隐藏层 二 ,输出(None, 128)
            tf.keras.layers.Dense(128,
                                  kernel_initializer=keras.initializers.truncated_normal(stddev=0.05),
                                  activation=tf.nn.relu,
                                  kernel_regularizer=keras.regularizers.l2(0.001)),

            # Dropout 随机失活,防止过拟合,20%的神经元失活,输出  (None, 128)
            tf.keras.layers.Dropout(0.2),
            # 隐藏层 三 ,输出 (None, 256)
            tf.keras.layers.Dense(256,
                                  kernel_initializer=keras.initializers.truncated_normal(stddev=0.05),
                                  activation=tf.nn.relu,
                                  kernel_regularizer=keras.regularizers.l2(0.001)),
            # Dropout 随机失活,防止过拟合,20%的神经元失活,输出 (None, 254)
            tf.keras.layers.Dropout(0.2),
            # softmax 层,输出 (None, 10)
            tf.keras.layers.Dense(10, activation='softmax')
        ])

    # 编译模型
    def compile(self):
        # 输出模型摘要
        self.model.summary()
        # 定义训练模式
        self.model.compile(optimizer='adam',
                           loss='sparse_categorical_crossentropy',
                           metrics=['accuracy'])

    # 训练模型
    def train(self, x_train, y_train):
        # tensorboard 训练日志收集
        tensorboard = keras.callbacks.TensorBoard(log_dir=self.log_path)

        # 训练过程保存 Checkpoint 权重,防止意外停止后可以继续训练
        model_checkpoint = keras.callbacks.ModelCheckpoint(self.checkpoint_path,  # 保存模型的路径
                                                           monitor='val_loss',  # 被监测的数据。
                                                           verbose=0,  # 详细信息模式,0 或者 1
                                                           save_best_only=True,  # 如果 True, 被监测数据的最佳模型就不会被覆盖
                                                           save_weights_only=True,
                                                           # 如果 True,那么只有模型的权重会被保存 (model.save_weights(filepath)),否则的话,整个模型会被保存,(model.save(filepath))
                                                           mode='auto',
                                                           # auto, min, max的其中之一。 如果 save_best_only=True,那么是否覆盖保存文件的决定就取决于被监测数据的最大或者最小值。 对于 val_acc,模式就会是 max,而对于 val_loss,模式就需要是 min,等等。 在 auto模式中,方向会自动从被监测的数据的名字中判断出来。
                                                           period=3  # 每3个epoch保存一次权重
                                                           )
        # 填充数据,迭代训练
        self.model.fit(
            x_train,  # 训练集
            y_train,  # 训练集的标签
            validation_split=0.2,  # 验证集的比例
            epochs=30,  # 迭代周期
            batch_size=30,  # 一批次输入的大小
            verbose=2,  # 训练过程的日志信息显示,一个epoch输出一行记录
            callbacks=[tensorboard, model_checkpoint]
        )
        # 保存训练模型
        self.model.save(self.model_path)

    def evaluate(self, x_test, y_test):
        # 评估模型
        test_loss, test_acc = self.model.evaluate(x_test, y_test)
        return test_loss, test_acc

上面优化器使用的 adamlosssparse_categorical_crossentropy,一共训练 30 个周期,每个 batch 30 张图片,验证集的比例为 20%,并且每三个周期保存一次权重,防止意外停止后继续训练,最后保存了 h5 的训练模型,方便后面进行测试预测效果。

下面开始训练模型:

import tensorflow as tf

keras = tf.keras
mnist = tf.keras.datasets.mnist

def main():
    # 加载 MNIST 数据集
    (x_train, y_train), (x_test, y_test) = mnist.load_data(path='F:/Tensorflow/datasets/mnist.npz')
    # 修改shape 数据归一化
    x_train, x_test = x_train / 255.0, x_test / 255.0

    checkpoint_path = './checkout/'
    log_path = './log'
    model_path = './model/model.h5'

    # 构建模型
    model = mnistModel(checkpoint_path, log_path, model_path)
    # 编译模型
    model.compile()
    # 训练模型
    model.train(x_train, y_train)
    # 评估模型
    test_loss, test_acc = model.evaluate(x_test, y_test)
    print(test_loss, test_acc)

if __name__ == '__main__':
    main()

运行后可以看到网络结构:


训练日志,可以看到 loss 一直在减小:


最后看下评估模型的结果:

毕竟是BP神经网络,这里评估的准确率只有 96.8 %,在本专栏后面博客,会使用多层卷积训练模型,可以实现更好的效果。

下面看下 tensorboard 中可视化的损失及准确率:

tensorboard --logdir=log/train


使用浏览器访问:http://localhost:6006/ 查看结果:

三、模型预测

上面搭建的模型,训练后会在 model 下生成 model.h5 模型,下面直接加载该模型进行预测:

import tensorflow as tf
import matplotlib.pyplot as plt

keras = tf.keras
mnist = tf.keras.datasets.mnist
plt.rcParams['font.sans-serif'] = ['SimHei']

# 加载 MNIST 数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 数据归一化
x_train, x_test = x_train / 255.0, x_test / 255.0

model = keras.models.load_model('./model/model.h5')

for i in range(10):
    image = x_test[i]
    label = y_test[i]
    softmax = model.predict(image.reshape([1, 784]))
    y_label = tf.argmax(softmax, axis=1).numpy()[0]
    plt.imshow(image, cmap=plt.cm.gray)
    plt.title(label = ('预测结果: '+ str(y_label) + ',  真实结果: '+ str(label)))
    plt.show()

运行后可以看下如下的图片示例:


可以看到面对书写较工整的数字都可以较好的进行识别,但是对于不工整的就有点吃力,下一篇使用卷积神经网络进行优化,提高识别的准确率。

基于tensorflow2.x实现多层卷积神经网络,实践mnist手写数字识别(代码片段)

...、MNIST数据集上篇文章中使用了Tensorflow2.x搭建了对层的BP神经网络,经过训练后发现准确率只有96.8%对于单环境的图片识别场景来说,还是有点偏低,本文使用多层的卷积代替BP网络中的隐藏层对模型进行优化。下面是... 查看详情

基于tensorflow2.x实现多层卷积神经网络,实践mnist手写数字识别(代码片段)

...、MNIST数据集上篇文章中使用了Tensorflow2.x搭建了对层的BP神经网络,经过训练后发现准确率只有96.8%对于单环境的图片识别场景来说,还是有点偏低,本文使用多层的卷积代替BP网络中的隐藏层对模型进行优化。下面是... 查看详情

基于tensorflow2.x实现bp神经网络,实践mnist手写数字识别(代码片段)

一、MNIST数据集MNIST是一个非常有名的手写数字识别数据集,在很多资料中都会被用作深度学习的入门样例。在Tensorflow2.x中该数据集已被封装在了tf.keras.datasets工具包下,如果没有指定数据集的位置,并先前也没有使... 查看详情

基于tensorflow2.x实现多层卷积神经网络,实践mnist手写数字识别(代码片段)

...、MNIST数据集上篇文章中使用了Tensorflow2.x搭建了对层的BP神经网络,经过训练后发现准确率只有96.8%对于单环境的图片识别场景来说,还是有点偏低,本文使用多层的卷积代替BP网络中的隐藏层对模型进行优化。下面是... 查看详情

bp神经网络训练自己的数据(tensorflow2.x版本)(代码片段)

一、开发环境python3.6Tensorflow2.xnumpy1.19matplotlib3.3scikit-learn0.24二、数据集介绍本次训练数据使用的是鸢尾花数据集,具体做法是将鸢尾花数据集保存在本地,充当自己的数据集。鸢尾花数据集中内包含3个类分别为山鸢尾... 查看详情

bp神经网络训练自己的数据(tensorflow2.x版本)(代码片段)

一、开发环境python3.6Tensorflow2.xnumpy1.19matplotlib3.3scikit-learn0.24二、数据集介绍本次训练数据使用的是鸢尾花数据集,具体做法是将鸢尾花数据集保存在本地,充当自己的数据集。鸢尾花数据集中内包含3个类分别为山鸢尾... 查看详情

基于tensorflow2.x实现多层卷积神经网络,实践fashionmnist服装图像识别(代码片段)

一、FashionMNIST服装数据集FashionMNIST数据集,该数据集包含10个类别的70000个灰度图像。大小统一是28x28的长宽,其中60000张作为训练数据,10000张作为测试数据,该数据集已被封装在了tf.keras.datasets工具包下,数... 查看详情

bp神经网络训练自己的数据(tensorflow2.x版本)(代码片段)

...尾5.935.11.8维吉尼亚鸢尾三、BP神经算法推导与结构见《BP神经网络算法推导》四、文件介绍--data --x_train.txt(用于存放训练数据) --result.txt(用于存放标签数据)--train.py(训练脚本ÿ 查看详情

基于tensorflow2.x实现多层卷积神经网络,实践fashionmnist服装图像识别(代码片段)

一、FashionMNIST服装数据集FashionMNIST数据集,该数据集包含10个类别的70000个灰度图像。大小统一是28x28的长宽,其中60000张作为训练数据,10000张作为测试数据,该数据集已被封装在了tf.keras.datasets工具包下,数... 查看详情

基于蝙蝠算法优化bp神经网络的数据分类算法及其matlab实现-附代码(代码片段)

基于蝙蝠算法优化BP神经网络的数据分类算法及其MATLAB实现-附代码文章目录基于蝙蝠算法优化BP神经网络的数据分类算法及其MATLAB实现-附代码1蝙蝠算法与BP神经网络分类模型1.1蝙蝠算法BA1.2one-hot编码2基于蝙蝠算法BA优化的BP神经... 查看详情

基于tensorflow2.x低阶api搭建神经网络模型并训练及解决梯度爆炸与消失方法实践(代码片段)

1.低阶API神经网络模型1.1.关于tf.Module关于Tensorflow2.x,最令我觉得有意思的功能就是tf.function和AutoGraph了.他们可以把Python风格的代码转为效率更好的Tensorflow计算图。TensorFlow2.0主要使用的是动态计算图和Autograph。Autograph机... 查看详情

基于tensorflow2.x低阶api搭建神经网络模型并训练及解决梯度爆炸与消失方法实践(代码片段)

1.低阶API神经网络模型1.1.关于tf.Module关于Tensorflow2.x,最令我觉得有意思的功能就是tf.function和AutoGraph了.他们可以把Python风格的代码转为效率更好的Tensorflow计算图。TensorFlow2.0主要使用的是动态计算图和Autograph。Autograph机... 查看详情

基于tensorflow2.x低阶api搭建神经网络模型并训练及解决梯度爆炸与消失方法实践(代码片段)

1.低阶API神经网络模型1.1.关于tf.Module关于Tensorflow2.x,最令我觉得有意思的功能就是tf.function和AutoGraph了.他们可以把Python风格的代码转为效率更好的Tensorflow计算图。TensorFlow2.0主要使用的是动态计算图和Autograph。Autograph机... 查看详情

bp预测基于遗传算法改进bp神经网络实现数据预测(代码片段)

  一、BP神经网络预测算法简介说明:1.1节主要是概括和帮助理解考虑影响因素的BP神经网络算法原理,即常规的BP模型训练原理讲解(可根据自身掌握的知识是否跳过)。1.2节开始讲基于历史值影响的BP神经网络... 查看详情

bp预测基于遗传算法改进bp神经网络实现数据预测(代码片段)

   一、BP神经网络预测算法简介说明:1.1节主要是概括和帮助理解考虑影响因素的BP神经网络算法原理,即常规的BP模型训练原理讲解(可根据自身掌握的知识是否跳过)。1.2节开始讲基于历史值影响的BP神经网... 查看详情

bp预测基于蝗虫算法改进bp神经网络实现数据预测(代码片段)

  一、BP神经网络预测算法简介说明:1.1节主要是概括和帮助理解考虑影响因素的BP神经网络算法原理,即常规的BP模型训练原理讲解(可根据自身掌握的知识是否跳过)。1.2节开始讲基于历史值影响的BP神经网络... 查看详情

bp预测基于蝗虫算法改进bp神经网络实现数据预测(代码片段)

   一、BP神经网络预测算法简介说明:1.1节主要是概括和帮助理解考虑影响因素的BP神经网络算法原理,即常规的BP模型训练原理讲解(可根据自身掌握的知识是否跳过)。1.2节开始讲基于历史值影响的BP神经网... 查看详情

bp预测基于海鸥算法改进bp神经网络实现数据预测(代码片段)

 一、BP神经网络预测算法简介说明:1.1节主要是概括和帮助理解考虑影响因素的BP神经网络算法原理,即常规的BP模型训练原理讲解(可根据自身掌握的知识是否跳过)。1.2节开始讲基于历史值影响的BP神经网络预... 查看详情