千彩手写识别系统(手写识别系统怎么安装)

/ 0评 / 0

千色手写识别系统(如何安装手写识别系统)2018-08-30 09:33程序员和新人学习

手写数字识别算法的设计与实现

本文利用python设计了基于TensorFlow的手写数字识别算法,并编写了GUI界面来构建手写数字识别系统。这是我的本科论文题目,当然也是机器学习的根本问题。这篇博文不会以论文的形式呈现,而是从编程实战完成机器学习项目的角度进行描述。

项目:本文要解决的重要问题是手写数字识别,最终要完成一个识别系统。

设计识别率高的算法,实现快速识别系统。

1 LeNet-5模型介绍

本文利用卷积神经网络实现手写数字识别,建模思想来自LeNet-5,如下图所示:

千彩手写识别系统(手写识别系统怎么安装)

这是最初用于手写数字识别的网络,我认为也是最简单的深度网络。

LeNet-5不包含输入,由七层组成。下层由卷积层和最大池层交替组成,上层为全内聚和高斯内聚。

LeNet-5的输入不同于BP神经网络的输入。假设图像是黑白的,LeNet-5的输入是一个32*32的二维矩阵。同时,输入和下一层也不是全连接,而是稀疏连接。这一层中每个神经元的输入来自前一层中神经元的局部区域(55)。卷积校验在原图像的卷积结果上加上相应的阈值,得到的结果经过激活函数处理,输出形成卷积层(C层)。卷积层中的每个特征图共享自己的权值和阈值,可以大大降低训练成本。下采样层执行二次采样,以便在保留有用信息的同时减少数据量。

第一卷积层(C1层)由六个特征图组成,每个特征图是一个2828个神经元的阵列,其中每个神经元负责通过卷积滤波器从55个区域中提取局部特征。一般来说,滤波器越多,得到的特征图就越多,原始图像的特征就越多。这一层有6(55+1)=156个训练参数,每一个像素由上层的55=25个像素和一个阈值连接计算,总共有2828156 = 122304个连接。

S2图层是与上述六种要素映射相对应的缩减像素采样图层(池图层)。池层的实现方式有两种,分离max-pooling和mean-pooling,LeNet-5采用mean-pooling,即取nn区域像素的平均值。平均C122窗口区域的像素,加上该层的阈值,然后通过激活函数的处理得到S2层。池化的实现,在保留图片信息的基础上,减少了权重参数,降低了计算成本,并且可以掌握过拟合。这一层有1*6+6=12个学习参数,S2的每个像素与C1层的22个像素和一个阈值连接,总共有6(22+1)1414=5880个连接。

S2层和C3层之间的联系相当复杂。C3卷积层由16个大小为1010的特征图组成,每个特征图与S2层中若干特征图的局部感受野(大小为55)相连。其中,前六张要素地图与S2层的三张持久性要素地图相连,后六张地图与S2层的四张持久性要素地图相连,后三张要素地图与S2层的四张持久性要素地图相连,最后一张地图与S2层的所有要素地图相连。这里卷积核的大小是55,所以有6(355+1)+9(455+1)+1(655+1)= 1516个学习参数。图像大小为2828,因此有151600个连接。

S4图层是C3图层的缩减像素采样。与S2类似,有161+16=32个学习参数和16(22+1)55=2000个连接。

C5层是由120个大小为11的特征图组成的卷积层,S4层与C5层全连通,因此学习参数总数为120(1625+1)=48120。

F6是84个神经元与C5完全连接,所以有84(120+1)=10164个学习参数。

卷积神经网络通过稀疏连接和共享权值和阈值,大大降低了计算成本。同时,池化的实现一定会减少过拟合问题的出现,非常适合图像处理和识别。

2.手写数字识别算法模型的构建

2.1各层的设计

有了第一节的基础知识,基本上,完善和提高它。

输入层设计

输入2828的矩阵,而不是向量。

激活功能的选择

Sigmoid函数具有光滑性、鲁棒性和导数自表达的优点,但其运算涉及指数运算。用倒灌法计算误差梯度时,导数涉及乘除运算,计算量比较大。同时,针对本文构造的两个卷积层和下采样层,由于sgmo技术资源网的id函数本身的特点,容易出现梯度在逆向流动中淡化的情况,导致网络训练难以完成。因此,本文设计的网络采用ReLU函数作为激活函数。

ReLU的表情:

千彩手写识别系统(手写识别系统怎么安装)

卷积层设计

本文采用离散卷积设计卷积神经网络,卷积步长为1,即每次计算度数和垂直方向移动一个像素。卷积核的大小是55。

缩减取样图层

本文降采样层的池化方法是max-pooling,大小为22。

输出层设计

输出层设置为10个神经网络节点。数字0~9的目的向量如下表所示:

千彩手写识别系统(手写识别系统怎么安装)

2.2网络模型的总体结构

千彩手写识别系统(手写识别系统怎么安装)

其实本文的网络构建参考了TensorFlow的手写数字识别官方教程,读者有兴趣可以详细浏览一下。

2.3编程算法

本文利用Python调用TensorFlow的api来完成手写数字识别的算法。

注意:这个程序的运行环境是:Win10,python3.5.2 .当然也可以在Linux下运行。由于TensorFlow与py2和py3兼容性相当,所以可以在Linux下的python2.7中运行。

#!/usr/bin/env python2

# -*-编码:utf-8 -*-

"""

创建于Fri 2017年2月17日19时50分49秒

@作者:黄永浩

"""

#导入模块

将numpy作为np导入

将matplotlib.pyplot作为plt导入

将张量流作为tf导入

导入时间

从日期时间导入时间增量

导入数学

从tensor flow . examples . tutorials . Mn ist导入输入数据

定义新权重(形状):

返回tf。变量(tf.truncated_normal(shape,stddev=0.05))

def new _ biases(长度):

返回tf。变量(tf.constant(0.1,shape=length))

def conv2d(x,W):

return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME ')

def max_pool_2x2(inputx):

return tf.nn.max_pool(inputx,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME ')

#导入数据

数据=输入数据。read _ data _ sets(" ./data ",one _ hot = true) # one _ hot表示2的[0.01.00.00]标准

打印("大小:")

打印("- Training-set:tt{} "。格式(len(data.train.labels))

打印("- Testing-set:tt{} "。格式(len(data.test.labels)))

打印("- Validation-set:tt{} "。格式(len(data.validation.labels)))

data . test . cls = NP . arg max(data . test . labels,axis=1) #显示真正的测试标签:[7 2 1...,4 5 6],10000个值

x = tf.placeholder("float ",shape=[None,784],name='x ')

x _ image = TF . shape(x,[-1,28,28,1])

y_true = tf.placeholder("float ",shape=[None,10],name='y_true ')

y_true_cls = tf.argmax(y_true,dimension=1)

# Conv 1

layer _ con v1 = { " weights ":new _ weights([5,5,1,32]),

" bias ":new _ bias([32])}

h _ con v1 = TF . nn . relu(conv 2d(x _ image,layer _ con v1[" weights "])+layer _ con v1[" bias "])

h_pool1 = max_pool_2x2(h_conv1)

# Conv 2

layer _ con v2 = { " weights ":new _ weights([5,5,32,64]),

" bias ":new _ bias([64])}

h _ con v2 = TF . nn . relu(conv 2d(h _ pool 1,layer _ con v2[" weights "])+layer _ con v2[" bias "])

h_pool2 = max_pool_2x2(h_conv2)

#全连接第1层

fc1 _ layer = { " weights ":new _ weights([7 * 7 * 64,1024]),

" bias ":new _ bias([1024])}

h _ pool 2 _ flat = TF . shape(h _ pool 2,[-1,7*7*64])

h _ fc1 = TF . nn . relu(TF . mat mul(h _ pool 2 _ flat,fc1 _ layer[" weights "])+fc1 _ layer[" bias "])

# Droupout层

keep _ prob = TF . placeholder(" float ")

h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)

#全连接第2层

fc2 _ layer = { " weights ":new _ weights([1024,10]),

【偏向】:new_weights([10])}

#预测类别

y _ pred = TF . nn . soft max(TF . matmul(h _ fc1 _ drop,fc2 _ layer[" weights "])+fc2 _ layer[" bias "])#输出类似于[0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]

y_pred_cls = tf.argmax(y_pred,dimension=1) #显示真正的预测数,如“2”

#要优化的成本函数

cross _ entropy =-TF . reduce _ mean(y _ true * TF . log(y _ pred))

optimizer = TF . train . adamoptimizer(learning _ rate = 1e-4)。最小化(交叉熵)

#绩效评估

correct _ prediction = TF . equal(y _ pred _ cls,y_true_cls)

准确度= TF . reduce _ mean(TF . cast(correct _ prediction,“float”))

用tf。会话()作为会话:

init = TF . global _ variables _ initializer()

sess.run(初始化)

训练批量大小= 50

定义优化(迭代次数):

total_iterations=0

start_time = time.time()

对于范围内的I(总迭代次数,总迭代次数+迭代次数):

x_batch,y _ true _ batch = data . train . next _ batch(train _ batch _ size)

feed_dict_train_op = {x:x_batch,y_true:y_true_batch,keep_prob:0.5}

feed_dict_train = {x:x_batch,y_true:y_true_batch,keep_prob:1.0}

sess.run(optimizer,feed_dict=feed_dict_train_op)

#每100次迭代打印一次状态。

如果i%100==0:

#计算训练集的准确度。

acc = sess.run(精度,feed_dict=feed_dict_train)

#用于打印的消息。

msg = "优化迭代:{0:>6},训练精度:{1:>6.1%} "

#打印出来。

print(消息格式(i+1,acc))

#更新执行的迭代总数

total _ iterations+= num _ iterations

#结束时间

end_time = time.time()

#开始时间和结束时间之间的差异。

time_dif =结束时间-开始时间

#打印时间使用情况

print("时间用法:"+str(Time delta(seconds = int(round(Time _ dif))))

测试批量大小= 256

def print_test_accuracy():

#测试集中的图像数量。

num_test = len(data.test.images)

cls _ pred = NP . zeros(shape = num _ test,dtype=np.int)

i = 0

当我<数量测试:

#下一批的结束索引表示为j

j = min(I+测试批量大小,数量测试)

#从索引I和j之间的测试集中获取图像

images = data.test.images[i:j,:]

#获取相关标签

labels = data.test.labels[i:j,:]

#用这些图片和标签创建一个feed-dict。

feed_dict={x:images,y_true:labels,keep_prob:1.0}

#使用Tensorflow计算预测类。

cls _ pred[I:j]= sess . run(y _ pred _ cls,feed_dict=feed_dict)

#将下一批的开始索引设置为

#当前批次的结束索引

i = j

cls_true = data.test.cls

correct = (cls_true==cls_pred)

correct_sum = correct.sum()

acc = float(正确总数)/数字测试

#打印精确度

msg = "测试集的准确性:{0:.1%} ({1}/{2})"

print(消息格式(acc,correct_sum,num_test))

# 10000次优化迭代后的性能

一个

2

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

四十二个

43

四十四

45

46

47

48

四十九个

50

51

五十二个

53

54

55

五十六岁

57

58

59

60

61

62

63

64

65

66

67

六十八

六十九

70

71

七十二个

73

74

75

76

77

七十八

79

80

81

82

83

84

八十五

86

87

88

八十九

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

运行结果表明,测试集的准确率约为99.2%。

我还写了一些帮助功能,可以看看一些识别问题的图片。

千彩手写识别系统(手写识别系统怎么安装)

你也可以查看混合矩阵,

千彩手写识别系统(手写识别系统怎么安装)

2.3手写识别系统的实现

最后,训练好的参数被保留并封装到GUI界面中,以形成手写识别系统。

千彩手写识别系统(手写识别系统怎么安装)

系统还增加了少量的图像预处理操作,如图像信息的灰度化、归一化等,更加贴近实际应用。

系统可以快速识别,如下图所示。

千彩手写识别系统(手写识别系统怎么安装)

3摘要

本文实现的系统实际上是一个基于卷积神经网络的手写数字识别系统。该系统能快速实现手写数字识别,成功率高。缺陷:只能准确识别单个号码,图像预处理不够。没有图像分割,读者可以自行添加和完善。

4收获

在我之前的本科期间,虽然努力学习了高等数学,线性代数,概率论,但是并没有认真学习机器学习。我是2017年才开始系统学习机器学习的相关知识,毕业论文也选择了相关课题。虽然是比较基础的,但是认真完成之后有一种学以致用的满足感。同时也鼓励我对技术资源网进行更深层次的理论学习和实践探讨,与各位读者共勉。

==================================

2018年5月13日更新

分享来源链接:https://pan.baidu.com/s/1BNlifR3DvIvTO5qkOTTpsQ

========================================

2018 . 6 . 6更新!!

Python(TensorFlow)实现手写字符识别

在这里,“手写字符”实际上是指notMNIST数据库中的手写字符,该数据库实际上与MNIST数据库相同。在这里,要实现手写字符识别,重要的是要说明TensorFlow框架具有很强的可扩展性,具体来说,只需修改少量代码就可以达到新的识别效果。

NotMnist数据库

这个数据库和MNIST数据库基本相同,除了10个数字被10个字母代替,分别是:A,B,C,D,E,F,G,H,I,J,k

当然这个数据库的鉴定难度更大,因为数据噪音更多,读者可以搜索详情。

真正的战斗

下载NotMNIST数据库后,放在这篇博文的上述网络中,不需要修改代码,直接训练,就可以得到一个可以识别字符的网络模型。

最后,在测试集中的准确率低于MNIST,约为96%。

本文还将训练好的网络模型封装在类似于上述系统的GUI系统中,

千彩手写识别系统(手写识别系统怎么安装)

后果还可以!

类似地,卷积层被可视化。

千彩手写识别系统(手写识别系统怎么安装)

标签

TensorFlow框架扩展性很强,只要设计好网络就可以轻松实现。同时,CNN识别的整体框架也差不多,很多识别义务都是通用的。当然,要在具体实践中获得近乎完美的效果,还是需要付出很多努力的!好好学习加油!

(如果你/你有什么有趣的想法,可以在下面留言。如果我有兴趣,有时间,我会努力去做。_)