java 手写数字识别_10 行代码,实现手写数字识别
识别手写的阿拉伯数字,对于人类来说十分简单,但是对于程序来说还是有些复杂的。
不过随着机器学习技术的普及,使用10几行代码,实现一个能够识别手写数字的程序,并不是一件难事。这是因为有太多的机器学习模型可以拿来直接用,比如tensorflow、caffe,在python下都有现成的安装包,写一个识别数字的程序,10几行代码足够了。
然而我想做的,是不借助任何第三方的库,从零开始,完全自己实现一个这样的程序。之所以这么做,是因为自己动手实现,才能深入了解机器学习的原理。
1 模型实现
1.1 原理
熟悉神经网络回归算法的,可以略过这一节了。
学习了一些基本概念,决定使用回归算法。首先下载了著名的MNIST数据集,这个数据集有60000个训练样本,和10000个测试样本。每个数字图片都是2828的灰度图片,所以输入可以认为是一个2828的矩阵,也可以认为是一个28*28=784个像素值。
这里定义一个模型用于判断一个图片数字,每个模型包括每个输入的权重,加一个截距,最后再做个归一。模型的表达式:
Out5= sigmoid(X0W0+ X1W1+……X783*W783+bias)
X0到X783是784个输入,W0到W783是784个权重,bias是一个常量。sigmoid函数可以将较大范围的数挤压到(0,1)区间内,也就是归一。
例如我们用这一组权重和bias来判断数字5,期望当图片是5时输出是1,当不是5时输出是0。然后训练的过程就是根据每个样本的输入,计算Out5的值和正确值(0或1)的差距,然后根据这个差距,调整权重和bias。转换一下公式,就是在努力使得(Out5-正确值)接近于0,即所谓损失最小。
同理,10个数字就要有10套模型,每个判断不同的数字。训练好以后,一个图片来了,用这10套模型进行计算,哪个模型计算的结果更接近于1,就认为这个图片是哪个数字。
1.2 训练
按照上面的思路,使用集算器的SPL(结构化处理语言)来编码实现:
不用再找了,训练模型的所有代码都在这里了,没有用到任何第三方库,下面解析一下:
A1,用游标导入MNIST训练样本,这个是我转换过的格式,可以被集算器直接访问;
A2,定义变量:输入x,权重wei,训练速度v,等;
A3,B3,初始化10组模型(每组是784个权重+1个bias);
A4,循环取5万个样本进行训练,10模型同时训练;
B4,取出来label,即这个图片是几;
B5,计算正确的10个输出,保存到变量y;
B6,取出来这个图片的28*28个像素点作为输入,C6把每个输入除以255,这是为了归一化;
B7,计算X0W0+ X1W1+……X783*W783+bias
B8,计算sigmoid(B7)
B9,计算B8的偏导,或者叫梯度;
B10,C10,根据B9的值,循环调整10个模型的参数;
A11,训练完毕,把模型保存到文件。
1.3 测试
测试一下这个模型的成功率吧,用 SPL 写了一个测试程序:
运行测试,正确率达到了91.1%,我对这个结果是很满意的,毕竟这只是一个单层模型,我用TensorFlow的单层模型得到的正确率也是91%多一点。下面解析一下代码:
A1,导入模型文件;
A2,把模型提取到变量里;
A3,计数器初始化(用于计算成功率);
A4,导入MNIST测试样本,这个文件格式是我转换过的;
A5,循环取1万个样本进行测试;
B5,取出来label;
B6,清空输入;
B7,取出来这个图片的28*28个像素点作为输入,每个输入除以255,这是为了归一化;
B8,计算X0W0+ X1W1+……X783*W783+bias
B9,计算sigmoid(B7)
B10,得到最大值,即最可能的那个数字;
B11,判断正确测计数器加一;
A12,A13,测试结束,关闭文件,输出正确率。
1.4 优化
这里要说的优化并不是继续提高正确率,而是提升训练的速度。想提高正确率的同学可以尝试一下这几个手段:
1. 加一个卷积层;
2. 学习速度不要用固定值,而是随着训练次数递减;
3. 权重的初始值不要使用全零,使用正态分布;
我认为单纯追求正确率的意义不大,因为MNIST数据集有些图片本身就有问题,即使人工也不一定能知道写的是数字几。我用集算器显示了几张出错的图片,都是书写十分不规范的,下面这个图片很难看出来是2。
下面说重点,要提高训练速度,可以使用并行或集群。使用SPL语言实现并行很简单,只要使用fork关键字,把上面的代码稍加处理就可以了。
使用了并行之后,训练的时间减少差不多一半,而代码并没有做太多修改。
2 为什么是 SPL 语言?
使用SPL语言在初期可能会有点不适应,用得多了会觉得越来越方便:
1. 支持集合运算,比如例子里用到的784个输入和784个权重的乘法,直接写一个**就可以了,如果使用Java或者C,还要自己实现。
2. 数据的输入输出很方便,可以方便地对文件读写。
3. 调试太方便了,所有变量都直观可见,这一点比python要好用。
4. 可以单步计算,有了改动不用从头重来,Java和C做不到这一点,python虽然可以但也不方便,集算器只要点中相应格执行就可以了。
5. 实现并行和集群很方便,不需要太多的开发工作量。
6. 支持调用和被调用。集算器可以调用第三方java库,Java也可以调用集算器的代码,例如上面的代码就可以被Java调用,实现一个自动填验证码的功能。
这样的编程语言,用在数学计算上,实在是最合适不过了。
java 手写数字识别_10 行代码,实现手写数字识别相关推荐
- 手把手,74行代码实现手写数字识别
手把手,74行代码实现手写数字识别 689 次阅读 - 2015.12.29 - 人工智能 - 龙猫 http://dataunion.org/20992.html 1. 引言:不要站在岸上学游泳 & ...
- C++ 中的多线程的使用和线程池建设。150行代码,手写线程池
C++ 11 引入了 std::thread 标准库,方便了多线程相关的开发工作. 说到多线程开发,可不仅仅是创建一个新线程就好了,不可避免的要涉及到线程同步的问题. 而保证线程同步,实现线程安全,就 ...
- 人脸检测算法代码python_Python有多强大!20行代码实现人脸检测与识别
题记:大二的时候发现人生苦短,所以信了拍神,开始学Python.学了大半年之后成功转行做前端了.来写个教程帮助大家入门Python. Python优点 Python是一种简单易学.功能强大的编程语言, ...
- 从大专生到蚂蚁金服CTO,他写下“支付宝”第一行代码:逆风的方向,更适合飞翔!...
Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨Mr.K 整理丨Emma 来源丨技术领导力 ...
- 突发!倪行军出任支付宝中国董事长,技术出身的他,曾写下“支付宝”第一行代码.........
作者| Mr.K 整理| Emma 来源| 技术领导力(ID:jishulingdaoli) 昨天(8月1日),支付宝(中国)网络技术有限公司法定代表人.董事长由井贤栋变更为倪行军.阿里巴巴这次高 ...
- python代码示例500行源代码-500行代码使用python写个微信小游戏飞机大战游戏
这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手. 帮助蹲厕族.YP族.饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右 ...
- python爬虫都能干什么用_5 行代码就能写一个 Python 爬虫
欢迎关注我的公众号:第2大脑,或者博客:高级农民工,阅读体验更好. 摘要:5 行代码就能写一个 Python 爬虫. 如果你是比较早关注我的话,会发现我此前的大部分文章都是在写 Python 爬虫,前 ...
- python怎么判断真假_Python不超过10行代码就可实现人脸识别,教你辨别真假
[[爱编程的南风]Python不超过10行代码就可实现人脸识别,教你辨别真假]http://toutiao.com/group/6518157903055045127/?iid=15906422033 ...
- c 语言500行小游戏代码,500行代码使用python写个微信小游戏飞机大战游戏.pdf
500行行代代码码使使用用python写写个个微微信信小小游游戏戏飞飞机机大大战战游游戏戏 这篇文章主要介绍了500行代码使用python写个微信小游戏飞机大战游戏,本文通过实例代码给大家介绍的非常详 ...
- 手把手入门神经网络系列(2)_74行代码实现手写数字识别
作者: 龙心尘&&寒小阳 时间:2015年12月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/5028124 ...
最新文章
- mvc ajax提交html标签,asp.net-mvc – 如何使用ajax get或post在带有参数的mvc中将数据从View传递到Controller...
- 【PAT (Advanced Level) Practice】PAT (Advanced Level) Practice
- [剑指offer]面试题第[61]题[JAVA][扑克牌中的点数][HashSet][数组]
- php 数组设置为空,PHP数组设置空值
- (OS 64)指定的网络名不再可用,winnt_accept: Asynchronous AcceptEx failed.
- 上传文件到阿里云OSS对象存储,查询访问地址,删除文件
- 调用Kubernetes SDK实现二次开发
- iOS 动态隐藏状态栏
- python字符串输入小圆点_第6章 多序列比对
- rman异机恢复 Linux _RAC至Win_Single Instance note
- Python中的numpy库介绍!
- AutomateTheBoringStuffWithPython
- js打印去掉页眉页脚
- 类、面向对象(封装、继承、多态),面向过程
- Mysql5.7在上亿级别的存储性能测试报告 Mysql到底可不可以支持单表过亿?要分区么?分表?...
- pubg:您的客户端将在10秒内关闭,因为一个关键的防作弊进程没有正确运行。通过验证您的游戏文件的完整性来解决此问题....
- 错误连接数据库 [xxx] : org.pentaho.di.core.exception.KettleDatabaseException: Error occurred while try
- csdn--接口自动化测试之postman如何设置断言
- 关于微信小程序A 与 微信小程序B 之间的跳转问题
- php post翻页,php的POST值 如何连续跨页传递(不用表单)?
热门文章
- 彩灯控制器课程设计vhdl_基于VHDL的彩灯控制器的设计
- CAN波特率计算公式
- FFT蝶形算法的verilog实现专题——从FFT算法的定义开始入手
- 半导体器件(一) 学习笔记
- 设计心理学读书笔记 之一 记忆的结构
- MRP里如何预测lead time :Approaches for the Prediction of Lead Times in an Engineer to Order Environment
- 创业与投资 - 谈谈融资这个事儿(上)
- 网易视频大神:七个问题告诉你做游戏CG还是做影视?
- 江西银行服务器怎么选择硬件配置
- 义齿计算机辅助制作技术包括,可摘局部义齿CAD/CAM/SLM金属3D打印制作新方法