zoukankan      html  css  js  c++  java
  • keras与卷积神经网络(CNN)实现识别mnist手写数字

    在本篇博文当中,笔者采用了卷积神经网络来对手写数字进行识别,采用的神经网络的结构是:输入图片——卷积层——池化层——卷积层——池化层——卷积层——池化层——Flatten层——全连接层(64个神经元)——全连接层(500个神经元)——softmax函数,最后得到分类的结果。Flatten层用于将池化之后的多个二维数组展开成一维数组,再灌入全连接层的神经元当中。

    首先导包:

    import keras
    from keras import layers
    from keras import models

    建立神经网络的顺序模型:

    model = models.Sequential()

    添加神经网络的结构(三组卷积层,池化层。一个flatten层,以及两个全连接层),激活函数我一般喜欢使用relu,当然你也可以使用sigmoid,tanh这两个激活函数,更改我的代码即可。由于是手写数字,最后的softmax一共只能够有十个数字,因此输出写10.激活函数使用softmax。其他都是relu。

    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Flatten())
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.Dense(500, activation='relu'))
    model.add(layers.Dense(10, activation='softmax'))

    神经网络搭建完毕,开始导minist手写数字,对数字进行分类,分为训练集和验证集,同时将数字进行reshape,代码如下:

    from keras.datasets import mnist
    from keras.utils import to_categorical
    (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
    train_images = train_images.reshape((60000, 28, 28, 1))
    train_images = train_images.astype('float32') / 255
    test_images = test_images.reshape((10000, 28, 28, 1))
    test_images = test_images.astype('float32') / 255
    train_labels = to_categorical(train_labels)
    test_labels = to_categorical(test_labels)

    紧接着选择需要进行梯度下降的优化器,常见的有adagrad,adam,rmsprop等等,这里选择了rmsprop。损失函数loss function这里选择了Cross Entropy,也就是交叉熵(因为最后是一个softmax函数进行分类,我们常常用交叉熵来衡量模型的准确度,这个计算起来比较方便,也比较有道理)。模型fit的过程当中我选择了mini—batch小批量梯度下降法,用这个方法比较适合电脑,如果使用所有数据进行梯度下降,那么电脑跑很久才能够完成,如果使用小批量梯度下降,电脑则可以自动进行并行计算,时间减少。迭代次数我选择了10次,每一个mini——batch的批量为128,这个无所谓,这个参数适中即可,不可太大也不能太小。代码如下:

    model.compile(optimizer='rmsprop',
    loss='categorical_crossentropy',
    metrics=['accuracy'])
    model.fit(train_images, train_labels, epochs=10, batch_size=128)

    输出:

    Epoch 1/10
    60000/60000 [==============================] - 42s 703us/step - loss: 0.0192 - acc: 0.9940
    Epoch 2/10
    60000/60000 [==============================] - 42s 706us/step - loss: 0.0166 - acc: 0.9945
    Epoch 3/10
    60000/60000 [==============================] - 43s 724us/step - loss: 0.0146 - acc: 0.99580s - loss: 0.0145 - acc: 0.9
    Epoch 4/10
    60000/60000 [==============================] - 43s 720us/step - loss: 0.0129 - acc: 0.9960
    Epoch 5/10
    60000/60000 [==============================] - 43s 718us/step - loss: 0.0130 - acc: 0.9962
    Epoch 6/10
    60000/60000 [==============================] - 44s 728us/step - loss: 0.0105 - acc: 0.9966
    Epoch 7/10
    60000/60000 [==============================] - 44s 737us/step - loss: 0.0095 - acc: 0.9969
    Epoch 8/10
    60000/60000 [==============================] - 44s 728us/step - loss: 0.0101 - acc: 0.9972
    Epoch 9/10
    60000/60000 [==============================] - 44s 735us/step - loss: 0.0085 - acc: 0.9974
    Epoch 10/10
    60000/60000 [==============================] - 45s 743us/step - loss: 0.0081 - acc: 0.99750s - loss: 0.0081 - acc: 0.997

    可以看到模型经过十次迭代,训练集的准确度已经达到了%99.7以上,这样会不会出现过拟合的情况呢?用不用减少一下模型的迭代次数呢?笔者的心里怕怕的,于是用验证集来验证一下模型的准确度:

    test_loss, test_acc = model.evaluate(test_images, test_labels)
    print(test_acc)

    输出:

    0.9868

    模型的准确度达到了%98.68,接近百分之九十九的样子,比笔者仅用全连接神经网络训练的结果高了零点几的准确度,从中还是可以看出卷积神经网络的有效性,在没有进行调参的情况下准确度已经很高了!

  • 相关阅读:
    fill & stroke
    UIView 中 hidden、alpha、clear color 与 opaque 的区别
    图像处理之_仿射变换与透视变换
    GPU性能:光栅化、图层混合、离屏渲染
    PHP开发api接口安全验证的实例,值得一看
    svn钩子(hooks)自动部署代码到web目录
    linux安装配置SVN并设置钩子
    使用Navicat for MySQL把本地数据库上传到服务器
    svn upgrade
    QQ分享 QQ空间分享 API链接:
  • 原文地址:https://www.cnblogs.com/geeksongs/p/12695805.html
Copyright © 2011-2022 走看看