欲直接下载代码文件,关注咱们的公众号哦!查看历史消息便可!python
手写笔记仍是电子笔记好呢?算法
毕业季刚结束,眼瞅着2018级小萌新立刻就要来了,老腊肉小编为了咱学弟学妹们的学习,绞尽脑汁准备编一套大学秘籍,这不刚开了个头就赶上了个难题——作笔记究竟是手写笔记好呢仍是电子笔记好呢?编程
聪明的小伙伴们或许就该怼小编了,不是有电子手写笔记吗!哼,机智如我怎么可能没想过这个呢!数组
你们用电子笔记除了省纸张外,每每还但愿有笔记整理和搜索的功能,手写电子笔记若是不能实现手写识别搜索的功能,那还真是只能省纸张了。为此小编亲自体验过GoodNotes这款手写笔记应用,虽然可以作到手写识别搜索,但须要字迹工整,不能连笔,大概能劝退一批包括小编在内的字迹感人群体了吧。网络
那么到底怎么实现手写识别呢?本期魔术师就来教会你们如何用简单的编程实现看似高深的手写识别技术。参考网上的一些教程,咱们将展现用tensorflow实现MNIST手写识别的例子。app
首先给你们学习该篇内容的思惟导图,若是有没讲到的细节,请自行参考学习:框架
MNIST 数据集来自美国国家标准与技术研究所,National Institute of Standards and Technology (NIST)。训练集 (training set) 由来自 250 个不一样人手写的数字构成,其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工做人员。测试集(test set) 也是一样比例的手写数字数据。机器学习
先给你们介绍一下tensorflow吧。编程语言
tensorflow是谷歌于2015年11月9日正式开源的计算框架。tensorflow计算框架能够很好地支持深度学习的各类算法,但它的应用也不限于深度学习,是由Jeff Dean领头的谷歌大脑团队基于谷歌内部第一代深度学习系统DistBelief改进而来的通用计算框架。函数
咱们经过基于python3的编程语言调用tensorflow这一框架。
下载方式参考以下:
咱们看一个最简单的机器学习模型,线性回归的例子。
狭义的最小二乘方法,是线性假设下的一种有闭式解的参数求解方法,最终结果为全局最优。
梯度降低法,是假设条件更为普遍(无约束)的,一种经过迭代更新来逐步进行的参数优化方法,最终结果为局部最优。
而咱们经过调用Tensorflow计算梯度降低的函数tf.train.GradientDescentOptimizer来实现优化。
咱们看下这个例子代码,只有30多行,逻辑仍是很清晰的。
最终会获得一个接近2的值,好比我此次运行的值为1.9183811
线性回归不过瘾,咱们直接一步到位,开始进行手写识别。
咱们采用深度学习三巨头之一的Yann Lecun教授的MNIST数据为例。 如上图所示,MNIST的数据是28x28的图像,而且标记了它的值应该是什么。
咱们先看看数据是怎样从图片一步步转化为咱们的预测的:
咱们能够获取到的数据在编译器里是以矩阵形式存储的,以下:
teX为10000乘784的矩阵,teY为10000乘10的矩阵,10000表示例子的数目,784就是28x28个像素点,由于有10种不一样的数字,因此teY的另外一维度为10,每一维的值用来判断是不是该维对应的数字。teX,teY构成了训练集的数据。同理,trX,trY为测试集。
接下来要介绍的部分都只是模型构建的部分不一样,你们能够参考上面数据的转化图片进行理解。
咱们首先无论三七二十一,就用线性模型来作分类。
算上注释和空行,一共加起来30行左右,咱们就能够解决手写识别这么困难的问题啦!请看代码:
通过100轮的训练,咱们的准确率是92.36%。
用了最简单的线性模型,咱们换成经典的神经网络来实现这个功能。
咱们仍是无论三七二十一,创建一个隐藏层,用最传统的sigmoid函数作激活函数。sigmoid的数学形式以下:
其核心逻辑仍是矩阵乘法,这里面没有任何技巧。
h = tf.nn.sigmoid(tf.matmul(X, w_h))
return tf.matmul(h, w_o)
完整代码以下,仍然是40多行,不长:
第一轮运行,我此次的准确率只有69.11% ,第二次就提高到了82.29%。跑100轮的最终结果是95.41%,比Logistic回归的强!
请注意咱们模型的核心那两行代码,彻底就是无脑地全链接作了一个隐藏层而己,这其中没有任何的技术。彻底是靠神经网络的模型能力。
咱们将sigmoid函数换成ReLU函数。
线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元, 是一种人工神经网络中经常使用的激活函数(activation function),一般指代以斜坡函数及其变种为表明的非线性函数。
固然,Dropout也是要作的,Dropout能够比较有效地减轻过拟合的发生,必定程度上达到了正则化的效果。因而咱们仍是一个隐藏层,写个更现代一点的模型吧:
X = tf.nn.dropout(X, p_keep_input)
h = tf.nn.relu(tf.matmul(X, w_h))
h = tf.nn.dropout(h, p_keep_hidden)
h2 = tf.nn.relu(tf.matmul(h, w_h2))
h2 = tf.nn.dropout(h2, p_keep_hidden)
return tf.matmul(h2, w_o)
除了ReLU和dropout这两个技巧,咱们仍然只有一个隐藏层,表达能力没有太大的加强。并不能算是深度学习。
从结果看到,第二次就达到了96%以上的正确率。后来就一直在98.4%左右游荡。仅仅是ReLU和Dropout,就把准确率从95%提高到了98%以上。
接下来,真正的深度学习利器CNN,卷积神经网络出场。此次的模型比起前面几个无脑型的,的确是复杂一些。涉及到卷积层和池化层。
咱们看下此次的运行数据:
0 0.95703125
1 0.9921875
2 0.9921875
3 0.98046875
4 0.97265625
5 0.98828125
6 0.99609375
在第6轮的时候,就跑出了99.6%的高分值,比ReLU和Dropout的一个隐藏层的神经网络的98.4%大大提升。由于难度是越到后面越困难。
在第16轮的时候,居然跑出了100%的正确率:
7 0.99609375
8 0.99609375
9 0.98828125
10 0.98828125
11 0.9921875
12 0.98046875
13 0.99609375
14 0.9921875
15 0.99609375
16 1.0
借助Tensorflow和机器学习工具,咱们只有几十行代码,就解决了手写识别这样级别的问题,并且准确度能够达到如此程度。
说了这么多模型,咱们来作个对比:
咱们再用手写的图片试验一下模型的效果,手写图片以下:
图片处理的方式以下:
import numpy as np
from PIL import Image
img=Image.open(r'图片文件路径').convert('L')
# resize的过程
if img.size[0] != 28 or img.size[1] != 28:
img = img.resize((28, 28))
# 暂存像素值的一维数组
arr = []
for i in range(28):
for j in range(28):
# mnist 里的颜色是0表明白色(背景),1.0表明黑色
pixel = 1.0 - float(img.getpixel((j, i)))/255.0
# pixel = 255.0 - float(img.getpixel((j, i))) # 若是是0-255的颜色值
arr.append(pixel)
arr1 = np.array(arr).reshape((1, 28, 28, 1))#arr1就是输入模型的图像数据
咱们能够看到,图片导入到编译器里后存储为了一个矩阵,矩阵里面的数字表明了每个像素点。
输出结果分别为[2]和[3],预测成功!说明训练出来的模型识别数字的能力仍是挺强的。
据说最近苹果霸霸又申请了一项新专利——实时手写识别技术。
手写电子笔记的福音啊!
连苹果都在研究的技术,我们也能小秀一把,是否是超开心!
欲直接下载代码文件,关注咱们的公众号哦!查看历史消息便可!