Android平台上基于卷积神经网络的手写数字识别实验

2017-11-09 08:46朱虎明缑水平田小林焦李成张小华
计算机教育 2017年11期
关键词:C语言程序设计教材

朱虎明,罗 政,缑水平,田小林,焦李成,张小华

(西安电子科技大学 电子工程学院,陕西 西安 710071)

刘喜平, 万常选, 舒 蔚, 骆斯文

(江西财经大学 信息管理学院, 江西 南昌 330013)

Android平台上基于卷积神经网络的手写数字识别实验

朱虎明,罗 政,缑水平,田小林,焦李成,张小华

(西安电子科技大学 电子工程学院,陕西 西安 710071)

卷积神经网络算法由于良好的性能已经广泛使用在自动驾驶、语音识别和图像分类等领域,为增强学生学习和利用卷积神经网络算法的能力,文章设计在Android平台上基于TensorFlow卷积神经网络的手写数字识别实验,并说明实施过程,同时介绍卷积神经网络算法、Android平台相关技术原理和实验过程。

卷积神经网络; 手写数字识别;Android; TensorFlow

1 背 景

2006年加拿大多伦多大学的Hinton教授提出了基于“逐层训练”和“精调”的两阶段策略,解决深度神经网络中参数训练的难题,此后纽约大学的LeCun、蒙特利尔大学的Bengio和斯坦福大学的Andrew Ng等人对深度神经网络展开研究,并提出深度自编码器(Deep Auto Encoder)、深度置信网(Deep Belief Networks)、卷积神经网络(Convolutional Neural Networks)等深度模型[1]。深度神经网络获得学术界和工业界的广泛关注,在围棋和德州扑克等领域获得突破性进展,而且深度学习的相关课程也逐渐进入高校。在国内,吴立德教授在复旦大学开设了深度学习课程;在国外,一些知名高校也开设了深度学习课程,如斯坦福大学、牛津大学、纽约大学等。目前,深度学习在本科教学中目前涉及的内容还比较少,为帮助学生更好的理解和学习算法,笔者设计在Android平台上进行深度学习实验,实验以卷积神经网络为例,利用TensorFlow深度学习框架并将其应用于手写体识别。

卷积神经网络是近年发展起来并引起广泛重视的一种高效识别方法。20世纪60年代,Hubel和Wiesel在研究猫脑皮层中的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出卷积神经网络。现在,卷积神经网络已经成为众多科学领域的研究热点之一,特别是在模式分类领域,由于卷积神经网络算法避免了对图像手工提取特征等步骤,因而得到更为广泛的应用。

随着智能终端在全球范围内的普及,目前主流的智能手机操作系统有谷歌公司的Android系统、苹果公司的iOS系统和微软公司的Windows Phone系统,由于Android系统的开源特性,使得华为、三星、小米等厂商的手机都采用了Android操作系统。2017年5月,NetMarketShare数据网站公布了手机操作系统市场份额,其中Android系统的占有率是65.19%,排名居首。鉴于Android系统越来越广的使用领域,目前高校开设了很多基于Android系统的实验类课程[23]。

2015年11月9日,Google发布并开源第二代人工智能学习系统TensorFlow[4],其命名源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到另一端的计算,TensorFlow是将复杂的数据输入至人工智能神经网中进行分析和处理过程的系统,它可在小到一部智能手机、大到数千台数据中心服务器的各种设备上运行。

2 卷积神经网络算法介绍

卷积神经网络是一种前馈神经网络[5],其基本结构一般包括两层:其一为特征提取层,每个神经元的输入与前一层的局部感受相连,并提取该局部的特征[5],一旦该局部特征被提取后,它与其他特征间的位置关系也随之确定下来;其二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。

卷积神经网络主要用来识别位移、缩放及扭曲不变性的二维图像[68]。由于卷积神经网络的卷积层通过训练数据进行学习,所以在使用时,避免了显式的特征提取,而隐式地从训练数据中进行学习;再者由于同一特征映射面上的神经元权值相同,所以网络可以并行学习。

本次实验的卷积神经网络是由两个卷积层(conv)、两个池化层(pool)和两个全连接层(fc)以及一个softmax组成。第一层卷积层有32个5*5的卷积核,网络采用了Relu(Recti fi ed Linear Unit 修正线性函数)作为激活函数。第二层是最大池化层,求取特征图后,用大小为2*2池化窗口对特征图进行池化操作。第三层中,有64个5*5的卷积核,同样采用Relu作为激活函数。第四层也是池化窗口为2*2的最大池化层。第五层是全连接层,有1024个神经元。为了减少过拟合,在输出层之前加入dropout算子。只在训练过程中启用dropout。第六层也是全连接层,有10个神经元。最后添加一个softmax层,将网络输出值转换成概率值,网络结构如图1所示。

3 实验步骤

实验过程分为两个部分,训练过程和推理过程。在训练过程中,首先要建立卷积神经网络的网络结构,同时设置训练过程的一些超参数,如学习率、动力因子、最大迭代次数等,接着使用训练集对网络参数进行训练,但在部分情况下,会把训练集划分出一部分作为验证集用来交叉验证。推理过程是用测试集对模型进行验证。实验流程如图2所示。

图1 卷积神经网络网络结构

图2 实验流程

3.1 训练过程

卷积神经网络训练过程在计算机上完成,分为3个步骤:①建立卷积神经网络网络结构;②利用带有GPU的计算机训练模型;③保存模型。

(1)建立卷积神经网络网络结构。

TensorFlow深度学习框架提供了python语言的API接口,因此利用python编程语言编写训练代码,建立卷积神经网络的网络结构,本次实验参考TensorFlow官方给出的Deep MNIST for Experts模型训练卷积神经网络。

(2)利用带有GPU的计算机训练模型。

在建立好网络结构之后,下一步是训练模型,训练模型的时间一般比推理时间长很多,且模型的超参数会影响正确率,所以一般需要多次训练,一般采用安装有GPU的计算机进行训练,由于GPU强大的计算能力,可以大大缩短深度神经网络的训练时间。

本次实验采用的是MNIST数据集,手写数字MNIST数据库包含一个训练样本集和一个测试样本集,训练样本集包含60,000个样例,测试样本集包含10,000个样例。图片被归一化成一张放在中间部位的28*28像素的灰度图。该数据集包含0~9共10类阿拉伯数字。数据集共包含4个文件,它们分别是训练样本数据集、训练数据样本标签集、测试用例数据集和测试用例数据标签集。MNIST的部分样例如图3所示。

图3 MNIST数据集样例

本实验中,训练优化方法分别采用Adagrad、GradienDescent和Adam,其中GradienDescent优化方法测试了多组参数,对比识别的准确率(见表1)发现,GradientDescent(学习率为0.001)的正确率最高,因此网络采用GradientDescent(学习率为0.001)的优化算法。

(3)保存模型。

在模型训练结束后,使用TensorFlow的API函数tf.g fi le.FastGFile()将模型保存为.pb文件,该函数既能保存模型的结构,又能够保存模型中参数的值。

表1 优化算法对比表

3.2 推理过程

推理过程分为两个步骤:①搭建Android平台上的卷积神经网络系统;②系统性能测试。

(1)搭建Android平台上的卷积神经网络。

本次实验所用到的集成开发软件为Android工具Android studio IDE,设计开发的Android应用程序分为两个部分,第一部分是UI界面的设计,第二部分是将采集的测试样本进行推理。

UI界面设计主要是和用户进行交互,实验中使用了两个Button和一个Bitmap控件。系统界面布局如图4所示,本次实验中Android应用通过Bitmap和Canvas操作使得界面自适应屏幕大小。通过Android触控屏记录手写过程的轨迹,并将手写轨迹存储为图像数据即可生成了手写体数据。执行图像预处理,即后台处理生成bitmap,作为模型的输入。一个Button用作清屏,另一个Button用作触发推理事件,即调用训练好的模型进行推理,并且将返回推理结果更新到界面上。

图4 系统界面布局

接下来是将TensorFlow移植到Android平台上,首先编译在Android平台上调用TensorFlow模型需要的jar包和so文件;接着将训练好的模型pb文件放入项目中app/src/main/assets位置,添加jar包和so文件;接下来是创建接口和实现调用,分为四步:导入jar包、导入so文件、Tensor fl ow 接口初始化和模型的调用。

然后接下来的主要工作就是安卓项目的编译以及将编译完的apk文件安装到手机,这部分内容与一般的安卓项目没有区别。

(2)系统性能测试。

基于卷积神经网络的手写数字识别APP设计完成且安装到Android设备后,在运行时,利用Android的触屏功能记录轨迹,手写完成后,单击测试按钮,调用模型,进行识别,并输出结果到用户界面。在测试完成后,单击清除按钮,会将绘图区域内生成的手写数字以及识别结果清除。

4 实验结果展示

本次实验结果如图5、图6所示,由图5可知,在Android上实现的手写数字识别算法取得了较好的识别效果。图6则是无法正确识别的实例,比如当字符比较小的时候或者字符出现在Bitmap的边缘的时候,识别效果不太理想。

笔者下一步将着重从图像预处理方面改善因字符太小和书写位置偏离中心位置等原因造成手写数字识别度不高的问题。

图5 手写数字识别图—识别正确

图6 手写数字识别图—识别错误

[1] Hinton G E, Salakhutdinov R R. Reducing the dimensionality of data with neural networks[J]. Science, 2006(5786): 504-507

[2] 刘春.以Android应用为案例的软件工程教学[J]. 计算机教育,2015(11):75-77.

[3] 刘成明,李玮玮. Android手机开发课程的案例教学法[J]. 计算机教育, 2015(14): 37-40.

[4] Abadi M, Agarwal A, Barham P, et al. TensorFlow: Large-Scale machine learning on heterogeneous distributed systems[EB/OL].(2016-03-14)[2017-04-05]. http://download. tensor fl ow.ong/paper/white paper 2015.pdf.

[5] 吴岸城. 神经网络与深度学习[M]. 北京: 电子工业出版社. 2016.

[6] 周飞燕, 金林鹏, 董军. 卷积神经网络研究综述[J]. 计算机学报, 2017(7): 1-23.

[7] 余滨, 李绍滋, 徐素霞, 等. 深度学习: 开启大数据时代的钥匙[J]. 工程研究——跨学科视野中的工程, 2014(3): 234-235.

[8] 焦李成, 杨淑媛, 刘芳, 等. 神经网络七十年: 回顾与展望[J]. 计算机学报, 2016(8): 1697-1716.

1672-5913(2017)11-0159-04

G642

西安电子科技大学新实验开发与新实验设备研制及实验教学改革(SY1408)。

朱虎明,男,副教授,研究方向为高性能计算及其应用,zhuhum@mail.xidian.edu.cn。

(编辑:史志伟)

教材建设

器—术—道:程序设计教材建设经验谈

刘喜平, 万常选, 舒 蔚, 骆斯文

(江西财经大学 信息管理学院, 江西 南昌 330013)

文章编号:1672-5913(2017)11-0163-04

中图分类号:G642

摘 要:介绍编程能力培养的3个层次:器—术—道,分析这3个层次对能力的要求,然后探讨《C程序设计:方法与实践》教材在夯实编程之器、提炼编程之术、引导编程之道3个方面中的做法。

关键词:程序设计; 教材; C语言; 器—术—道

基金项目:江西省2013年度普通本科高校卓越工程师教育培养计划项目(赣教高字[2013]78 号);江西省高等学校省级教改立项重点项目(JXJG-16-4-6);江西财经大学“3+7+x”专业主干课程建设项目(教务通知字[2017]33号)。

作者简介:刘喜平,男,副教授,研究方向为数据库和数据挖掘,lewislxp@gmail.com;

万常选(通信作者),男,教授,研究方向为信息检索和数据挖掘,wanchangxuan@263.net。

0 引 言

程序设计的境界有3种:器—术—道。在程序设计能力培养方面,一般由“器”入门,通过熟悉“术”,最终达到“道”的境界。在编写程序设计教材的时候,要注意这3个层次的内容安排,并注意它们之间的过渡。

1 编程中的“器术道”

1.1 编程中的“器”

《易经》曰“形而下者谓之器”,说得通俗一些,“器”就是具体工具。在编程中,“器”首先指编程语言,如Java、C/C++。“器”的另一层意思是具体特性。要学好一门语言,首先要掌握语言的基本特性,如选择、循环、函数等;其次要掌握好这门语言的独特特性,如指针操作之于C。“器”的第三层意思是具体的开发和调试工具。学任何语言的时候,初学者都要熟练掌握一种开发和调试工具,如C/C++编程,在Linux下要学会使用GDB调试,在Windows下,要会使用Visual Studio或者其他工具开发。

1.2 编程中的“术”

“术”是中国古人对技艺、技巧、技能的一个称谓,比如武术。“术”强调的是应用,是对“器”非常熟练基础上的灵活运用。

在编程中,“术”对应套路、思路和算法。比如,在C文件编程中,要把一个二进制文件中的某些记录删除,直观的做法是:逐个记录扫描,如果记录需要删除,则将后面的记录往前挪动。两种常见的套路是:①创建一个新的文件,将需要保留的数据复制到新文件中,需要删除的记录则跳过,最后将旧文件删除,将新文件重命名为旧文件,这种删除套路称为硬删除;②软删除,不真正地删除记录,而是标上记号。这两种套路各有优缺点,需要灵活选用。再比如,在一个应用中如果需要将商品按照销量排序,那么需要用到某种排序算法;如果经常需要排序的话,需要考虑用某种数据结构,如B树、堆等。

1.3 编程中的“道”

《易经》说“形而上者谓之道”,也就是说,“道”是对事物蕴含思想、哲理的反思。掌握了编程之“道”的人,看透了编程工具和语言背后的差别,不再执着于某种工具和语言,通常谈论的是架构、设计模式、框架、抽象、分解等概念。如果要用一个简单的词语概括编程中的“道”,那就是常说的“计算思维”[1]。

举两个简单的例子说明“道”和“术”在编程上的区别。对于二分查找算法,得“术”者看到的是这个算法的运用前提(数据存储在线性表中且有序)、算法的基本思路等,而得“道”者看到的是这个算法背后的分治思想;当应用某一种框架的时候,得“术”者看到的是这个框架的组成、交互方式等,得“道”者看到的是这个框架背后的思维,如模型、视图和控制相分离的原则。

2 编程中的“器术道”在程序设计教材中的体现

面向初学者的程序设计课程的目标,是让学生掌握“器”,熟悉“术”,并引导他们感悟“道”。

2.1 夯实编程之“器”

C程序设计是一门非常基础的课程,在“器”这个层面上,必须要掌握两部分:一是C语言的知识点;二是C语言的开发和调试工具。

大部分教材介绍C语言知识点的时候,把这些知识点分割成若干个条块。一种常见的知识点划分见图1,其中虚线框部分可以并列,其先后顺序比较随意。

图1 C语言知识点条块结构图

这种条块式结构的优点是:结构清晰,方便教学。学校的教学实践,初期也采取这种教学模式,但是在实践中发现,这种条块式结构存在以下不足:

(1)知识点之间的渗透不够。

(2)教学初期的例子比较简单、单调。

(3)学生的综合训练比较少。

考虑到这些问题,笔者采取一种新的层级式结构:先介绍C语言的内核,再系统地介绍C语言知识点,这个内核包含的内容如下。

· C程序的构成;

· 最常见的数据类型:int、 fl oat和 double、char 4种基本数据类型;

· 输入输出:printf和scanf函数(只介绍常用的格式控制符);

· 常量和变量的概念;

· 运算符与表达式:算术运算符、关系运算符、逻辑运算符、赋值运算符;

· 语句:简单语句、语句块、if语句、for语句、while语句;

· 函数调用。

在此基础上,系统地介绍C语言的知识点。按照顺序分别是:数据类型与输入输出、运算符与表达式、分支结构、循环结构、函数、指针与数组、C程序运行原理、结构体、文件和其他。在这些章节中,有几个部分值得特别介绍。

(1)数据类型与输入输出。这一部分与其他教材差别很大。除了基本数据类型及其输入和输出,也介绍了:

· 数组、字符串及其输入输出。这里介绍了数组是如何创建、初始化和遍历的(用for、while语句),还介绍了puts、gets等常见的字符串输入和输出函数,但没有直接引入指针的概念。

· 文本文件输入输出,包括fscanf和fprintf两个格式化输入输出函数。

(2)循环结构。在介绍循环结构的时候,引入了选择排序、冒泡排序、杨辉三角、字符串单词统计、文本文件字符统计等例子,一方面让学生更好地掌握复杂的循环结构,另一方面加强了知识点的融合,扩大了知识面。

(3)C程序运行原理。这一章包含了所有系统底层的介绍,包括计算机的存储器体系结构、程序的内存布局、变量的存储类型等。这一章的目的是更好地培养学生的系统观。

(4)文件。由于在前面章节中已经对文本文件的读写操作进行了很多演练,因此这一章主要围绕二进制文件的读写进行。特别地介绍了二进制文件记录的读、写、删、查等操作场景。通过这些例子,可以让学生更熟悉文件操作,也更侧重实际应用。

通过这样的安排,不仅加强了知识点之间的融合,而且大大提高了例题的多样性,还可以在教学过程中安排更多的综合训练,比如文本文件处理。

另一方面,“器”还强调对工具的使用,这里最主要的是调试工具。笔者在教材中安排一章介绍常见开发环境的使用(介绍了Visual Studio Community和Code::Blocks),可以帮助初学者掌握调试技巧。

2.2 提炼编程之“术”

程序设计中的“术”就是应用基本的程序设计知识点解决问题的模式[2]、套路和算法。因此,它是知识点的综合应用,是一些解决问题的有效思路。为了让学生尽快熟悉编程之术,在教材中采取了以下策略。

(1)精选例题,从例题中引申出编程之术。笔者安排了综合性、有代表性的例子,例如在循环结构这一章,介绍了选择排序和冒泡排序两种排序算法;在函数这一章,安排了输出日历以及简单四则运算的例子,通过分析这些问题,学生可以学习到程序分解的过程以及关于日期的操作;在结构体这一章,介绍了基于链表的学生学籍信息管理实例,让学生掌握与记录操作相关的套路;在文件这一章,展示了如何从二进制文件中删除满足某些条件的记录的思路。

(2)注重总结,提炼出编程之术。初学者往往不善于总结,因此教材中加入了大量的总结和提炼。首先,每一章结束后都有本章小结,对本章的知识点、常见套路和算法进行了总结。其次,在一些代表性的例题后面,对例题中的关键算法进行了总结。第三,介绍一些知识点的时候,顺便介绍该知识点相关的常见套路。例如介绍了字符之后,总结大小写字符之间的转换等;在介绍浮点数的时候,提醒浮点数比较的注意事项;在介绍循环结构的时候,提炼穷举算法的思想和注意事项;在讲解递归函数调用的时候,总结递归这一技巧应用的要点。

(3)及时训练,巩固编程之术。在习题和实验中,设计了相关题目,要求学生及时应用学到的套路和算法。

在编程实践中,还有大量与编程风格和编程效率有关的经验和技巧,这些也属于“术”的范畴。这些内容在教材中的8个“编程实践”章节中有所涉及,如代码风格、命名、程序计时、软件测试、实用字符串处理、程序设计与操作系统、中文处理等。这8个章节的内容可以扩大学生的知识面,激发学生的兴趣。在实际教学中,这8个章节不一定由教师讲授,完全可以让学生自学。

2.3 感悟编程之“道”

对初学者来说,编程之“道”,或者说计算思维,往往比较抽象,难以理解。因此,需要对学生加以引导和点化。本教材中,很多地方都点出了程序背后的“道”。

(1)专门开辟了一个章节“复杂问题的求解算法”,介绍了很多面向问题求解的思想,如分治、贪心、动态规划和回溯。对于每种思想,描述了其思维模式,指出其应用范围和优缺点,并给出多个例子演示其应用。这样,对于这些抽象思想,学生就有了比较感性的认识。

(2)在介绍知识点的时候适时点化。比如,缓存的思想在计算机硬件和软件中经常用到。教材在介绍计算机存储体系的时候,不是直接介绍这些存储器,而是把内存看作CPU和磁盘之间的缓存,L2 cache看作CPU和内存之间的缓存,L1 cache又是CPU和L2 cache之间的高速缓存。最后,指出其中存在缓存思路的反复应用:为了弥补高速处理器和低速存储器之间的速度差异,可以在它们之间插入一个更小但更快的存储器,换句话说,中间存储器是低速存储器的高速缓存。

类似这样的例子还有很多。通过这些例子,点出一些典型的计算思维,也许学生不一定马上就能够应用这些思维解决问题,但是可以引导学生从一个更高的角度看待问题,这对学生理解程序设计的本质和计算机系统无疑是有巨大帮助的。

当然,真正让学生感悟这些“道”,还需要教师在教学过程中的引导。

3 教材结构

教材《C程序设计:方法与实践》[3](以下简称本教材)的前身是2009年出版的《C语言与程序设计方法》第1版[4]和第2版[5]。在本教材正式出版之前,初稿于2015—2016年在本校试用了两年,并根据反馈意见进行了修改、定稿,最后由清华大学出版社于2017年5月出版。

3.1 教材的章节内容

本教材的章节目录和内容见表1。

与现有教材相比,本教材在结构上有所突破,在内容组织上有所创新,精选了例题,并强调工程化和规范化的开发,这些在前面都已提到,此处不再重复。

表1 教材目录和章节内容

3.2 教材的辅助资源

为了配合这本教材的使用,笔者在书中安排了9个实验,其中每个实验包含了若干个实验项目。每个实验经过精心设计,题目类型多样,可以有效地巩固所学内容。

另外,为了方便教师教学,教材编写组精心准备了前13章的教学课件,该教学课件是作者教学中使用并若干次修改和增补而来,内容非常丰富,可以直接用于教学。

4 结 语

在本教材出版之前,笔者在教学实践中一直在思考和尝试,进行了一系列的教学改革。本教材的出版是笔者的教学成果之一。跟本教材配套,笔者在教学方法上进行了一系列的调整,如实施了翻转教学、加大了实践训练的力度等。实践证明,围绕这一教材展开的教学改革有明显成效,学生的学习兴趣明显提升,实践动手能力有大的改进。

参考文献:

[1] Wing J M. Computational thinking [J]. Communications of the ACM, 2006, 49(3): 33-35.

[2] 张俊, 张彦铎. 模式在程序设计教学中的应用[J]. 计算机教育, 2010(3): 108-111.

[3] 刘喜平, 万常选, 舒蔚. C程序设计: 方法与实践[M]. 北京: 清华大学出版社, 2017.

[4] 万常选, 舒蔚, 骆斯文. C语言与程序设计方法[M]. 北京: 科学出版社, 2005.

[5] 万常选, 舒蔚, 骆斯文. C语言与程序设计方法[M]. 2版. 北京:科学出版社, 2009.

(编辑:孙怡铭)

猜你喜欢
C语言程序设计教材
教材精读
教材精读
教材精读
教材精读
基于Visual Studio Code的C语言程序设计实践教学探索
51单片机C语言入门方法
从细节入手,谈PLC程序设计技巧
基于C语言的计算机软件编程
高职高专院校C语言程序设计教学改革探索
PLC梯形图程序设计技巧及应用