在本篇博文当中, 笔者采用了卷积神经网络来对手写数字进行识别, 采用的神经网络的结构是: 输入图片 -- 卷积层 -- 池化层 -- 卷积层 -- 池化层 -- 卷积层 -- 池化层 --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, 接近百分之九十九的样子, 比笔者仅用全连接神经网络训练的结果高了零点几的准确度, 从中还是可以看出卷积神经网络的有效性, 在没有进行调参的情况下准确度已经很高了!
来源: https://www.cnblogs.com/geeksongs/p/12695805.html