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

2019-09-28 12:49:58 浏览数 (1)

在用全连接做手写数字识别的时候,准确率有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的参数数目,要与模型的匹配的上

0 人点赞