神经网络程序设计学习心得
简枢 SB16225001
本学期有幸再次选择了孟宁老师的2016年秋-网络程序设计课程。该课程主要聚焦于神经网络程序设计,基于深度学习神经网络等机器学习技术实现一个医学辅助诊断的专家系统原型,具体切入点为课程项目:对血常规检验报告的OCR识别、深度学习与分析。现对自己本学期的学习作个记录。
目录
学习心得
通过本课程的学习,使我对机器学习有了正确的认识,对人工神经网络有了初步的接触,并实际动手编写了一些解决实际问题的机器学习和人工神经网络程序:
人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。
在机器学习和相关领域,人工神经网络(人工神经网络)的计算模型灵感来自动物的中枢神经系统(尤其是脑),并且被用于估计或可以依赖于大量的输入和一般的未知近似函数。人工神经网络通常呈现为相互连接的“神经元”,它可以从输入的计算值,并且能够机器学习以及模式识别由于它们的自适应性质的系统。整体上看,机器学习就是模仿人识别事物的过程,即:学习、提取特征、识别、分类。
本人在工程中完成的工作
- 实现了神经网络实现手写字符识别系统,一个小巧的神经网络程序,带领我进入了机器算法学习的大门。该程序是基于BP神经网络实现一个手写字符识别系统,前端以网页形式收集用户手写数据,传至后端进行训练和预测。实验报告见此。
- 对上述程序进行了改进,将BP神经网络替换成了朴素贝叶斯算法,并成功在Spark上运行。PullRequest【第一次pull不熟悉,未更新到最新版本,被拒】
- 在利用血常规检验的各项数据进行年龄、性别预测阶段,使用基于Spark的朴素贝叶斯算法进行了训练和预测。PullRequest【再次因版本问题被拒】
- 利用Spark自带的内置函数,将线性支持向量机、逻辑回归、随机森林等多种算法实现移植到了Spark平台上,性别预测准确度最高超过了70%。PullRequest【接受】
- 附上了关于Spark单机节点安装部署的详细文档,以及MongoDB Connector for Hadoop安装部署方法,使MongoDB可作为数据源直接支持Spark计算。[PullRequest]【接受】(https://coding.net/u/mengning/p/np2016/git/pull/237)
- 向同学们汇报了关于大数据、并行计算以及基于Spark的机器学习的相关学习心得。
项目概况
项目托管地址
项目主要功能
基于神经网络、随机森林等深度机器学习技术实现一个医学辅助诊断的专家系统原型,具体切入点为对血常规检验报告的OCR识别、有监督的深度学习与分析。
血常规检测报告OCR识别
- 上传血常规检测报告图片,将图片存储到了mongodb数据库得到一个OID或到指定目录到一个path
- 自动截取目标区域,不同旋转角度的图片自动准备截取目标区域,预处理,通过增加对比度、锐化等图像处理方法对图片进行预处理
- 自动识别图片中数据并得到一个json数据,存储到mongodb数据库中
对识别结果进行医学辅助诊断
- 使用训练后的模型对识别出的血常规检测数据进行性别、年龄的预测。现使用随机树、逻辑回归等多种算法对部分数据的性别的预测准确率已超过70%。
运行环境
安装numpy,
sudo apt-get install python-numpy # http://www.numpy.org/
安装opencv
sudo apt-get install python-opencv # http://opencv.org/
安装OCR和预处理相关依赖
sudo apt-get install tesseract-ocr
sudo pip install pytesseract
sudo apt-get install python-tk
sudo pip install pillow
安装Flask框架、mongo
sudo pip install Flask
sudo apt-get install mongodb # 如果找不到可以先sudo apt-get update
sudo service mongodb started
sudo pip install pymongo
安装JDK
java -version
如果未安装,请下载最新JDK并设置相应的JAVA_HOME、JRE_HOME、CLASSPATH、PATH变量
安装Scala并添加Scala_HOME,更新PATH
sudo apt-get install scala
下载Spark并解压
官网下载地址:http://spark.apache.org/downloads.html
配置Spark环境
cp ./conf/spark-env.sh.template ./conf/spark-env.sh
设置Python依赖路径
sudo vim /etc/profile
在结尾处添加
export SPARK_HOME=/home/hadoop/spark #你的Spark解压目录
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.1-src.zip:$PYTHONPATH #py4j及pysqrk的相关依赖路径,py4j-0.10.1-src文件名可能会因Spark版本不同而不同,请设置为自己对应目录下的文件名
安装MongoDB Connector for Hadoop
MongoDB Connector for Hadoop是一个类库,他允许包括Spark、Pig、Hive、Mapreduce等在内的多种Hadoop架构中的组件使用MongoDB作为数据源。
- 第三方软件安装
使用Maven安装:
<dependency>
<groupId>org.mongodb.mongo-hadoop</groupId>
<artifactId>mongo-hadoop-core</artifactId>
<version>1.5.1</version>
</dependency>
或使用Gradle安装:
compile 'org.mongodb.mongo-hadoop:mongo-hadoop-core:1.5.1'
- 独立安装
克隆源代码:
git clone https://github.com/mongodb/mongo-hadoop.git
源代码克隆后需要编译,编译过程需连接外网进行下载,国内下载速度较慢,建议使用VPN
./gradlew jar
编译后的文件会放在core/build/libs目录下。若安装了Hadoop,则将三个文件分别拷贝至以下目录
-$HADOOP_PREFIX/lib/
-$HADOOP_PREFIX/share/hadoop/mapreduce/
-$HADOOP_PREFIX/share/hadoop/lib/
若是Spark独立部署,则将其拷贝至本机pyspark目录下即可。
$SPARK_HOME/python:$SPARK_HOME/python/lib/
项目运行
本项目由超过40名同学共同协作完成,使用多种方法结合多种平台实现;笔者在本项目中的主要方向是基于Spark平台的各项功能、算法的实现。故在此仅选取基于Spark平台实现的几个典型功能、算法进行演示,其他算法和平台的使用方法在各自文件夹下有详细介绍,请读者自行阅读。
启动SPARK
sudo ./sbin/start-all.sh
在root下输入jps应该可以看到Master和Worker两个进程
也可以登陆
http://127.0.0.1:8080/
查看Spark状态
在/Spark/DigitRecogn_Spark/目录下
基于Spark的Ocr手写字符识别系统Demo
构造训练测试数据
下载数据集
wget http://labfile.oss.aliyuncs.com/courses/593/data.csv
该数据集是https://www.shiyanlou.com/courses/593/labs/1966/document 中为反向神经网络训练用的数据集
格式化数据集
Spark深度学习常用的两种训练数据格式为Labeled point和LibSVM,在此,我们使用Labeled point作为训练数据格式。
labeled point 是一个局部向量,要么是密集型的要么是稀疏型的,用一个label/response进行关联。在Spark里,labeled points 被用来监督学习算法。我们使用一个double数来存储一个label,因此我们能够使用labeled points进行回归和分类。
在二进制分类里,一个label可以是 0(负数)或者 1(正数)。在多级分类中,labels可以是class的索引,从0开始:0,1,2,……
本Demo采用朴素贝叶斯作为训练、预测模型,特征值必须是非负数。
该Demo使用的训练、预测方法是基于Spark的朴素贝叶斯算法。
朴素贝叶斯分类器基于一个简单的假定:给定目标值时属性之间相互条件独立。
通过以上定理和“朴素”的假定,我们知道:
P( Category | Document) = P ( Document | Category ) * P( Category) / P(Document)
朴素贝叶斯分类器(Naive Bayes Classifier,或 NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。理论上,NBC模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为NBC模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,这给NBC模型的正确分类带来了一定影响。
程序在运行过程中先读取并格式化./data.csv中的数据,然后和网页前端传来的训练数据一起格式化为labeled points格式
新生成的LabeledPoints数据保存在LabeledPointsdata.txt中。
需要预测时,先将LabeledPointsdata.txt中的数据读取为Spark 专用 RDD 形式,然后训练到model中。RDD是Spark的一个重要抽象概念,笔者将在本文后面简单介绍。
运行
创建服务器
python -m SimpleHTTPServer 3000
加载服务器
python server.py
访问
localhost:3000
Demo运行结果
用户在Http页面上画出数字的图形,点击Train向服务器发送数据进行训练,或是点击Test进行预测,服务器返回预测结果,以弹出窗口的形式展示。
血常规检验报告OCRDemo
加载服务器
cd BloodTestReportOCR
python view.py
在浏览器访问http://127.0.0.1:8080即可
上传需要预测的血常规检测报告图片
OCR识别
对性别和年龄进行预测
现阶段实现了多种算法,其对性别的预测准确度基本可超过70%,但对年龄预测的准确度不佳。上述例子使用的是随机森林算法进行的预测。使用朴素贝叶斯算法对上述报告进行预测年龄为1岁,相当接近。但应该是个特例,整体上讲,朴素贝叶斯算法对性别和年龄的预测准确率要低于随机森林,不过年龄预测准确率比随机森林要稳定一些。
以下为利用Spark实现的七种机器学习算法对年龄和性别的平均预测准确率和均方差值(每种算法都使用随机分割的数据集进行了100次测试),部分算法只支持二分类,估仅对性别进行了预测(年龄预测正负5岁之类都算对)。具体预测算法可通过更改config.py中的MODEL值来选定。
朴素贝叶斯算法(支持多分类)
python ./BloodTestReportbyNB.py
结果:
Sex Prediction Accuracy AVG is:0.621970740283
Sex Prediction Accuracy MSE is:0.0339853457575
Age Prediction Accuracy AVG is:0.539635804425
Age Prediction Accuracy MSE is:0.039652048965
线性支持向量机(仅支持二分类)
python ./BloodTestReportbySVM.py
结果(迭代次数=100):
Sex Prediction Accuracy AVG is:0.528946440893
Sex Prediction Accuracy MSE is:0.0499342692342
逻辑回归(仅支持二分类)
python ./BloodTestReportbyLR.py
结果(迭代次数=100):
Sex Prediction Accuracy AVG is:0.717975697167
Sex Prediction Accuracy MSE is:0.0303414723843
随机树(支持多分类)
python ./BloodTestReportbyRF.py
结果(树=3,最大深度=4,最大叶子数=128,纯度计算方式:基尼系数,性别分类=2,年龄分类=1000):
Sex Prediction Accuracy AVG is:0.71622711581
Sex Prediction Accuracy MSE is:0.0255871783772
Age Prediction Accuracy AVG is:0.561977173151
Age Prediction Accuracy MSE is:0.0622593472121
梯度提升树(仅支持二分类)
python ./BTR_gradient_boosting.py
结果(迭代次数=100):
Sex Prediction Accuracy AVG is:0.728212518228
Sex Prediction Accuracy MSE is:0.0305777571064
二分类(仅支持二分类)
python ./BTR_binary_classification.py
结果(迭代次数=100):
Sex Prediction Accuracy AVG is:0.718756411999
Sex Prediction Accuracy MSE is:0.0311279215968
决策树(支持多分类)
python ./BTR_decision_tree.py
结果:
Sex Prediction Accuracy AVG is:0.707608775434
Sex Prediction Accuracy MSE is:0.0292234440441
Age Prediction Accuracy AVG is:0.552560046229
Age Prediction Accuracy MSE is:0.05098502703
大数据与云计算
学习过程中老师能充分调动大家的积极性,鼓励大家在实际工程的基础之上学习新的技术。于是乎,在浏览了老师的微博之后,本人决定再在原有工程的基础上加入了大数据(Hadoop+Spark)的切入点,使得该工程能应对大数据、并行计算模式下的运行环境。
大多数机器学习都是基于海量训练数据的深度学习,要处理这种大规模的数据,传统的单节点服务器很难驾驭。利用现有的成熟云计算+大数据技术,可较好处理这个问题。
云计算
云计算(Cloud Computing)是分布式处理(Distributed Computing)、并行处理(Parallel Computing)和网格计算(Grid Computing)的发展,或者说是这些计算机科学概念的商业实现。
云计算的基本原理是,通过使计算分布在大量的分布式计算机上,而非本地计算机或远程服务器中,企业数据中心的运行将更与互联网相似。这使得企业能够将资源切换到需要的应用上,根据需求访问计算机和存储系统。下图形象的表现了分布式云计算与传统大规模集群的不同。
大数据
在2003-2006年之间,Google在云计算的基础上发表了三篇论文,为现有大数据概念定义了一个出发点:
GFS:一个面向大规模数据密集型应用的、可伸缩的分布式文件系统。
BigTable:一个分布式的非关系型数据库(NoSQL)。
MapReduce:一个分布式的大规模并行计算模型。
2010年2月,肯尼斯ž库克尔在《经济学人》上发表了长达14页的大数据专题报告《数据,无所不在的数据》。
2011年5月,全球知名咨询公司麦肯锡(McKinsey&Company)肯锡全球研究院(MGI)发布了一份报告——《大数据:创新、竞争和生产力的下一个新领域》,大数据开始备受关注,这也是专业机构第一次全方面的介绍和展望大数据。
而2005年,Apache发布开源项目Hadoop。Hadoop发布初期由三个部分组成:HDFS、HBase、MapReduce分别对应了Google三篇论文中的GFS、BigTable以及MapReduce。此外还开发了Mahout、Hive等模块,支持一些其他应用
云计算、大数据、Hadoop三者之间的关系是:
云计算是一种商业概念,它提出的是一种新的商业模式,是分布式计算的进化版。
从技术上看,大数据与云计算的关系就像一枚硬币的正反面一样密不可分。大数据难以用单台的计算机进行处理,必须采用分布式计算架构。它的特色在于对海量数据的挖掘,但它必须依托云计算的分布式处理、分布式数据库、云存储和虚拟化技术。
Hadoop是云计算的产品,他是云计算在发展过程中应运而生的一个框架。
Spark
Hadoop 的MRv1存在以下不足:
可扩展性差:JobTracker既负责资源管理又负责任务调度,当集群繁忙时,JobTracker很容易成为瓶颈。
可用性差:采用了单节点的Master,没有备用Master。
资源利用率低:TaskTracker使用“slot”等量划分本节点上的资源量。“slot”代表计算资源(CPU、内存等)。slot 分为Map slot 和Reduce slot 两种,分别供MapTask 和Reduce Task 使用。有时会因为作业刚刚启动等原因导致MapTask很多,而Reduce Task任务还没有调度的情况,这时Reduce slot也会被闲置。
不能支持多种MapReduce框架:无法通过可插拔方式将自身的MapReduce框架替换为其他实现。
Apache为了解决以上问题,对Hadoop升级改造,MRv2最终诞生了。MRv2中,重用了MRv1中的编程模型和数据处理引擎。但是运行时环境被重构了。MRv2中MapReduce的核心不再是MapReduce框架,而是YARN。在以YARN为核心 的MRv2中,MapReduce框架是可插拔的,完全可以替换为其他MapReduce实现。而Spark就是其中一种较为经典的MapReduce的替代。
Hadoop MapReduce的 Job将中间输出和结果存储在HDFS中,读写HDFS造成磁盘IO成为瓶颈。Spark允许将中间输出和结果存储在内存中,节省了大量的磁盘IO。同时 Spark自身的DAG执行引擎也支持数据在内存中的计算。Spark官网声称性能比Hadoop快100倍。即便是内存不足需要磁盘IO,其速度也是Hadoop的10倍以上。
课程感悟
课程授课模式非常开放,完全没有阅读PPT的传统教学的枯燥。老师带领大家一起,结合实际工程学习神经网络算法。以前的认识中,神经网络算法对博士生来讲都是极其难以驾驭的,而本课程课时虽然不多,但内容极其丰富,每个切入点都是当前最前沿最尖端的技术。在短短不到两个月的时间里,老师不光带领我们认识了机器学习和神经网络元的基本算法,还完成了一个实际的Demo项目。这在一个有一定经验的开发团队里都算非常高效的,何况老师是带领了一群本科专业各异,几乎完全没有项目经验的学生完成的。老师带着大家从Git的团队协作学起,大家从对Git的盲目到积极的pull request,并认真撰写每个模块的Readme文档,学会了很多团队开发的经验。孟老师不光是一个善于教学的好老师,更是一个非常优秀的产品经理。
通过课程我发现,机器学习已经有非常多的成熟工具、类库,在这些工具和类库的基础之上进行机器学习的开发成本已大幅降低。同时,随着大数据概念的不断发展,供机器学习的训练集也越来越丰富。但较为成熟的应用却多集中在很多大型互联网公司之中。其实以现有条件,很多规模以下的互联网公司甚至个人都可以开发出一款基于机器学习的应用。随着人们观念的改变,机器学习很有可能成为互联网增长中的下一个增长点。