前几天用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("Baseline Error: %.2f%%" % (100-scores[1]*100))#输出错误率
结果:
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