前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习-用keras做cnn手写数字识别

机器学习-用keras做cnn手写数字识别

作者头像
sjw1998
发布2019-09-28 12:49:58
9180
发布2019-09-28 12:49:58
举报
文章被收录于专栏:孤独的S孤独的S

在用全连接做手写数字识别的时候,准确率有97%了,但是还是会出现一些测试图片没有预测对,出来更好的去优化参数,现在就直接改进神经网络的模型,用cnn去训练数据。


cnn--Convolutional neural network,简称cnn,中文翻译过来是,卷积神经网络

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。卷积神经网络具有表征学习(representation learning)能力,能够按其阶层结构对输入信息进行平移不变分类(shift-invariant classification),因此也被称为“平移不变人工神经网络(Shift-Invariant Artificial Neural Networks, SIANN)

-------摘自百度百科

cnn的结构有:卷积层,池化层,全连接层

卷积层(Convolution Layer):

卷积层主要进行卷积操作,这里会有一个叫卷积核的东西匹配数据的矩阵

池化层(Pooling Layer):

这里就是把卷积层完成卷积操作后得到的特征图(feature Map)进行分区域,池化,然后把每个区域取出最大值或者均值或者最小值来表示

数据处理

代码语言:javascript
复制
from keras.datasets import mnist
import numpy as np
from keras.utils import to_categorical
import matplotlib.pyplot as plt
(x_train,y_train),(x_test, y_test) = mnist.load_data()


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_train[0].shape)
input_shape = (28,28,1)

x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
y_train = to_categorical(y_train,10)
y_test = to_categorical(y_test, 10)

跟全连接的手写识别大部分一样,

有一点不一样的就是数据是(数据量,图片尺寸,图片尺寸,颜色)颜色的意思是黑白的就是1,彩色的就是3

接着就是卷积层跟池化层:

代码语言:javascript
复制
import keras
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D

model = Sequential()
model.add(Conv2D(32, kernel_size=(3,3),activation='relu', input_shape=input_shape))
model.add(Conv2D(64,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())

首先就是导入相应的模块和库,然后就是定义一个Sequential模型,接着添加卷积层,这里用Conv2D,其中第一个参数是训练这个图要检测的过滤器的数量(32,64),第二个参数是卷积核的大小,第三个是激活函数。一般用relu,第四个就是输入的形状的信息。是几维的,一般在第一层设置好就可以了。接着再添加一层卷积层,接着就是池化层,用来减少卷积层的结果的参数,有助于过度拟合,再接着就是Dropout(抓爆),有助于减低过拟合的现象,一般设置0.5,这里设置为0.25,

最后就是Flatten,将池化后的数据转成一列n行的数据。例如池化后的数据是(2,2,128),经过flatten后就是2*2*128 = 512

最后就是全连接层:

代码语言:javascript
复制
model.add(Dense(128,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10,activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model_log = model.fit(x_train,y_train,
                      batch_size=128,
                      epochs= 8,
                      verbose=1,
                      validation_data=(x_test,y_test))
score = model.evaluate(x_test,y_test,verbose=0)
print('test accuracy:', score[1])
model.save('cnnshouxie.h5')

这里跟去全连接的时候一样,不同就是加了一个抓爆。

就这样一个简单的cnn手写数字识别就做好了,不过手写数字识别相比于全连接的手写数字识别,cnn的训练比较慢,训练时间长,但是准确性好,我在全连接的图片没有测出来,在cnn中就可以测出来。最后在测试中去预测一下图片的结果。

代码语言:javascript
复制
from keras.models import load_model
import cv2
def prepare(path):
    img = cv2.imread(path,0)
    img = img.reshape(1,28,28,1)
    img = img.astype('float32')/255
    return img
model = load_model('cnnshouxie.h5')
model.summary()
img = prepare('3.jpg')
precetion = model.predict_classes(img)
print(precetion)

这里的预测代码跟全连接也是一样的,不同就是要修改图片的reshape的参数数目,要与模型的匹配的上

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 孤独的S 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档