minst手写体识别是深度学习的一个基础实验,相当于每一个程序开发的"hello world",下面通过简单介绍学习一下使用keras工具库如何快速搭建一个识别手写字体的网络模型
1.keras介绍
Keras是一个高层神经网络API,Keras由纯Python编写而成。基于Theano和TensorFlow的深度学习库。
Keras的设计原则是:
- 用户友好:Keras是为人类而不是天顶星人设计的API。用户的使用体验始终是我们考虑的首要和中心内容。Keras遵循减少认知困难的最佳实践:Keras提供一致而简洁的API, 能够极大减少一般应用下用户的工作量,同时,Keras提供清晰和具有实践意义的bug反馈。
- 模块性:模型可理解为一个层的序列或数据的运算图,完全可配置的模块可以用最少的代价自由组合在一起。具体而言,网络层、损失函数、优化器、初始化策略、激活函数、正则化方法都是独立的模块,你可以使用它们来构建自己的模型。
- 易扩展性:添加新模块超级容易,只需要仿照现有的模块编写新的类或函数即可。创建新模块的便利性使得Keras更适合于先进的研究工作。
- 与Python协作:Keras没有单独的模型配置文件类型(作为对比,caffe有),模型由python代码描述,使其更紧凑和更易debug,并提供了扩展的便利性。
Keras适用的Python版本是:Python 2.7-3.6
2.keras网络结构
keras网络结构3.数据输入
# 从Keras导入Mnist数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#输出数据集查看
print('样本数 ')
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
结果显示为
样本数
(60000,28,28)(60000,)
(10000,28,28)(10000,)
可以看到我们下载的数据集包含6万张28.28像素大小的训练集图像和1万张28.28像素的测试集图像,我们要识别的字体包含0~9数字,也就是相当于10个类别的图片
# 显示1张手写数字图片
plt.imshow(x_train[0], cmap=plt.get_cmap('gray'))
结果显示
手写字体5.png
#数据归一化
x_train = x_train.reshape(60000, 28*28)
x_test = x_test.reshape(10000, 28*28)
x_train = x_train / 255
x_test = x_test / 255
归一化:因为softmax函数的取值是0到1之间的,网络最后一个节点的输出也是如此,所以经常要对样本的输出归一化处理。
#进行one-hot编码
y_train = keras.utils.to_categorical(y_train,10)
y_test = keras.utils.to_categorical(y_test,10)
在数据处理和特征工程中,经常会遇到类型数据,如性别分为[男,女], 手机运营商分为[移动,联通,电信]等,我们通常将其转为数值带入模型,如[0,1], [-1,0,1]等,但模型往往默认为连续型数值进行处理,这样其实是违背我们最初设计的,也会影响模型效果。 独热编码便是解决这个问题,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。比如上面的代码处理后5的独热编码为 [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]
4.构建模型
model = Sequential()
# 第一个隐藏层
model.add(Dense(512, activation='relu', input_shape=(28*28,)))
# 第二个隐藏层
model.add(Dense(256, activation='relu'))
# 输出层
model.add(Dense(10, activation='softmax'))
model.summary()
我们构建包含输入层在内的共四层网络,第一层输出维度设置为512,使用relu函数作为激活函数,因为是承接输入层,所以固定输入矩阵大小为784;第二层定义该层的输出维度为256,第三层设置为10,因为有10个标签,设置激活函数为常用的分类函数softmax。每层的结构如下图。
模型结构图
5.训练模型
model.compile(optimizer=SGD(), loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=64, epochs=5, validation_data=(x_test, y_test))
我们训练模型采用SGD优化器,使用二分类交叉熵计算损失函数,并得到准确率。使用之前转换好格式的训练集进行模型的训练优化,设置批次大小为64(也就是一次处理64张图片),迭代次数设置为5次,并且将测试集带入以得到准确率。
结果显示
迭代结果
从结果可以看出我们的模型准确率有0.9,并且损失函数结果为0.2201,可以说识别准确率已经很高了。
6.应用模型
我们训练好这个模型后,就可以使用它来进行手写字体的识别实验了,比如我们就使用下载的测试集来当验证集,带入模型中
score = model.evaluate(x_test, y_test)
print('LOSS', score[0])
print('ACCU', score[1])
结果显示
应用结果
我们把数据带入后得到了准确率大小为0.9387的结果,这个结果与我们刚刚训练出来的结果相一致,由此也证明我们的模型可以很好的识别minst数据集中的手写字体识别。
通过这样的例子可以完整的理解神经网络是如何识别一个图像的过程,也可以看到使用keras的库让我们能够快速搭建一个网络模型,并且封装了感知器的搭建过程,使用起来非常方便。
网友评论