Keras中使用CNN来完成MNIST手写体识别

     在上一篇文章中,使用了传统的多层感知机神经网络来实现手写体识别,具体参见这里,最终获得了大概97%的神经网络,还能不能得到更高的准确率的,答案当然是肯定的,那就是卷积神经网络CNN。在这里我们使用keras的CNN网络来实现MNIST手写体识别任务。具体的步骤与之前类似,直接贴代码吧:

import numpy as np

f = np.load('mnist.npz')
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
f.close()
print('训练数据集样本数: %d ,标签个数 %d ' % (len(x_train), len(y_train)))
print('测试数据集样本数: %d ,标签个数  %d ' % (len(x_test), len(y_test)))

print(x_train.shape)
print(x_test.shape)


#特征值缩放

x_train = x_train / 255
x_test = x_test / 255


#输出标签进行one-hot编码
from keras.utils import np_utils

print('Integer-valued labels:')
print(y_train[:10])

#标签进行one-hot编码
y_train = np_utils.to_categorical(y_train, 10)
y_test = np_utils.to_categorical(y_test, 10)

print('One-hot labels:')
print(y_train[:10])


#定义模型架构:
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPool2D
from keras.models import Sequential

model = Sequential()
model.add(Conv2D(filters = 16, kernel_size = 2, padding = 'same', activation = 'relu',input_shape = (28, 28, 1)))
model.add(MaxPool2D(pool_size = 2))
model.add(Dropout(0.2))
model.add(Conv2D(filters = 32, kernel_size = 2, padding = 'same', activation = 'relu'))
model.add(MaxPool2D(pool_size = 2))
model.add(Dropout(0.2))
model.add(Conv2D(filters = 64, kernel_size = 2, padding = 'same', activation = 'relu'))
model.add(Flatten())
model.add(Dense(500, activation = 'relu'))
model.add(Dense(10, activation = 'softmax'))

model.summary()

#编译模型
model.compile(loss = 'categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])

#训练模型
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
print(x_train.shape)
print(x_test.shape)
model.fit(x_train, y_train, batch_size=128, epochs = 10, verbose=1, validation_data=(x_test, y_test))

#评估模型
score = model.evaluate(x_test, y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])

最终获得的准确率:,相比之下确实比传统的神经网络性能好了很多。当然

有兴趣的话还可以自己调整CNN的网络架构,或者调整其他超参数进行测试,相信能得到更好的结果。


那么,CNN相比MLP的不同?

    1.    MLP拥有超多的参数,在MNIST示例中,28*28像素的图片产生的需要更新的参数就超过了50W,CNN可以大大减少

            需要更新的参数。

    2.    MLP在将图片矩阵转换为向量过程中,丢失了图片中包含的所有二维信息,这种空间或者位置信息其实对我们发现像素值之间的规律其实是很有

            帮助的,因此我们需要一种全新的方式来处理图片输入,而CNN通过使用更加稀疏互联的层级来解决这些问题,它可以帮助我们保留发发现

            空间信息,进而发现规律。

总结下来,CNN具有的优点:

    1.    更少的权重;

    2.    空间共享。


注意:由于缺失数据集,代码可能跑不起来,需要下载数据集,这是代码和 数据集的地址:https://github.com/liujiao111/deep-learning/tree/master/cnn-keras-mnist-cnn

你可能感兴趣的:(深度学习,keras)