array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 使用 Keras + CNN 识别 MNIST 手写数字 - 爱码网

导入模块:

from keras.datasets import mnist
from keras.utils import np_utils
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D

下载手写数据集:

(x_Train,y_Train),(x_Test,y_Test)=mnist.load_data()
print(x_Train.shape)
print(y_Train.shape)
print(x_Test.shape)
print(y_Test.shape)


使用 Keras + CNN 识别 MNIST 手写数字

 

 

训练数据60000个,长度和宽度都是28,标签也是6000个。

测试数据10000个。

图形化数据集,查看前10个数据集:

def polt_images_label_prediction(images,labels,idx,num=10):
    fig=plt.gcf()
    fig.set_size_inches(12,14)
    for i in range(num):
        ax=plt.subplot(5,2,1+i)
        ax.imshow(images[idx],cmap='binary')
        title='label='+str(labels[idx])
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])
        ax.set_yticks([])
    plt.show()
polt_images_label_prediction(x_Train,y_Train,0)

使用 Keras + CNN 识别 MNIST 手写数字

数据预处理:

将features以reshape转化为6000*28*28*1的4维矩阵,并将其标准化。

x_Train4D=x_Train.reshape(x_Train.shape[0],28,28,1).astype('float32')
x_Test4D = x_Test.reshape(x_Test.shape[0], 28, 28, 1).astype('float32')
x_Train4D_normalize = x_Train4D / 255
x_Test4D_normalize = x_Test4D / 255

数据预处理,对标签进行one-hot编码处理:

#未转化第一个数是 5
print(y_Train[:1])
y_TrainOneHot = np_utils.to_categorical(y_Train)
#转化  One-Hot Encoding 都是以0 1 表示,5 在第六个位置
print(y_TrainOneHot[:1])

使用 Keras + CNN 识别 MNIST 手写数字

建立模型:

#建立一个 Sequential 线性堆叠模型
model=Sequential()
#建立第一个卷积层,input_shape 输入数字图像大小为 28*28*1, filters 卷积核个数 16 个,kernel_size 卷积核大小 3*3
#padding 是否零填充 same 表示填充, activation 激活函数 relu
model.add(Conv2D(filters = 16,
          kernel_size = (3, 3),
          padding = 'same',
          input_shape = (28, 28, 1),
          activation = 'relu'))
#建立第一个池化层 pool_size 池化窗口 2
model.add(MaxPooling2D(pool_size = (2, 2)))
#建立第二个卷积层, filters 卷积核个数 36 个,kernel_size 卷积核大小 3*3
#padding 是否零填充 same 表示填充, activation 激活函数 relu
model.add(Conv2D(filters = 36,
                kernel_size = (3, 3),
                padding = 'same',
                activation = 'relu'))
#建立第二个池化层 pool_size 池化窗口 2
model.add(MaxPooling2D(pool_size = (2, 2)))
#加入Dropout避免过度拟合
model.add(Dropout(0.25))
#建立平坦层,将多维向量转化为一维向量
model.add(Flatten())
#建立隐藏层,隐藏层有 128 个神经元, activation 激活函数用 relu
model.add(Dense(128, activation = 'relu'))
#加入Dropout避免过度拟合
model.add(Dropout(0.25))
#建立输出层,一共有 10 个神经元,因为 0 到 9 一共有 10 个类别, activation 激活函数用 softmax 这个函数用来分类
model.add(Dense(10, activation = 'softmax'))

查看模型摘要:

print(model.summary())

使用 Keras + CNN 识别 MNIST 手写数字

训练模型:

#定义训练模型, loss 损失函数用 categorical_crossentropy, optimizer 优化器用 adam, metrics 度量用 accuracy
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
#开始训练模型, x 是训练数据集, y 是训练数据集的标签, validation_split 是把训练数据集分为 8 份训练数据集 2 份验证集
#epochs 是迭代次数 20, batch_size 是批量 256, verbose 为 2 显示训练过程
train_history = model.fit(x = x_Train4D_normalize,
                          y = y_TrainOneHot,
                         validation_split = 0.2,
                         epochs = 20,
                         batch_size = 256,
                         verbose = 2)

使用 Keras + CNN 识别 MNIST 手写数字

查看训练模型loss和accuracy:

def show_train_history(train_history, train, validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train History')
    plt.ylabel(train)
    plt.xlabel('Epoch')
    plt.legend(['train', 'validation'], loc = 'upper left')
    plt.show()
show_train_history(train_history, 'loss', 'val_loss')
show_train_history(train_history, 'accuracy', 'val_accuracy')

使用 Keras + CNN 识别 MNIST 手写数字

使用 Keras + CNN 识别 MNIST 手写数字

评估模型,准确率为99.21%。

scores = model.evaluate(x_Test4D_normalize, y_TestOneHot)
print(scores[1])

使用 Keras + CNN 识别 MNIST 手写数字

预测模型:

#预测测试集第一个数字
prediction = np.argmax(model.predict(x_Test4D_normalize[:1]))
print('预测值:', prediction)
print('真实值:', np.argmax(y_TestOneHot[:1]))

使用 Keras + CNN 识别 MNIST 手写数字

 


 

【分析】

由训练过程数据以及精度图卡伊看出,当迭代到10次的时候就达到了最高精度,后面的另外10次迭代并没有让精度变得更好。所以把epochs改成10再仿真一次:

使用 Keras + CNN 识别 MNIST 手写数字

使用 Keras + CNN 识别 MNIST 手写数字

模型评估,准确率为99.11%,比迭代20次时准确率降低了0.1%。

使用 Keras + CNN 识别 MNIST 手写数字


 

看网上说,训练模型的时候先用小数据大参数,先让它过拟合,再慢慢调小,filter能用256就不用128,所以我先调一下filter参数看看是否会过拟合。

学到的一条经验就是在看训练参数的时候不要看准确率这个指标,而是要看损失函数这个指标,毕竟优化的就是loss。

使用 Keras + CNN 识别 MNIST 手写数字

 

 

两层的卷积核个数分别改成了32和64.

使用 Keras + CNN 识别 MNIST 手写数字

 

 但是并没有过拟合。

使用 Keras + CNN 识别 MNIST 手写数字

 

 准确率99.16%也并没有什么大的变化。

所以增大卷和核数量,改为64和128。

使用 Keras + CNN 识别 MNIST 手写数字

 

 

使用 Keras + CNN 识别 MNIST 手写数字

 

 

使用 Keras + CNN 识别 MNIST 手写数字

 

 

使用 Keras + CNN 识别 MNIST 手写数字

 

 准确率99.14%,这是已经过拟合了吧,毕竟训练的accuracy和测试的val_accuracy分别是99.72%和99.15%差的还挺多的。

 

再调大参数试试:

使用 Keras + CNN 识别 MNIST 手写数字

 

 

使用 Keras + CNN 识别 MNIST 手写数字

 

 

准确率99.32%。

感觉纠结与此已然没有太多意义,本身就是想练习一下调参。所以打算把参数改成原来的,并且增加一层卷积层试试:


#建立第三个卷积层, filters 卷积核个数 64 个,kernel_size 卷积核大小 3*3
#padding 是否零填充 same 表示填充, activation 激活函数 relu
model.add(Conv2D(filters = 64,
                kernel_size = (3, 3),
                padding = 'same',
                activation = 'relu'))
#建立第三个池化层 pool_size 池化窗口 2
model.add(MaxPooling2D(pool_size = (2, 2)))

多加一层,10次迭代,结果准确率99.17%:

使用 Keras + CNN 识别 MNIST 手写数字

 

 使用 Keras + CNN 识别 MNIST 手写数字

 

 


使用 Keras + CNN 识别 MNIST 手写数字

 

 

就算模型只有一层卷积层,准确率也有98.6%。

——2019.11.12

 

 

相关文章: