基于CNN卷积神经网络手写数字识别模型
环境python3.10
今天介绍如何利用卷积神经网络进行MNIST数据集的手写数字识别,即将手写数字图像images识别为数字标签labels。
卷积神经网络是一类包含卷积计算且具有深度结构的前馈神经网络,是深度学习的代表算法之一,在图像处理和识别的方向上取得很大的成就,本文只要进行的是基于CNN卷积神经网络的数字识别模型训练。
建模思路如下:
1、数据预处理
2、建立模型
3、训练模型
4、评估师准确率
5、预测
代码:
import numpy as np from keras.datasets import mnist from keras.utils import np_utils from keras.models import Sequential,load_model from keras.layers import Dense,Dropout,Convolution2D,MaxPooling2D,Flatten from keras.optimizers import Adam import matplotlib.pyplot as plt from keras.utils.vis_utils import plot_model from keras.utils.image_utils import load_img,img_to_array from keras.applications.vgg16 import preprocess_input import sys,os import h5py from PIL import Image import random # 载入数据 (x_train,y_train),(x_test,y_test) = mnist.load_data() # (60000,28,28)->(60000,28,28,1) 60000个数据,28*28,深度为1 x_train = x_train.reshape(-1,28,28,1)/255.0 #-1能够自动匹配, x_test = x_test.reshape(-1,28,28,1)/255.0 # 换one hot格式 y_train = np_utils.to_categorical(y_train,num_classes=10) y_test = np_utils.to_categorical(y_test,num_classes=10) model_path = 'models/shouxie_CNN.h5' if os.path.exists(model_path): model = load_model(model_path) else: # 定义顺序模型 model = Sequential() # 第一个卷积层 input_shape 输入平面 filters 卷积核/滤波器个数 kernel_size 卷积窗口大小 strides 步长 padding padding方式 same/valid activation 激活函数 model.add(Convolution2D(input_shape = (28,28,1), filters = 32, kernel_size = 5, strides = 1, padding = 'same',activation = 'relu')) # 第一个池化层 model.add(MaxPooling2D(pool_size = 2, strides = 2, padding = 'same',)) # 第二个卷积层 model.add(Convolution2D(64,5,strides=1,padding='same',activation = 'relu')) #像64,5这样的,按照convolution2D这个函数形参顺序传入 # 第二个池化层 model.add(MaxPooling2D(2,2,'same')) # 把第二个池化层的输出扁平化为1维 model.add(Flatten()) # 第一个全连接层 model.add(Dense(1024,activation = 'relu')) # Dropout model.add(Dropout(0.5)) # 第二个全连接层 model.add(Dense(10,activation='softmax')) # 定义优化器 adam = Adam(lr=1e-4) # 定义优化器,loss function,训练过程中计算准确率 model.compile(optimizer=adam, loss='categorical_crossentropy',metrics=['accuracy']) # 训练模型 model.fit(x_train,y_train,batch_size=64,epochs=30) # 评估模型 loss,accuracy = model.evaluate(x_test,y_test) print('test loss',loss) print('test accuracy',accuracy) model.save(model_path) # 预测图库 n = 10 fig = plt.figure(figsize=(15, 3)) fig.canvas.manager.set_window_title("mnist图库预测结果:") pre = model.predict(x_test[:n], n) for i in range(n): plt.subplot(5, 10, i + 1) t = x_test[i].reshape(28, 28) plt.imshow(t, cmap='binary') plt.subplots_adjust(wspace=2) # 调整子图间的间距,挨太紧了不好看 plt.title('%d' % pre[i].argmax()) plt.xticks([]) # 取消x轴刻度 plt.yticks([]) plt.show() #预测query/number/下面的图片 dirpath = 'query/number/' filelist = os.listdir(dirpath) random.shuffle(filelist) n = len(filelist) fig = plt.figure(figsize=(15, 3)) fig.canvas.manager.set_window_title("query/number/下面的图片预测结果:") for i,filename in enumerate(filelist): plt.subplot(5, 10, i + 1) filepath = os.path.join(dirpath, filename) img=Image.open(filepath) img = img.convert('L') #图片灰度化 test_img=img.resize((28,28)) #修改图片大小 img_arr=np.array(test_img) #图片转为 np数组 img_data = img_arr.reshape(1,28,28,1) plt.imshow(img_arr, cmap='binary') predict = model.predict(img_data) predicte = np.argmax(predict[0]) plt.subplots_adjust(wspace=2) plt.title('%d' % predicte) plt.xticks([]) # 取消x轴刻度 plt.yticks([]) plt.show()
其中query/number 文件写我截了几张手写图片
执行结果:
query/number文件夹下图片我在预测时打乱了顺序:
结果相当不错
如果有个网站或者app的图形验证码是数字和字母组合的,结果你想想,基本和没有一样,呵呵
参考:
https://blog.csdn.net/qq_42100276/article/details/121181137
https://blog.csdn.net/weixin_43242765/article/details/106073904/
本文来自博客园,作者:河北大学-徐小波,转载请注明原文链接:https://www.cnblogs.com/xuxiaobo/p/17211977.html