如何用卷积神经网络CNN识别手写数字集?

如何用卷积神经网络CNN识别手写数字集?

前几天用CNN识别手写数字集,后来看到kaggle上有一个比赛是识别手写数字集的,已经进行了一年多了,目前有1179个有效提交,最高的是100%,我做了一下,用keras做的,一开始用最简单的MLP,准确率只有98.19%,然后不断改进,现在是99.78%,然而我看到排名第一是100%,心碎 = =,于是又改进了一版,现在把最好的结果记录一下,如果提升了再来更新。

手写数字集相信大家应该很熟悉了,这个程序相当于学一门新语言的“Hello World”,或者mapreduce的“WordCount”:)这里就不多做介绍了,简单给大家看一下: 复制代码

1 # Author:Charlotte 2 # Plot mnist dataset

3 from keras.datasets import mnist 4 import matplotlib.pyplot as plt 5 # load the MNIST dataset

6 (X_train, y_train), (X_test, y_test) = mnist.load_data() 7 # plot 4 images as gray scale 8 plt.subplot(221)

9 plt.imshow(X_train[0], cmap=plt.get_cmap('PuBuGn_r')) 10 plt.subplot(222)

11 plt.imshow(X_train[1], cmap=plt.get_cmap('PuBuGn_r')) 12 plt.subplot(223)

13 plt.imshow(X_train[2], cmap=plt.get_cmap('PuBuGn_r')) 14 plt.subplot(224)

15 plt.imshow(X_train[3], cmap=plt.get_cmap('PuBuGn_r')) 16 # show the plot 17 plt.show() 复制代码 图:

1.BaseLine版本

一开始我没有想过用CNN做,因为比较耗时,所以想看看直接用比较简单的算法看能不能得到很好的效果。之前用过机器学习算法跑过一遍,最好的效果是SVM,96.8%(默认参数,未调优),所以这次准备用神经网络做。BaseLine版本用的是MultiLayer Percepton(多层感知机)。这个网络结构比较简单,输入--->隐含--->输出。隐含层采用的rectifier linear unit,输出直接选取的softmax进行多分类。

网络结构:

代码: 复制代码

1 # coding:utf-8

2 # Baseline MLP for MNIST dataset 3 import numpy

4 from keras.datasets import mnist 5 from keras.models import Sequential 6 from keras.layers import Dense 7 from keras.layers import Dropout 8 from keras.utils import np_utils 9 10 seed = 7

11 numpy.random.seed(seed) 12 #加载数据

13 (X_train, y_train), (X_test, y_test) = mnist.load_data() 14

15 num_pixels = X_train.shape[1] * X_train.shape[2]

16 X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32') 17 X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32') 18

19 X_train = X_train / 255 20 X_test = X_test / 255 21

22 # 对输出进行one hot编码

23 y_train = np_utils.to_categorical(y_train) 24 y_test = np_utils.to_categorical(y_test) 25 num_classes = y_test.shape[1] 26

27 # MLP模型

28 def baseline_model(): 29 model = Sequential()

30 model.add(Dense(num_pixels, input_dim=num_pixels, init='normal', activation='relu')) 31 model.add(Dense(num_classes, init='normal', activation='softmax')) 32 model.summary()

33 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) 34 return model 35

36 # 建立模型

37 model = baseline_model() 38 39 # Fit

40 model.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=10, batch_size=200, verbose=2) 41

42 #Evaluation

43 scores = model.evaluate(X_test, y_test, verbose=0)

44 print(\输出错误率 复制代码

结果: 复制代码

1 Layer (type) Output Shape Param # Connected to

2 ==================================================================================================== 3 dense_1 (Dense) (None, 784) 615440 dense_input_1[0][0]

4 ____________________________________________________________________________________________________ 5 dense_2 (Dense) (None, 10) 7850 dense_1[0][0]

6 ==================================================================================================== 7 Total params: 623290

8 ____________________________________________________________________________________________________ 9 Train on 60000 samples, validate on 10000 samples 10 Epoch 1/10

11 3s - loss: 0.2791 - acc: 0.9203 - val_loss: 0.1420 - val_acc: 0.9579 12 Epoch 2/10

13 3s - loss: 0.1122 - acc: 0.9679 - val_loss: 0.0992 - val_acc: 0.9699 14 Epoch 3/10

15 3s - loss: 0.0724 - acc: 0.9790 - val_loss: 0.0784 - val_acc: 0.9745 16 Epoch 4/10

17 3s - loss: 0.0509 - acc: 0.9853 - val_loss: 0.0774 - val_acc: 0.9773 18 Epoch 5/10

19 3s - loss: 0.0366 - acc: 0.9898 - val_loss: 0.0626 - val_acc: 0.9794 20 Epoch 6/10

21 3s - loss: 0.0265 - acc: 0.9930 - val_loss: 0.0639 - val_acc: 0.9797 22 Epoch 7/10

23 3s - loss: 0.0185 - acc: 0.9956 - val_loss: 0.0611 - val_acc: 0.9811 24 Epoch 8/10

25 3s - loss: 0.0150 - acc: 0.9967 - val_loss: 0.0616 - val_acc: 0.9816 26 Epoch 9/10

27 4s - loss: 0.0107 - acc: 0.9980 - val_loss: 0.0604 - val_acc: 0.9821 28 Epoch 10/10

29 4s - loss: 0.0073 - acc: 0.9988 - val_loss: 0.0611 - val_acc: 0.9819 30 Baseline Error: 1.81% 复制代码

可以看到结果还是不错的,正确率98.19%,错误率只有1.81%,而且只迭代十次效果也不错。这个时候我还是没想到去用CNN,而是想如果迭代100次,会不会效果好一点?于是我迭代了100次,结果如下:

Epoch 100/100

8s - loss: 4.6181e-07 - acc: 1.0000 - val_loss: 0.0982 - val_acc: 0.9854 Baseline Error: 1.46%

从结果中可以看出,迭代100次也只提高了0.35%,没有突破99%,所以就考虑用CNN来做。

2.简单的CNN网络

keras的CNN模块还是很全的,由于这里着重讲CNN的结果,对于CNN的基本知识就不展开讲了。

网络结构:

代码: 复制代码 1 #coding: utf-8 2 #Simple CNN 3 import numpy

4 from keras.datasets import mnist 5 from keras.models import Sequential 6 from keras.layers import Dense 7 from keras.layers import Dropout 8 from keras.layers import Flatten

9 from keras.layers.convolutional import Convolution2D 10 from keras.layers.convolutional import MaxPooling2D 11 from keras.utils import np_utils 12 13 seed = 7

14 numpy.random.seed(seed) 15

16 #加载数据

17 (X_train, y_train), (X_test, y_test) = mnist.load_data() 18 # reshape to be [samples][channels][width][height]

19 X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype('float32') 20 X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype('float32') 21

22 # normalize inputs from 0-255 to 0-1 23 X_train = X_train / 255 24 X_test = X_test / 255 25

26 # one hot encode outputs

27 y_train = np_utils.to_categorical(y_train) 28 y_test = np_utils.to_categorical(y_test) 29 num_classes = y_test.shape[1] 30

31 # define a simple CNN model 32 def baseline_model(): 33 # create model 34 model = Sequential()

联系客服:779662525#qq.com(#替换为@)