10分钟教你用python 30行代码搞定简单手写识别!

时间:2022-01-16 05:19:24

欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可!

10分钟教你用python 30行代码搞定简单手写识别!

手写笔记还是电子笔记好呢?

毕业季刚结束,眼瞅着2018级小萌新马上就要来了,老腊肉小编为了咱学弟学妹们的学习,绞尽脑汁准备编一套大学秘籍,这不刚开了个头就遇上了个难题——做笔记到底是手写笔记好呢还是电子笔记好呢?

聪明的小伙伴们或许就该怼小编了,不是有电子手写笔记吗!哼,机智如我怎么可能没想过这个呢!

大家用电子笔记除了省纸张外,往往还希望有笔记整理和搜索的功能,手写电子笔记如果不能实现手写识别搜索的功能,那还真是只能省纸张了。为此小编亲自体验过GoodNotes这款手写笔记应用,虽然能够做到手写识别搜索,但需要字迹工整,不能连笔,大概能劝退一批包括小编在内的字迹感人群体了吧。

10分钟教你用python 30行代码搞定简单手写识别!

那么到底怎么实现手写识别呢?本期魔术师就来教会大家如何用简单的编程实现看似高深的手写识别技术。参考网上的一些教程,我们将展示用tensorflow实现MNIST手写识别的例子。

首先给大家学习该篇内容的思维导图,如果有没讲到的细节,请自行参考学习:

10分钟教你用python 30行代码搞定简单手写识别!

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这一框架。

下载方式参考如下:

10分钟教你用python 30行代码搞定简单手写识别!

入门捷径:线性回归

我们看一个最简单的机器学习模型,线性回归的例子。

狭义的最小二乘方法,是线性假设下的一种有闭式解的参数求解方法,最终结果为全局最优。

梯度下降法,是假设条件更为广泛(无约束)的,一种通过迭代更新来逐步进行的参数优化方法,最终结果为局部最优。

而我们通过调用Tensorflow计算梯度下降的函数tf.train.GradientDescentOptimizer来实现优化。

我们看下这个例子代码,只有30多行,逻辑还是很清晰的。

10分钟教你用python 30行代码搞定简单手写识别!

最终会得到一个接近2的值,比如我这次运行的值为1.9183811

线性模型:logistic回归

线性回归不过瘾,我们直接一步到位,开始进行手写识别。

10分钟教你用python 30行代码搞定简单手写识别!

我们采用深度学习三巨头之一的Yann Lecun教授的MNIST数据为例。 如上图所示,MNIST的数据是28x28的图像,并且标记了它的值应该是什么。

我们先看看数据是怎样从图片一步步转化为我们的预测的:

10分钟教你用python 30行代码搞定简单手写识别!

我们可以获取到的数据在编译器里是以矩阵形式存储的,如下:

10分钟教你用python 30行代码搞定简单手写识别!

teX为10000乘784的矩阵,teY为10000乘10的矩阵,10000表示例子的数目,784就是28x28个像素点,因为有10种不同的数字,所以teY的另一维度为10,每一维的值用来判断是否是该维对应的数字。teX,teY构成了训练集的数据。同理,trX,trY为测试集。

接下来要介绍的部分都只是模型构建的部分不同,大家可以参考上面数据的转化图片进行理解。

我们首先不管三七二十一,就用线性模型来做分类。

算上注释和空行,一共加起来30行左右,我们就可以解决手写识别这么困难的问题啦!请看代码:

10分钟教你用python 30行代码搞定简单手写识别!

经过100轮的训练,我们的准确率是92.36%。

无脑的浅层神经网络

用了最简单的线性模型,我们换成经典的神经网络来实现这个功能。

我们还是不管三七二十一,建立一个隐藏层,用最传统的sigmoid函数做激活函数。sigmoid的数学形式如下:

10分钟教你用python 30行代码搞定简单手写识别!

其核心逻辑还是矩阵乘法,这里面没有任何技巧。

    h = tf.nn.sigmoid(tf.matmul(X, w_h)) 
       return tf.matmul(h, w_o)

完整代码如下,仍然是40多行,不长:

10分钟教你用python 30行代码搞定简单手写识别!

10分钟教你用python 30行代码搞定简单手写识别!

第一轮运行,我这次的准确率只有69.11% ,第二次就提升到了82.29%。跑100轮的最终结果是95.41%,比Logistic回归的强!

请注意我们模型的核心那两行代码,完全就是无脑地全连接做了一个隐藏层而己,这其中没有任何的技术。完全是靠神经网络的模型能力。

深度学习时代方案 - ReLU和Dropout

我们将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这两个技巧,我们仍然只有一个隐藏层,表达能力没有太大的增强。并不能算是深度学习。

10分钟教你用python 30行代码搞定简单手写识别!

10分钟教你用python 30行代码搞定简单手写识别!

从结果看到,第二次就达到了96%以上的正确率。后来就一直在98.4%左右游荡。仅仅是ReLU和Dropout,就把准确率从95%提升到了98%以上。

卷积神经网络出场

接下来,真正的深度学习利器CNN,卷积神经网络出场。这次的模型比起前面几个无脑型的,的确是复杂一些。涉及到卷积层和池化层。

10分钟教你用python 30行代码搞定简单手写识别!

10分钟教你用python 30行代码搞定简单手写识别!

10分钟教你用python 30行代码搞定简单手写识别!

我们看下这次的运行数据:

    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和机器学习工具,我们只有几十行代码,就解决了手写识别这样级别的问题,而且准确度可以达到如此程度。

模型结果展示

说了这么多模型,我们来做个对比:

10分钟教你用python 30行代码搞定简单手写识别!

模型实践显神威

我们再用手写的图片试验一下模型的效果,手写图片如下:

10分钟教你用python 30行代码搞定简单手写识别!

10分钟教你用python 30行代码搞定简单手写识别!

图片处理的方式如下:

    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就是输入模型的图像数据

我们可以看到,图片导入到编译器里后存储为了一个矩阵,矩阵里面的数字代表了每一个像素点。

10分钟教你用python 30行代码搞定简单手写识别!

输出结果分别为[2]和[3],预测成功!说明训练出来的模型识别数字的能力还是挺强的。

听说最近苹果霸霸又申请了一项新专利——实时手写识别技术。

10分钟教你用python 30行代码搞定简单手写识别!

手写电子笔记的福音啊!

连苹果都在研究的技术,咱们也能小秀一把,是不是超开心
欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可!

10分钟教你用python 30行代码搞定简单手写识别!

10分钟教你用python 30行代码搞定简单手写识别!的更多相关文章

  1. 30行代码搞定WCF并发性能测试

    [以下只是个人观点,欢迎交流] 30行代码搞定WCF并发性能 轻量级测试. 1. 调用并发测试接口 static void Main()         {               List&lt ...

  2. Tensorflow快餐教程(1) - 30行代码搞定手写识别

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/lusing/article/details ...

  3. 【python】10分钟教你用python打造贪吃蛇超详细教程

    10分钟教你用python打造贪吃蛇超详细教程 在家闲着没妹子约, 刚好最近又学了一下python,听说pygame挺好玩的.今天就在家研究一下, 弄了个贪吃蛇出来.希望大家喜欢. 先看程序效果: 0 ...

  4. 【python】10分钟教你用python如何正确把妹

    前言 今天没妹子约,刚好研究一下.如何用神奇的python打造一个把妹神器吧.看完这个,你们就能走向人生巅峰,迎娶白富美啦. 我知道你们想看看效果 image 当然啦,这只是测试版的效果,真正的版本可 ...

  5. 10分钟教你用Python打造天气机器人+关键字自动回复+定时发送

    01 前言 Hello,各位小伙伴.自上次我们介绍了Python实现天气预报的功能以后,那个小程序还有诸多不完善的地方,今天,我们再次来完善一下我们的小程序.比如我们想给机器人发“天气”等关键字,它就 ...

  6. 【python】10分钟教你用python下载和拼接微信好友头像图片

    前言 相信微信大家是用得再多也不过了.那么,对于python+微信,又能玩出什么新的花样呢?下面小编就给大家带来一个好玩的东西.用python下载所有的微信好友的头像,然后拼接成一张大图.这样,大家就 ...

  7. 10分钟教你用Python打造微信天气预报机器人

    01 前言 最近武汉的天气越来越恶劣了.动不动就下雨,所以,拥有一款好的天气预报工具,对于我们大学生来说,还真是挺重要的了.好了,自己动手,丰衣足食,我们来用Python打造一个天气预报的微信机器人吧 ...

  8. 10分钟教你用Python玩转微信之好友性别比例统计分析

    01 前言+效果展示 想必,微信对于大家来说,是再熟悉不过的了.那么,大家想不想探索一下微信上的各种奥秘呢?今天,我们一起来简单分析一下微信上的好友性别比例吧~废话不多说,开始干活. 结果如下: 02 ...

  9. 10分钟教你用Python玩转微信之抓取好友个性签名制作词云

    01 前言+展示 各位小伙伴我又来啦.今天带大家玩点好玩的东西,用Python抓取我们的微信好友个性签名,然后制作词云.怎样,有趣吧~好了,下面开始干活.我知道你们还是想先看看效果的. 后台登录: 词 ...

随机推荐

  1. IO(三)----序列流

    SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的 ...

  2. css优先级问题

    关于CSS specificityCSS 的specificity 特性或称非凡性,它是衡量一个衡量CSS值优先级的一个标准,既然作为标准,就具有一套相关的判定规定及计算方式,specificity用 ...

  3. nginx不支持pathinfo函数

    server { listen ; server_name www.domain.com domain.com; error_page /.html; error_page /50x.html; lo ...

  4. jquery ajax/post/get 传参数给 mvc的action

    jquery ajax/post/get 传参数给 mvc的action1.ActionResult Test1    2.View  Test1.aspx3.ajax page4.MetaObjec ...

  5. C# 二维数组和集合

    本次课我主要学习了二维数组和集合的部分内容. 在二维数组的部分中,我主要学习了二维数组的定义方法:int [,] array=new int [4,2];做了一个小练习:用二维数组打印自己的姓氏. s ...

  6. View与ViewGroup有什么区别?

    百度知道:http://zhidao.baidu.com/link?url=B5MFOzDlww8soYqr5CL5FldH4sXD6eumS1XTRn8XEh8gu4mKjQdPkJSLIBt7u_ ...

  7. thinkphp获取特定字段的两种方法

    thinkphp getField( )和field( ) 2014年10月05日 ⁄ 综合 ⁄ 共 1509字 ⁄ 字号 小 中 大 ⁄ 评论关闭 做数据库查询的时候,比较经常用到这两个,总是查手册 ...

  8. https知识了解与javaweb中如何使用https

    1)      https是什么? https是一种协议,在说https之前我们先说一下什么是http,http就是我们平时浏览网页时使用的一种协议,https协议传输的数据都是未加密的,也就是明文的 ...

  9. web.xml中配置spring配置(application.xml)文件

    application.xml 一般放到WEB-INF下,当然,你也可以将它放到任意问题,但需要web.xml指向到该文件 1.application.xml配置 <?xml version=& ...

  10. 一:ActiveMQ知识整理

    一:JMS概念 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消 ...