[純C#實現]基於BP神經網絡的中文手寫識別算法


效果展示

這不是OCR,有些人可能會覺得這東西會和OCR一樣,直接進行整個字的識別就行,然而並不是.
OCR是2維像素矩陣的像素數據.而手寫識別不一樣,手寫可以把用戶寫字的筆畫時間順序,抽象成一個維度.這樣識別的就是3維的數據了.識別起來簡單很多.

最近需要做一個中文手寫識別算法.搜索了網上的一些前人作品,發現都是只講了理論,不講實際開發.於是打算自己開發一個,並記錄開發過程.

由於代碼量比較多,這里不會全部貼上來講解,代碼已經放到了gitee,部分地方需對照代碼進行觀看,下面有URL.

思路

網上關於中文手寫識別的文章不多,不過數字OCR方案確有很多.
雖然中文手寫識別並不等於OCR,但總歸有點關聯性.
我發現數字的OCR大概是這么個套路:

神經網絡的輸出層每一個節點對應一個數字的相似度.而中文不能這么做.因為中文有上萬字.
不過這是手寫識別,我們有用戶寫字的時候每一筆的數據,可以先識別筆畫.然后再根據筆畫,去識別字.

資源獲取與數據模型設定

首先我們需要一個字典,用於提供所有中文漢字的筆畫順序,這玩意在百度搜索"字典 mdb"能得到很多(我會放到源碼里)

通過查看字典的"筆順"字段,我們可以看到,字典中的字,筆順分為了: 橫,豎,撇,捺,其它 這5個類型

橫豎撇捺好弄,不過這個"其它"有點特別,通過查詢.中文的筆畫有30多種.
我按照長相,將筆畫大體分成了這7種:

ID 筆畫 名稱
0
1
2
3
4 ㇕㇖⺄ 橫折
5 ㇗㇙㇞㇟ㄣ㇂ ㇛㇜ 豎折
6 ㇡ ㇌ 橫折折折

也就是說,我這里是分成7種來識別的,后續使用的時候,是再轉換為5種筆畫.

我們將用戶輸入的筆畫順序識別出來后,經過字符串相似度算法,識別出用戶輸入的筆畫,與字典中每個字的筆畫的相似度,然后進行排序.
關於字符串相似度,這里采用的是 levenshtein算法,相關代碼可在我的源碼中找到.

開發采集工具&采集一些數據

首先我需要采集一些筆畫數據,然后交給神經網絡,訓練神經網絡識別能力.

這里開發了一個采集工具,用來采集一些用於訓練的數據:
Gitee查看源碼>>
Github查看源碼>>

使用方法如下:

保存后會得到一個json文件,里面是采集到的筆畫數據:

每個筆畫采集30次之后保存,在保存后,請將這個文件改名,然后再重新打開一次軟件,采集下一個筆畫

把上面表格中的7個筆畫每一個采集30次左右(次數不需要完全一樣)每個筆畫單獨采集到一個文件

再額外采集一個用於測試的數據:

訓練過程

這里選擇BP網絡的原因是因為網絡上有直接復制即可用的C#代碼,畢竟我是用C#開發,基於C#的神經網絡代碼很少.大部分是基於C或者python的.
我對我找到的BP網絡的部分代碼進行了修改,訓練完后可以把訓練結果保存為單個json文件.也可以讀取json文件接着訓練,或着運用里面的訓練結果進行識別.

把上面采集的7個筆畫樣本放入神經網絡訓練:

如你所見,我另外開發了一個訓練工具,讀取前面步驟采集到的筆畫數據生成矩陣,給BP網絡,進行訓練.

矩陣的格式:
注:我用來訓練的矩陣的大小是固定的16*16,以下只是為了說明而做的一個縮小版:

\ 第0列 第1列 第2列 第3列 第4列 第5列 更多列
第0行 0.2 0.0 0.0 0.0 0.0 0.0 .
第1行 0.0 0.4 0.0 0.0 0.0 0.0 .
第2行 0.0 0.0 0.6 0.0 0.0 0.0 .
第3行 0.0 0.0 0.0 0.8 0.0 0.0 .
第4行 0.0 0.0 0.0 0.0 1.0 0.0 .
第5行 0.0 0.0 0.0 0.0 0.0 0.0 .
更多行 . . . . . . .

注意:我在矩陣中使用0~1之間的浮點數標識出了哪個像素是先畫出來的,哪個像素是后畫出來的.
不過神經網絡輸入的矩陣是1維的,所以在代碼中可以看到,我寫了個GetDim1Matrix方法,將這里面的數據,全部連接到了一起.
在代碼中,有一個MatrixData類,這個類用於存放訓練或者識別用的數據並進行矩陣的輸出,可以在這里面找到生成矩陣的算法.

訓練完成后,使用訓練結果,對測試數據進行了測試.並生成了訓練結果文件:

訓練工具源碼:
Gitee查看源碼>>
Github查看源碼>>

實際使用

識別功能和采集工具做在一起了,將神經網絡訓練出來的結果"GData.json"文件放進采集工具工程里.運行工程即可.

在實際使用中效果沒有想象中的好,筆畫相似度高的字比較多,得把字寫得比較工整才能識別到,想要獲取更好的結果,還需要對方案進行更多的優化才行.

改進計划

目前我比較傾向於這兩個方案:

  1. 在測試中有個現象,筆畫識別錯誤率有點高,可能需要修改筆畫識別的方式,嘗試用別的方式去識別筆畫
  2. 我找到的字典有問題,字符雖然很全,但是筆畫分類才5種,只分為"橫,豎,撇,捺,其它",這個"其它"比較礙事,可以嘗試找筆畫分類更細的字典來解決這個問題.

如果對這個項目感興趣或者有更好優化的思路,可以給我留言


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM