文档章节

网络程序设计课程项目总结

成运畅
 成运畅
发布于 2016/12/28 21:36
字数 3844
阅读 299
收藏 1

SA16225036+成运畅+网络程序设计课程(孟宁老师)

学习体会

    这门课程于我而言的意义,是我在开课之初完全未意识到的。尽管选课之前对孟宁老师的授课风格早有耳闻,但是到自己真正体验的时候,还是着实一惊。我之前一直以为对学生主观能动性的培养只是做实验之流,殊不知这种亲身参与,学生老师共同学习,合作开发,自主掌握课程节奏的风格才是当之无愧的自主。整个课程期间,老师以一个统筹者和参与者的身份与全班学生一起在coding.net上有节奏和有方向的合作开发,让我们平稳自然的进入到将要面临的工作节奏当中,整个班级作为一个团队,稳步向前推进,也激励了如我一般相对弱势一点的同学短期内的快速进步。

    整个项目开发期间,有几个关键点需要着重强调:

    1.文档的编写在软件开发过程中真的是极其重要。本次的课程项目由于是在codin.net上的多热合作开发,由于时间和空间的限制,大家不能时时刻刻进行良好的面对面交流,以至于在对项目的理解和擅长区域有偏差的情况下,很有可能会导致一些错误的产生。这时候,一份清晰明了的文档就显得尤为重要了。好在老师在我们整个项目的开发过程中对文档要求极高,不仅要求代码的合理和正确,也要求每个功能性文件的产生和改动都有相关的清晰准确的说明文档,大大方便了之后的同学对其进行理解和改进,使整个项目更加的具有包容性,也更有生命力。

    2.良好的代码风格也是保证项目可扩展的重要条件。项目开发过程中孟老师对代码集成,封装,注释和规范上的要求让我明白了好的代码风格在项目开发过程中的重要性。我们整个项目的开发过程算得上是极其顺利的,我想这很大一部分原因要归功于此。良好的代码风格,能够让同学们更好的理解代码结构,掌握算法内容,减轻了对其进行修改的负担。同时在项目后期我们对之前的算法进行整合和维护的工作也变得更加轻松写意。课程结束之后项目的扩展(我认为肯定是有的)也有很大好处。

    3.开放互助的精神是团队合作的核心精神。作为一个由整个班六十人组合而成的团队,水平存在差异是在所难免的,这时候要想完完全全切实的参与到这个项目当中来,一些基础差的同学就需要有基础的同学稍微帮助一下。就我的感受而言,我们整个团队就是这么做的,我之前是安全没有接触过Python和机器学习的,之所以能比较快的跟上整个项目当进度,跟很多同学的帮助是分不开的。也正是这种开放互助,大家资源共享,互相帮助的团队精神,也在一定程度上减轻了之前有过基础的同学的工作量,使大家都能做一些力所能及的工作。

    再谈到我对项目的贡献,说起来真的有点惭愧。我真的就属于那种只改过几行代码的人。唯一pr被接受的就是修改了网页端的一个表单不能清空的bug,因为之前毫无接触,所以更多的时间都是用在学习和理解其他同学的代码,这个过程一开始确实是不好受的,因为跟别人的差距会给你造成很大的压力,这门课最大的难点亦在于此。当我慢慢渡过初级阶段,在一些同学的帮助下能够比较完整和清楚的理解整个项目的结构和代码的意义,了解项目开发的进程和目标后,整个人就豁然开朗。之后的过程反而没有那么压抑,更多的是学习的动力和探索的欲望。这与我而言真的是非常难能可贵的一次经历,不仅见证了一个完整项目的从无到有的过程,也体验了对一门新技术从零开始的学习过程。整个过程中对心态的调整,进度的把握都有了一定的经验。

项目介绍

项目功能

    该项目是基于机器学习神经网络的一个医学辅助诊断系统。通过对病人血常规化验单的图片的识别采集数据进行分析。利用通过大量真实数据训练出来的有一定可接受的准确率的模型对病人所提供的数据进行判断,通过对各项血常规数据的分析来实现对病人性别和年龄的预测。

项目地址

项目托管地址>

coding.net:https://git.coding.net/doublehearts/np2016.git

运行环境

安装前置依赖包

此处提供的包是安装Python模块的前置依赖包文件

# 安装 Python 发布版本,dev包必须安装,很多用pip安装包都需要编译

sudo apt-get install python2.7 python2.7-dev python3.2 python3.2-dev

# 很多pip安装的包都需要libssl和libevent编译环境

sudo apt-get install build-essential libssl-dev libevent-dev libjpeg-dev libxml2-dev libxslt-dev

安装python模块

PS: 装python模块时最好每一步进入python命令行尝试import是否成功

此处提供的是进行神经网络机器学习该项目所需要的一些包文件以及和识别有关的包文件

# 安装pip

sudo apt-get install python-pip

# 安装numpy,

sudo apt-get install python-numpy # http://www.numpy.org/

# 安装opencv

sudo apt-get install python-opencv # http://opencv.org/

#装完后需要更新环境变量

vim /etc/bash.bashrc

#在文件末尾添加两行代码

export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/dist-packages

export PYTHONPATH="${PYTHONPATH+${PYTHONPATH}:}/usr/local/lib/python2.7/site-packages"

##安装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

 

    博主是采用的是在Spark平台利用准确率相对最高的朴素贝叶斯算法对模型进行训练和预测

Spark平台的大只安装过如下:

安装JDK

下载jdk-8u45-linux-x64.tar.gz,解压到/opt/jdk1.8.0_45

安装Scala

安装scala,下载scala-2.11.6.tgz,解压到/opt/scala-2.11.6

安装Spark

下载spark-1.3.1-bin-hadoop2.6.tgz,解压到/opt/spark-hadoop

配置JDK和Spark相关的环境变量

  • sudo gedit /etc/profile
  • 在文件最后增加:
    #Setting JDK JDK环境变量
    export JAVA_HOME=/opt/jdk1.8.0_45
    export JRE_HOME=${JAVA_HOME}/jre
    export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
    export PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH
    #Setting Scala Scala环境变量
    export SCALA_HOME=/opt/scala-2.11.6
    export PATH=${SCALA_HOME}/bin:$PATH
    # Setting Spark Spark环境变量
    export SPARK_HOME=/opt/spark-hadoop/
    #PythonPath 将Spark中的pySpark模块增加的Python环境中
    export PYTHONPATH=/opt/spark-hadoop/python
  • 重启电脑,使/etc/profile永久生效,临时生效,打开命令窗口,执行 source /etc/profile 在当前窗口生效

    使用虚拟机开发的同学,有些包文件系统内部安装可能会存在问题,此处给了一一些外部下载的链接以及安装教程:

Python发布版本的安装:http://www.cnblogs.com/ningvsban/p/4384995.html

Spark的安装:http://blog.csdn.net/dst1213/article/details/51626789

Spark下载地址:http://spark.apache.org/downloads.html

jdk下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

scala下地地址: http://www.scala-lang.org/

文件介绍

view.py

Web 端上传图片到服务器,存入mongodb并获取oid,稍作修整,希望能往REST架构设计,目前还不完善

imageFilter.py

对图像透视裁剪和OCR进行了简单的封装,以便于模块间的交互,规定适当的接口

对图像的处理工作是识别过程的第一步

imageFilter = ImageFilter() # 可以传入一个opencv格式打开的图片

num = 22

print imageFilter.ocr(num)

ocr函数 - 模块主函数返回识别数据

用于对img进行ocr识别,他会先进行剪切,之后进一步做ocr识别,返回一个json对象 如果剪切失败,则返回None规定剪切项目数

perspect函数做 - 初步的矫正图片

用于透视image,他会缓存一个透视后的opencv numpy矩阵,并返回该矩阵 透视失败,则会返回None,并打印不是报告透视参数

关于param

参数的形式为[p1, p2, p3 ,p4 ,p5]。 p1,p2,p3,p4,p5都是整型,其中p1必须是奇数。

p1是高斯模糊的参数,p2和p3是canny边缘检测的高低阈值,p4和p5是和筛选有关的乘数。

如果化验报告单放在桌子上时,有的边缘会稍微翘起,产生比较明显的阴影,这种阴影有可能被识别出来,导致定位失败。 解决的方法是调整p2和p3,来将阴影线筛选掉。但是如果将p2和p3调的比较高,就会导致其他图里的黑线也被筛选掉了。 参数的选择是一个问题。 我在getinfo.default中设置的是一个较低的阈值,p2=70,p3=30,这个阈值不会屏蔽阴影线。 如果改为p2=70,p3=50则可以屏蔽,但是会导致其他图片识别困难。

就现在来看,得到较好结果的前提主要有三个

  • 化验单尽量平整
  • 图片中应该包含全部的三条黑线
  • 图片尽量不要包含化验单的边缘,如果有的话,请尽量避开有阴影的边缘。

filter函数 - 过滤掉不合格的或非报告图片

返回img经过透视过后的PIL格式的Image对象,如果缓存中有PerspectivImg则直接使用,没有先进行透视 过滤失败则返回Nonefilter参数

autocut函数 - 将图片中性别、年龄、日期和各项目名称数据分别剪切出来

用于剪切ImageFilter中的img成员,剪切之后临时图片保存在out_path, 如果剪切失败,返回-1,成功返回0剪切项目数剪切参数

剪切出来的图片在BloodTestReportOCR/temp_pics/ 文件夹下

函数输出为data0.jpg,data1.jpg……等一系列图片,分别是白细胞计数,中性粒细胞记数等的数值的图片。

classifier.py

用于判定裁剪矫正后的报告和裁剪出检测项目的编号

imgproc.py

将识别的图像进行处理二值化等操作,提高识别率 包括对中文和数字的处理

对朴素贝叶斯算法的分析:

    该算法所在的文件是BloodTestReportbyNB.py,由于它使我们所训练过的四种算法中准确率最高的,所以博主用它进行性别和年龄的预测。首先会读取Spark能够识别的labeled point类型的数据,有csv数据及转化而来,利用Spark平台所提供的特有的应用接口对数据进行训练,然后进行预测,并返回一个RDD数据类型的数据,在经过处理最后转化为json结构的训练结果并返回。这段代码如下所示:

# -*- coding: UTF-8 -*-
#基于Spark的朴素贝叶斯血常规检验报告深度学习系统
#2016.12.14
from __future__ import print_function
import json
import sys
import math
from pyspark import SparkContext
from pyspark.mllib.classification import NaiveBayes, NaiveBayesModel
from pyspark.mllib.util import MLUtils
class BloodTestReportbyNB:
    
    def __init__(self, sc):	
        self.sc = sc 
    		# 读取数据.
    		print('Begin Load Data File!')
    		self.sexData = MLUtils.loadLabeledPoints(self.sc, "LabeledPointsdata_sex.txt")
    		self.ageData = MLUtils.loadLabeledPoints(self.sc, "LabeledPointsdata_age.txt")
    		print('Data File has been Loaded!')
        self.predict_gender = ""
        self.predict_age = ""
    def predict(self):
        	sexTraining = self.sexData
        	ageTraining = self.ageData
        	# 训练朴素贝叶斯模型.
        	sexModel = NaiveBayes.train(sexTraining, 1.0)
        	ageModel = NaiveBayes.train(ageTraining, 1.0)
        #读取预测数据
        sexPredict = MLUtils.loadLabeledPoints(self.sc, "LabeledPointsdata_predict_gender.txt")
        agePredict = MLUtils.loadLabeledPoints(self.sc, "LabeledPointsdata_predict_age.txt")
        	# 对数据进行预测
        predict_genderCollect = sexPredict.map(lambda p: sexModel.predict(p.features)).collect()
        self.predict_gender = predict_genderCollect[0]
        predict_ageCollect = agePredict.map(lambda p: ageModel.predict(p.features)).collect()
        self.predict_age = predict_ageCollect[0]
        	#self.predict_gender = sexModel.predict(sexPredict).collect()
        	#self.predict_age = ageModel.predict(agePredict).collect()
        if 0 == self.predict_gender:
            self.predict_gender = "男"
        if 1 == self.predict_gender:
            self.predict_gender = "女"
        
        print ('Predict Gender:', self.predict_gender)
        print ('Predict Age:', self.predict_age)
        predict_data = {
            "age": self.predict_age,
            "gender": self.predict_gender
        }
        json_data = json.dumps(predict_data, ensure_ascii=False)
        print ('JSON data of predict_data:', json_data)
        return json_data
        
        		
#unit test
if __name__ == "__main__":
    sc = SparkContext(appName="BloodTestReportPythonNaiveBayesExample")
    BloodTestReportbyNB = BloodTestReportbyNB(sc)
    BloodTestReportbyNB.predict()

   朴素贝叶斯分类是一种十分简单的分类算法,叫它朴素贝叶斯分类是因为这种方法的思想真的很朴素,朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。通俗来说,就好比这么个道理,你在街上看到一个黑人,我问你你猜这哥们哪里来的,你十有八九猜非洲。为什么呢?因为黑人中非洲人的比率最高,当然人家也可能是美洲人或亚洲人,但在没有其它可用信息下,我们会选择条件概率最大的类别,这就是朴素贝叶斯的思想基础。

朴素贝叶斯分类的正式定义如下:

      1、设为一个待分类项,而每个a为x的一个特征属性。

      2、有类别集合。

      3、计算

      4、如果,则

      那么现在的关键就是如何计算第3步中的各个条件概率。我们可以这么做:

      1、找到一个已知分类的待分类项集合,这个集合叫做训练样本集。

  2、统计得到在各类别下各个特征属性的条件概率估计。即

      3、如果各个特征属性是条件独立的,则根据贝叶斯定理有如下推导:

      

      因为分母对于所有类别为常数,因为我们只要将分子最大化皆可。又因为各特征属性是条件独立的,所以有:

      

所以它的整个流程如下:

项目演示

项目启动

*

1

2

3

进入你所克隆的本地项目文件夹下面,并在terminal下运行下列文件

$ python dataformat.py(将csv格式的训练数据转化为可用的label point数据)

$ python view.py(启动Spark和Web服务器)

访问 http://0.0.0.0:8080/(不同的本地目录可能存在微小的后续路径差别)

选择图片上传

    选择图片进行上传并提交,提交之后网页上会显示所选择的照片,用户可据此判断所提交的图片的准确性。

生成血常规检验报告

    此处所生成的血常规检验报告是可以对其中的项目数据进行修改的,防止因为识别不准确造成的一些数据出错对后续的预测活动造成影响。

对年龄和性别进行预测

 

 

© 著作权归作者所有

成运畅
粉丝 0
博文 1
码字总数 3844
作品 0
安康
程序员
私信 提问
清华大学视频课件:面向对象程序设计(C++)(自主模式)

清华大学视频课件:面向对象程序设计(C++)(自主模式) 课程简介 C++是从C语言发展演变而来的一种面向对象的程序设计语言。面向对象的程序设计方法将数据及对数据的操作方法封装在一起,作...

dragonscroll
2017/11/16
0
0
上不了名校?可以在 GitHub 上读他们的课程

今天开始,全国各大区域的高考成绩陆续公布,又到了几家欢喜几家愁的时刻,如果你准备报考计算机相关专业,但是又由于分数不高而苦恼。别担心,在GitHub上有着大量的名校教学资源,即使上不了...

HelloGitHub
06/24
0
0
人脸识别完整项目实战(1):目录大纲篇

一、前言 本文是《人脸识别完整项目实战》系列博文第1章《目录大纲篇》,本章内容系统介绍,《人脸识别项目完整实战》系列博文的目录结构,共8大部分53个章节。 项目概述篇:系统介绍人脸识别...

Hadoop develop
02/28
0
0
绩点

课程名称 绩点 成绩 计算机应用基础与程序设计1 3.5 85 电路分析 3.5 85 计算机应用基础与程序设计2 4.0 优秀 概率论与数理统计A 3.5 87 数据结构 2.5 78 数据库系统原理 3.5 89 线性代数 4....

仇诺伊
2017/11/20
0
0
如何学编程

一般理工科学生上大学都会学习一门程序设计语言C/C++语言。我曾经无数次的给学生说过,大学里每个学期按5门课算,8个学期下来40门课,其实只要学会一门C语言,找工作不成问题,甚至找个高薪工...

王顶老师
2014/06/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
10
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0
PHP+Ajax微信手机端九宫格抽奖实例

PHP+Ajax结合lottery.js制作的一款微信手机端九宫格抽奖实例,抽奖完成后有收货地址添加表单出现。支持可以设置中奖概率等。 奖品列表 <div class="lottery_list clearfix" id="lottery"> ......

ymkjs1990
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部