基于卷积神经网络的手写体识别
- 19.2 深度学习的概念及关键技术
-
- 19.3 Python深度学习库——Keras
-
- 1、Keras的安装
- 2、Keras的网络层
- 3、用Keras构建神经网络
- 19.4 程序设计的思路
- 19.5 源代码
-
- 1、MNIST数据集
- 2、手写体识别案例体现
- 3、预测自己手写图像
19.2 深度学习的概念及关键技术
1、神经网络模型
·生物神经元
·轴突(输出)终端为其他神经元的树突(输入)
·人工神经网络
2、深度学习之卷积神经网络
·深度学习结构:含有多隐层的神经网络。
·池化:子采样,可看作一种特殊的卷积过程。
·激活函数:sigmoid、tanh、relu
·sigmoid:把一个实数压缩至0~1(分类的概率)
·relu:对于随机梯度下降的收敛有巨大的加速作用。
但脆弱,易造成不可逆转的死亡。
·卷积神经网络的网络结构
若干卷积层(配合relu) + 池化层 + 全连接层(分类器的作用)
19.3 Python深度学习库——Keras
1、Keras的安装
import numpy,scipy
import tensorflow as tf
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、手写体识别案例体现
import numpy as np
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
class ImageLoader(Loader):
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
def get_one_sample(self, picture):
sample = []
for i in range(28):
for j in range(28):
sample.append(picture[i][j])
return sample
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
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
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
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()
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()
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('')
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
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)
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)
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'))
model.compile(loss = 'categorical_crossentropy', optimizer='adadelta', metrics= ['accuracy'])
model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_test, Y_test))
score = model.evaluate(X_test, Y_test, verbose=0)
print('Test score:', score[0])
print('Trst accuracy:', score[1])
model.save('cnn_model.h5')
3、预测自己手写图像
from keras.models import load_model
import numpy as np
import cv2
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)