18 深度学习案例——基于卷积神经网络的手写体识别

Lamaara ·
更新时间:2024-09-20
· 543 次阅读

基于卷积神经网络的手写体识别19.2 深度学习的概念及关键技术1、神经网络模型2、深度学习之卷积神经网络19.3 Python深度学习库——Keras1、Keras的安装2、Keras的网络层3、用Keras构建神经网络19.4 程序设计的思路19.5 源代码1、MNIST数据集2、手写体识别案例体现3、预测自己手写图像 #!/usr/bin/env python # coding: utf-8 19.2 深度学习的概念及关键技术 1、神经网络模型 ·生物神经元 ·轴突(输出)终端为其他神经元的树突(输入) ·人工神经网络 2、深度学习之卷积神经网络 ·深度学习结构:含有多隐层的神经网络。 ·池化:子采样,可看作一种特殊的卷积过程。 ·激活函数:sigmoid、tanh、relu ·sigmoid:把一个实数压缩至0~1(分类的概率) ·relu:对于随机梯度下降的收敛有巨大的加速作用。 但脆弱,易造成不可逆转的死亡。 ·卷积神经网络的网络结构 若干卷积层(配合relu) + 池化层 + 全连接层(分类器的作用) 19.3 Python深度学习库——Keras 1、Keras的安装 import numpy,scipy # In[ ]: import tensorflow as tf # In[ ]: import keras 2、Keras的网络层 (包括:常用层、卷积层、池化层、局部连接层、递归层、嵌入层、高级激活层、规范层、噪声层、包装层,自己编写的层) ·二维卷积层 ·Dense层(全连接层) 3、用Keras构建神经网络 步骤: 1、选择模型 2、构建网络层 3、编译 4、训练 5、预测 19.4 程序设计的思路 数据集的描述: ·训练与测试数据:28*28像素 ·训练数据集:测试数据集 = 60000 : 10000 ·输出层:十个神经元 网络结构: ·输入层:原始训练图像 ·第一卷积层:6个5*5的卷积核,步长为1 ·第一池化层:2*2的卷积核,步长为2的最大池化 ·第一卷积层:12个5*5的卷积核,步长为1 ·第一池化层:2*2的卷积核,步长为2的最大池化 ·输出层:十维向量,激活函数为sigmoid 代码流程简述: (1)获取训练数据 和 测试数据 (2)训练网络的超参数的定义(学习率,每次迭代中训练的样本数目,迭代次数) (3)构建网络层级结构 (4)编译模型 (5)训练模型 (6)网络模型评估 19.5 源代码 1、MNIST数据集 ·一个计算机视觉数据集(7包含0000张手写数字的灰度图片)28*28像素点 2、手写体识别案例体现 # 读取MNIST数据集 import numpy as np # In[ ]: # 数据加载基类,派生出 图片加载器 和 标签加载器 class Loader(object): def __init__(self, path, count): self.path = path self.count = count def get_file_count(self): print(self.path) f = open(self.path, 'rb') content = f.read() f.close() return content # In[ ]: # 图像数据加载器 class ImageLoader(Loader): # 内部函数,从文件字节数组中获取第index个图像数据 def get_picture(self, content, index): start = index * 28 * 28 +16 picture = [] for i in range(28): picture.append([]) for j in range(28): byte1 = content[start + i*28 + j] picture[i].append(byte1) return picture # 将图像数据转化成长度为784行向量形式 def get_one_sample(self, picture): sample = [] for i in range(28): for j in range(28): sample.append(picture[i][j]) return sample # 加载数据文件,获得全部样本的输入向量,onerow表示是否将每张图片转化为行向量,to2表示是否转化为0,1矩阵 def load(self, onerow = False): content = self.get_file_content() data_set = [] for index in range(self.count): onepic = self.get_picture(content, index) if onerow: onepic = self.get_one_sample(onepic) data_set.append(onepic) return data_set # In[ ]: # 标签数据加载器 class LabelLoader(Loader): # 加载数据文件,获得全部样本的标签向量 def load(self): content = self.get_file_content() labels = [] for index in range(self.count): onelabel = content[index + 8] onelabelvec = self.norm(onelabel) labels.append(onelabelvec) return labels # 内部函数,one-hot编码,用于将一个值转换为10维标签向量 def norm(self, label): label_vec = [] label_value = label for i in range(10): if i == label_value: label_vec.append(1) else: label_vec.append(0) return label_vec # 获得训练数据集,onerow表示是否将每张图片转化为行向量 def get_training_data_set(num, onerow = False): image_loader = ImageLoader('train-images.idx3-ubyte', num) label_loader = LabelLoader('train-labels.idx1-ubyte', num) return image_loader(onerow), label_loader.load() # 获得测试数据集, onerow表示是否将每张图片转化为行向量 def get_test_data_set(num, onerow = False): image_loader = ImageLoader('t10k-images.idx3-ubyte', num) label_loader = LabelLoader('t10k-labels.idx1-ubyte', num) return image_loader.load(onerow), label_loader.load() # 将个长度为784的行向量打印成图形的样式 def printimg(onepic): onepic = onepic.reshape(28, 28) for i in range(28): for j in range(28): if onepic[i, j] == 0: print(' ', end = '') else: print('* ', end = '') print('') # In[ ]: # 训练及测试数据集 import numpy as np np.random.seed(1337) from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten from keras.layers import Conv2D, MaxPooling2D, AveragePooling2D import MNIST # In[ ]: # 全局变量 batch_size = 128 # 批处理样本数量 nb_classes = 10 # 分类数目 epochs = 600 # 迭代次数 img_rows, img_cols = 28, 28 # 输入图片样本的宽、高 nb_filters = 32 # 卷积核的个数 pool_size = (2, 2) # 池化层的大小 kernel_size = (5, 5) # 卷积核的大小 input_shape = (img_rows, img_cols, 1) # 输入图片的维度 # In[ ]: X_train, Y_train = MNIST.get_test_data_set(6000, False) X_test, Y_test = MNIST.get_test_data_set(1000, False) X_train = np.array(X_train).astype(bool).astype(float) / 255 # 数据归一化 X_train = X_train[:,:,:,np.newaxis] # 添加一个通道,代表图片通道 Y_train = np.array(Y_train) X_test = np.array(X_test).astype(bool).astype(float) / 255 # 数据归一化 X_test = X_test[:,:,:,np.newaxis] # 添加一个通道,代表图片通道 Y_test = np.array(Y_test) print('样本数据集的维度:', X_train.shape, Y_train.shape) print('测试数据集的维度:', X_test.shape, Y_test.shape) # In[ ]: # 构建模型 model = Sequential() model.add(Conv2D(6, kernel_size, input_shape=input_shape, strides=1)) model.add(AveragePooling2D(pool_size=pool_size, strides=2)) model.add(Conv2D(12, kernel_size, strides=1)) model.add(AveragePooling2D(pool_size=pool_size, strides=2)) model.add(Flatten()) # 拉成一维度矩阵 model.add(Dense(nb_classes)) model.add(Activation('sigmoid')) # In[ ]: # 编译模型 model.compile(loss = 'categorical_crossentropy', optimizer='adadelta', metrics= ['accuracy']) # In[ ]: # 训练模型(420最为精确!!) model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_test, Y_test)) # In[ ]: # 评估模型 score = model.evaluate(X_test, Y_test, verbose=0) print('Test score:', score[0]) print('Trst accuracy:', score[1]) # In[ ]: # 保存模型!!! model.save('cnn_model.h5') 3、预测自己手写图像 # In[2]: from keras.models import load_model import numpy as np import cv2 # In[ ]: model = load_model('cnn_model.h5') image = cv2.imread('1.png', 0) img = cv2.imread('1.png', 0) img = np.reshape(img, (1,28,28,1)).astype(bool).astype('float32') my_proba = model.predict_proba(img) my_predict = model.predict_classes(img) print('识别为:') print(my_proba * 10**10) print(my_predict * 10**10) cv2.imshow('Image1', image) cv2.waitKey(0)
作者:料理码王



手写体 学习 卷积神经网络 深度学习 神经网络 卷积

需要 登录 后方可回复, 如果你还没有账号请 注册新账号