神经网络手写数字识别

Posted renyuzhuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了神经网络手写数字识别相关的知识,希望对你有一定的参考价值。

聊了几天理论,是该弄一个 Hello World 了,在人工智能领域,或者说深度学习领域,Hello World 程序就是手写数字识别,今天我们就来看看手写数字识别的程序怎么写。不愿意看代码吗,那我就说一说这段代码干了点什么:先通过 keras 内置的数据集下载测试数据,是 60000 长手写图片的训练集和 10000 张测试集,随后定义了一个神经网络的模型,设置网络中的层参数,随后配置训练网络的参数,包括损失函数和评测模型,设置迭代次数,启动训练网络,最后将测试数据喂给网络,得出训练效果是否有效。还是建议看仔细看一下代码:

#!/usr/bin/env python3
from keras import layers
from keras import models
from keras.datasets import mnist
from keras.utils import to_categorical
?
def hello_world():
    # 下载手写数字数据集, https://s3.amazonaws.com/img-datasets/mnist.npz
    (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
?
    print('训练集:', train_images.shape)   # (60000, 28, 28)
    print('训练集:', len(train_labels))    # 60000
    print('训练集:', train_labels)         # [5 0 4 ... 5 6 8]
?
    print()
    print('测试集:', test_images.shape)    # (10000, 28, 28)
    print('测试集:', len(test_labels))     # 10000
    print('测试集:', test_labels)          # [7 2 1 ... 4 5 6]
?
    # 模型,可以理解为就是前文说的黑盒子
    network = models.Sequential()
    # 神经网络的核心就是 layer,是真正用来加工处理数据的,Dense 是定义网络层的基础方法
    # 512 定义神经元个数,activation 定义激活函数,input_shape 定义输入尺寸
    network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
    network.add(layers.Dense(10, activation='softmax'))
?
    # 配置训练模型,optimizer 优化器名,loss 损失函数,metrics 模型评估标准
    network.compile(optimizer='rmsprop',
                    loss='categorical_crossentropy',
                    metrics=['accuracy'])
?
    # 不改变数组内容,改变数组格式
    train_images = train_images.reshape((60000, 28 * 28))
    # 数据类型转换
    train_images = train_images.astype('float32') / 255
?
    test_images = test_images.reshape((10000, 28 * 28))
    test_images = test_images.astype('float32') / 255
?
    # 转换成二进制
    train_labels = to_categorical(train_labels)
    test_labels = to_categorical(test_labels)
?
    # 在数据集上进行迭代
    network.fit(train_images, train_labels, epochs=5, batch_size=128, callbacks=[TensorBoard(log_dir='./log')])
    # 测试模式下损失值和指标值
    test_loss, test_acc = network.evaluate(test_images, test_labels)
?
    print('test_loss', test_loss, ', test_acc:', test_acc)
?
if __name__ == "__main__":
    hello_world()

TensorFlow 作为其运行引擎,输出数据集格式:

技术图片

这是运行过程简图,可以看出准确率随着迭代次数,越来越高,训练后模型在测试集上运行识别准确率差不多为 98%:

技术图片

技术图片

这里我们思考几个问题:

  1. 这个网络真的好像一个黑盒子,给了一些训练数据,然后就得出了一个模型,但是这个训练过程中,究竟向量间是怎么运算的,究竟特征值是怎么取的,每次运算的结果还不一样,那是不是就没有办法分析这个网络中究竟发生了什么,是不是觉得有点慌。如果一个人工智能指挥的战争,我们是不是都没有办法预测究竟发生了什么,指挥的命令是否符合人类最高价值观,想一想就会觉得有点可怕。

  2. 这个训练过程其实还是挺耗时的,或者说神经网络运行一般都是挺耗时的,因此这个问题怎么去处理,怎么去剪枝,让其可以在有限的时间内就可以得到可以接受的结果。这是不是就对 AlphaGo 有了一点不一样的理解。

  3. 这个网络究竟是怎么训练数据的,似乎也没写什么相关代码呀,好像也可以完成不少的事情,神经网络都这么简单吗?当然不是。在 network.fit 中最后最后一个参数是设置了callback,在控制台用 tensorboard --logdir=log 命令可以查看运行过程图,看不懂没关系,以后我们慢慢分析,截图如下:

技术图片
技术图片

今天,我们写了一个 Hello World,用的是 Keras,其底层内核是 TensorFlow,直观感性的复习一下之前聊过的知识,只看无益,去试一试吧!

以上是关于神经网络手写数字识别的主要内容,如果未能解决你的问题,请参考以下文章

神经网络之手写数字识别

基于Numpy的神经网络+手写数字识别

使用神经网络来识别手写数字译- 用Python代码实现

图像识别 基于Keras的手写数字识别(含代码)

神经网络做MNIST手写数字识别代码

卷积神经网络 手写数字识别(包含Pytorch实现代码)