zoukankan      html  css  js  c++  java
  • 用BP人工神经网络识别手写数字

    http://wenku.baidu.com/link?url=HQ-5tZCXBQ3uwPZQECHkMCtursKIpglboBHq416N-q2WZupkNNH3Gv4vtEHyPULezDb50ZcKor41PEikwv5TfTqwrsQ4-9wmH06L7bYD04u

    用BP人工神经网络识别手写数字

    yzw20091201上传于2013-01-31|暂无评价|356人阅读|13次下载|暂无简介|举报文档

       �在手机打开
     

    赖勇浩(

     

    http://laiyonghao.com

     

    这是我读工程硕士的时候完成课程作业时做的,

    放在

     

     

    dropbox 

    的角落中生尘已经有若干年

    头了,

    最近

     

     

    @shugelee

     

    同学突然来了兴致搞验证码识别,

    问到我的时候我记起自己做过一

    点点东西,特发上来给他参考,并趁机补充了一下《

    Python

    也可以》系列。

     

    图像预处理

    使用下图(后方称为

     

    SAMPLE_BMP

    )作为训练和测试数据来源,

    下文将讲述如何将图像转换为训练数据。

     

     

     

     

    灰度化和二值化

     

    在字符识别的过程中,

    识别算法不需要关心图像的彩色信息。

    因此,

    需要将彩色图像转化为

    灰度图像。

    经过灰度化处理后的图像中还包含有背景信息。

    因此,我们还得进一步处理,

    背景噪声屏蔽掉,

    突显出字符轮廓信息。

    二值化处理就能够将其中的字符显现出来,

    并将背

    景去除掉。在一个

    [0

    255]

    灰度级的灰度图像中,我们取

     

    196 

    为该灰度图像的归一化值,

    代码如下:

     

    [python]

    view plaincopy 

    1.

     

    def

     convert_to_bw(im):   

    2.

     

        im = im.convert("L")   

    3.

     

        im.save("sample_L.bmp")   

    4.

     

        im = im.point(

    lambda

     x: WHITE 

    if

     x > 196

    else

     BLACK)   

    5.

     

        im = im.convert('1')   

    6.

     

        im.save("sample_1.bmp")   

    7.

     

    return

     im   

    下图是灰度化的图像,可以看到背景仍然比较明显,有一层淡灰色:

     

     

     

    下图是二值化的图像,可以看到背景已经完全去除:

     

     

     

     

    图片的分割和规范化:

     

    通过二值化图像,

    我们可以分割出每一个字符为一个单独的图片,

    然后再计算相应的特征值,

    如下图所示:

     

     

     

    这些图片是由程序自动进行分割而成,其中用到的代码片段如下:

     

    [python]

    view plaincopy 

    1.

     

    def

     split(im):   

    2.

     

    assert

     im.mode == '1' 

    3.

     

        result = []   

    4.

     

        w, h = im.size   

    5.

     

        data = im.load()   

    6.

     

        xs = [0, 23, 57, 77, 106, 135, 159, 179, 205, 228, w]   

    7.

     

        ys = [0, 22, 60, 97, 150, h]   

    8.

     

    for

     i, x 

    in

     enumerate(xs):   

    9.

     

    if

     i + 1 >= len(xs):   

    10.

     

    break

     

    11.

     

    for

     j, y 

    in

     enumerate(ys):   

    12.

     

    if

     j + 1 >= len(ys):   

    13.

     

    break

     

    14.

     

                box = (x, y, xs[i+1], ys[j+1])   

    15.

     

                t = im.crop(box).copy()   

    16.

     

                box = box + ((i + 1) % 10, )   

    17.

     

    #           save_32_32(t, 'num_%d_%d_%d_%d_%d'%box) 

    18.

     

                result.append((normalize_32_32(t, 'num_%d_%d_%d_%d_%d'%box), (i + 1) % 10)

    )   

    19.

     

    return

     result   

    其中的

     

    xs 

     

    ys 

    分别是横向和竖向切割的分界点,由手工测试后指定,

    t = 

    im.crop(box).copy() 

    代码行是从指定的区域中

    “抠”

    出图片,

    然后通过

     

    normalize_32_32 

    进行规范化。

    进行规范化是为了产生规则的训练和测试数据集,

    也是为了更容易地地计算出

    特征码。

     

     

    产生训练数据集和测试数据集

     

    为简单起见,我们使用了最简单的图像特征——黑色像素在图像中的分布来进行训练和测

    试。

    首先,

    我们把图像规范化为

     

    32*32 

    像素的图片,

    然后按

     

    2*2 

    分切成

     

    16*16 

     

    256 

    子区域,

    然后统计这

     

    个像素中黑色像素的个数,

    组成

     

    256 

    维的特征矢量,

    如下是数字

     

    的一个特征矢量:

     

    0 0 4 4 4 2 0 0 0 0 0 0 0 0 2 4 0 0 4 4 4 2 0 0 0 0 0 0 0 0 2 4 2 2 4 4 2 1 0 0 0 0 0 0 1 2 

    3 4 4 4 4 4 0 0 0 0 0 0 0 0 2 4 4 4 4 4 4 4 0 0 0 0 0 0 0 0 2 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 

    2 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 2 4 4 4 4 4 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 0 0 0 0 0 0 0 4 

    4 4 4 4 4 4 4 4 2 2 2 2 2 2 2 4 4 2 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 2 4 4 4 2 2 2 2 4 3 2 2 

    2 2 2 0 2 4 4 4 0 0 0 0 4 2 0 0 0 0 0 0 2 4 4 4 0 0 0 0 4 2 0 0 0 0 0 0 2 4 4 4 0 0 0 0 0 0 

    0 0 0 0 0 0 2 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 2 4 4 4 

    相应地,因为我们只需要识别

     

    0~9 

     

    10 

    个数字,所以创建一个

     

    10 

    维的矢量作为结果,

    数字相应的维置为

     

    值,其它值为

     

    0

    。数字

     

    的结果如下:

    0 0 1 0 0 0 0 0 0 0 

    我们特征矢量和结果矢量通过以下代码计算出来后,按

     

    FANN 

    的格式把它们存到

     

    train.data 

    中去:

     

    [python]

    view plaincopy 

    1.

     

    f = open('train.data', 'wt')   

    2.

     

    print

     >>f, len(result), 256, 10 

    3.

     

    for

     input, output 

    in

     result:   

    4.

     

    print

     >>f, input   

    5.

     

    print

     >>f, output   

    BP

    神经网络

    利用神经网络识别字符是本文的另外一个关键阶段,良好的网络

    性能是识别结果可靠性的重要保证。

    这里就介绍如何利用

    BP 

    神经网络来识别字符。

    反向传

    播网络(即:

    Back-Propagation Networks ,

    简称:

    BP 

    网络)是对非线性可微分函数进行

    权值训练的多层前向网络。在人工神经网络的实际应用中,

    80%

    90%

    的模型采用

     

    BP 

    络。它主要用在函数逼近,模式识别,分类,数据压缩等几个方面,体现了人工神经网络的

    核心部分。

     

     

    网络结构

     

    网络结构的设计是根据输入结点和输出结点的个数和网络性能来决定的,

    如下图。

    本实验中

    的标准待识别字符的大小为

     

    32*32 

    的二值图像,即将

     

    1024 

    个像素点的图像转化为一个

     

    256 

    维的列向量作为输入。由于本实验要识别出

    10 

    个字符,可以将目标输出的值设定为

    一个

    10 

    维的列向量,其中与字符相对应那个位为

    1

    ,其他的全为

    。根据实际经验和试

    验确定,本文中的网络隐含层结点数目为

    64

    。因此,本文中的

    BP 

    网络的结构为

     

    256-64-10

     

     
     
     
    delphi lazarus opengl 网页操作自动化, 图像分析破解,游戏开发
  • 相关阅读:
    VUE中tinymce设置字体大小、字体选择(就没有一篇文章能说的清楚的,那么我就说清楚这个问题)
    解决每次git push时需要输入用户名密码的问题
    vue路由,解决同一路由页面多次触发不刷新页面【vue开发】
    函数防抖和节流
    h5页面如何判断是系统Android,ios还是微信等
    react 结合 Promise 和 async await 解决多个异步请求 后统一设置状态问题
    对数组对象递归遍历给子对象添加父对象属性的方法
    React Hooks 使用指南
    webpack配置介绍
    React 实现键盘监听事件
  • 原文地址:https://www.cnblogs.com/delphi-xe5/p/5840719.html
Copyright © 2011-2022 走看看