本文所描述的研究主要關(guān)注在線手寫體識別系統(tǒng)中的單詞識別技術(shù)。該在線手寫體識別系統(tǒng)使用多組件神經(jīng)網(wǎng)絡(luò)(multiple component neural networks, MCNN)作為分類器的可交換部分。作為一種新近的方法,該系統(tǒng)通過將手寫文字分割成可單獨識別的小片段(通常是字符)來進(jìn)行識別。于是,識別結(jié)果便是每個已識別部分的組合。然后將這些組合詞發(fā)送給單詞識別模塊作為輸入,以便用一些字典搜索算法來從里面選擇好的一個。所提出的分類器克服了傳統(tǒng)的分類器對大量字符類別進(jìn)行分類時的障礙和困難。此外,所提出的分類器還具有可擴(kuò)展的能力,可以通過添加或更改組件網(wǎng)絡(luò)和內(nèi)置字典的方法來動態(tài)地識別另外的字符類別。
現(xiàn)在,觸摸式用戶接口(touch user interfaces, TUI)日益普及,將在人機(jī)交互中發(fā)揮重要作用。采用手指或筆進(jìn)行輸入的平板電腦、智能手機(jī)和TUI(觸摸式用戶接口)電腦正在成為許多人不可或缺的一部分。作為輸入設(shè)備,手指或筆代替了傳統(tǒng)的鼠標(biāo)和鍵盤的許多功能。筆在鼠標(biāo)上的一個主要優(yōu)點是,筆是一種自然的書寫工具,而鼠標(biāo)在被當(dāng)作書寫工具時卻是非常麻煩的。但是用筆作為輸入時,需要將手寫文本可靠地轉(zhuǎn)換為可由計算機(jī)直接處理的編碼,如ASCII(美國信息交換標(biāo)準(zhǔn)代碼)。傳統(tǒng)的轉(zhuǎn)換模型通常包含一個從圖像或輸入屏幕中提取每個單詞,并將其分成若干段的預(yù)處理步驟。神經(jīng)網(wǎng)絡(luò)分類器然后給出每段中每個可能字符的可能性。這些結(jié)果被后續(xù)的識別整個單詞的特殊算法作為輸入。近年來,手寫字符識別的研究已經(jīng)發(fā)展到可以商用的水平。然而,這種單個神經(jīng)網(wǎng)絡(luò)分類器的顯著缺點是其在大型網(wǎng)絡(luò)組織中以及在容量擴(kuò)展中的復(fù)雜性。
在識別少數(shù)字符類別時,很容易建立一個可靠的、識別率高的神經(jīng)網(wǎng)絡(luò)。但是在識別大量字符類別時,就不那么容易了。較大的輸入和輸出增加了神經(jīng)網(wǎng)絡(luò)的層數(shù)以及神經(jīng)元和連接的數(shù)目。于是,網(wǎng)絡(luò)在訓(xùn)練過程中會遇到更多的困難,尤其是所訓(xùn)練網(wǎng)絡(luò)的識別率會明顯下降。此外,單個神經(jīng)網(wǎng)絡(luò)分類器只適用于特定的字符類別。在不重新構(gòu)建或重新訓(xùn)練神經(jīng)網(wǎng)絡(luò)的情況下,這些單個神經(jīng)網(wǎng)絡(luò)分類器在識別附加的字符類別時,它們是不可交換且不可擴(kuò)展的。
本文提出了一種基于多卷積神經(jīng)網(wǎng)絡(luò)(convolutional neural networks,CNNs)的在線手寫字符識別系統(tǒng)。與傳統(tǒng)的單神經(jīng)網(wǎng)絡(luò)分類器不同,新的神經(jīng)網(wǎng)絡(luò)分類器包含一系列識別率非常高的CNN部件。每個CNN部件只正確識別大量字符類別(數(shù)字,字母等)中的一部分。但是當(dāng)用編程算法對這些網(wǎng)絡(luò)進(jìn)行組合時,通過簡單地添加或移除CNN組件和語言詞典,他們就可以創(chuàng)建一個靈活的、能夠識別大量字符類別的分類器。<o:p>
卷積神經(jīng)網(wǎng)絡(luò)(CNN)是一種特殊的多層神經(jīng)網(wǎng)絡(luò)。像幾乎所有其他的神經(jīng)網(wǎng)絡(luò)一樣,它們是用反向傳播算法的一種變體來進(jìn)行訓(xùn)練的。他們之間不同的地方就是架構(gòu)。卷積神經(jīng)網(wǎng)絡(luò)被設(shè)計成可以用小的預(yù)處理直接從像素圖像中識別視覺模式。他們可以識別極其易變的模式(例如手寫字符),而且它們對失真以及簡單的幾何變換具有魯棒性。

用于手寫數(shù)字識別的卷積神經(jīng)網(wǎng)絡(luò)LeNET 5在MNIST數(shù)據(jù)集上獲得了高達(dá)99%的可靠識別率。LeNET 5的輸入層大小為32 x32,該層接收包含有要識別數(shù)字的灰度圖像。像素強(qiáng)度被歸一化到-1和+1之間。個隱藏層C1包含有六個特征圖,每個特征圖有25個權(quán)重,構(gòu)成一個5x5的可訓(xùn)練核與偏差。將輸入層與相應(yīng)的核進(jìn)行卷積,然后應(yīng)用激活函數(shù)來計算特征圖的值。將特征圖的所有值限制為共享相同的可訓(xùn)練核或相同的權(quán)重值。由于邊界效應(yīng),特征圖的尺寸是28x28,比圖像輸入層的尺寸要小。<o:p>
每個卷積層之后是采樣層,該層用因子2來降低各卷積層中特征圖的尺寸。因此,隱藏層S2的二次采樣圖的尺寸為14×14。類似地,C3層具有16個尺寸為10×10的卷積圖,S4層具有尺寸為5×5的16個采樣圖。這些層的功能與C1和S2層完全相同。S4層的特征圖的尺寸是5x5,對于構(gòu)建第三個卷積層而言太小了。這個神經(jīng)網(wǎng)絡(luò)的C1到S4層可以看作是一個可訓(xùn)練的特征提取器。然后,可訓(xùn)練的分類器以3個全連接層(通用分類器)的形式被添加到特征提取器之后。<o:p>

手寫數(shù)字識別的另一個CNN模型是將卷積和二次采樣過程集成到一個單一層中,同樣可以使識別率達(dá)到99%以上。該模型以更高的分辨率提取簡單的特征圖,然后通過對圖層進(jìn)行二次采樣,以較低的分辨率將其轉(zhuǎn)換為更復(fù)雜的特征圖。可訓(xùn)練核的寬度通常選擇成以一個單位為中心(即為奇數(shù)大小),以便既可以有足夠的重疊而不會丟失信息(3將會過小,因為只有一個單位重疊),也不會產(chǎn)生冗余計算(7個單位太大,用5個單位或者采用超過70%的重疊)。填充輸入(使輸入更大,從而使邊界上的特征單元居中)并不會顯著提高性能。無填充的、具有兩個采樣層和一個5x5大小可訓(xùn)練核的每個卷積層可將特征圖大小從n減小到(n-3)/2。由于在這個模型中使用的初始MNIST輸入大小是28×28,所以在卷積2層后還能產(chǎn)生整數(shù)的近大小是29×29。經(jīng)過兩層卷積之后,5x5大小的特征對于第三層卷積來說太小了。這個神經(jīng)網(wǎng)絡(luò)的前兩層可以看作是一個可訓(xùn)練的特征提取器。然后,可訓(xùn)練的分類器以2個全連接層(通用分類器)的形式被添加到特征提取器之后。
對于對諸如數(shù)字或英文字母表(26個字符)等的少量字符類別進(jìn)行識別時,卷積神經(jīng)網(wǎng)絡(luò)的識別率確實很高。然而,創(chuàng)建一個可以可靠地識別更大的字符集合(62個字符)的大型神經(jīng)網(wǎng)絡(luò),仍是具有挑戰(zhàn)性的任務(wù)。因為利用大量輸入模式來訓(xùn)練神經(jīng)網(wǎng)絡(luò)需要更長的時間,尋找一個優(yōu)化的和足夠大的網(wǎng)絡(luò)變得更加困難。此類網(wǎng)絡(luò)收斂速度較慢,尤其是在書寫不良的字符、相似的字符和易混淆的字符集合比較大的情況下,準(zhǔn)確率有明顯的下降。<o:p>
針對上述問題,這里提出的解決方案是用多個在自己的輸出集合里擁有高識別率的小網(wǎng)絡(luò)來代替一個單獨的復(fù)雜神經(jīng)網(wǎng)絡(luò)。每個網(wǎng)絡(luò)組件在原始官方輸出集(數(shù)字,字母...)之外都有一個額外的未知輸出(未知字符)。這就意味著,如果輸入模式不被該網(wǎng)絡(luò)識別成官方的輸出字符,那么它將被解釋為一個未知的字符。

分類器的字符識別模塊是與輸入模式一起工作的多個神經(jīng)網(wǎng)絡(luò)部件的集合。一個手寫的單詞是通過分割成獨立的字符視覺模式來進(jìn)行預(yù)處理的。然后,這些模式傳遞給所有的神經(jīng)網(wǎng)絡(luò)組件作為輸入,每個神經(jīng)網(wǎng)絡(luò)組件將識別自身所擁有字符類別的可能性。因為在不同的類中有幾個相似的字符,因此一個視覺模式可能被單個、數(shù)個或者全部的網(wǎng)絡(luò)組件識別到。如果一個網(wǎng)絡(luò)無法識別出與它自身擁有字符類別相似的可能字符,它將返回一個未知的字符(空字符)。字符識別模塊的輸出結(jié)果是可能單詞的列表,它由所有識別出的可能單詞組成,如在上面的例子中,輸出結(jié)果是“Exper1,Expert,ExperJ,EXper1,EXpert,EXperJ”。未知字符(空字符)不會被用于組合單詞。之后,系統(tǒng)將這些單詞依次輸入下一個單詞識別模塊,以選擇正確的單詞作為整個分類器的輸出。在這個例子中,“Expert”這個單詞將會被選中。

在字符識別模塊中使用的單詞組成算法:
全局變量:
void GetWords(int startIndex, String baseWord) { String newWord = ""; if (startIndex == charMatrix.Count - 1) { for (int i = 0; i < charMatrix[startIndex].Count; i++) { newWord = String.Format("{0}{1}", baseWord, charMatrix[startIndex][i].ToString()); words.Add(newWord); } } else { for (int i = 0; i < charMatrix[startIndex].Count; i++) { newWord = String.Format("{0}{1}", baseWord, charMatrix[startIndex][i].ToString()); int newIndex = startIndex + 1; GetWords(newIndex, newWord); } } }
事實上,單詞識別模塊是一個使用了數(shù)個詞典搜索算法和文字修正技術(shù)的拼寫檢查器。這些算法與技術(shù)可以幫助獲得好的、有意義的單詞。所有來自字符識別模塊的可能單詞都被依次提供給字典搜索模塊。如果在內(nèi)置字典中找到其中一個單詞,它將成為分類器的輸出單詞。另外,在自動模式下一些文字修正技術(shù)將被應(yīng)用于選擇正確的單詞,在手動模式下則向用戶顯示近似單詞的列表。其中一些技巧是:
private bool ReplaceChars(String word, out String result) { result = ""; bool isFoundWord = false; foreach (WordDictionary dictionary in Dictionaries) { ArrayList replacementChars = dictionary.ReplaceCharacters; for (int i = 0; i < replacementChars.Count; i++) { int split = ((string)replacementChars[i]).IndexOf(' '); string key = ((string)replacementChars[i]).Substring(0, split); string replacement = ((string)replacementChars[i]).Substring(split + 1); int pos = word.IndexOf(key); while (pos > -1) { string tempWord = word.Substring(0, pos); tempWord += replacement; tempWord += word.Substring(pos + key.Length); if (this.TestWord(tempWord)) { result = tempWord.ToString(); isFoundWord = true; return isFoundWord; } pos = word.IndexOf(key, pos + 1); } } } return isFoundWord; }
private bool SwapChar(String word, out String result) { result = ""; bool isFoundWord = false; foreach (WordDictionary dictionary in Dictionaries) { for (int i = 0; i < word.Length - 1; i++) { StringBuilder tempWord = new StringBuilder(word); char swap = tempWord[i]; tempWord[i] = tempWord[i + 1]; tempWord[i + 1] = swap; if (this.TestWord(tempWord.ToString())) { result = tempWord.ToString(); isFoundWord = true; return isFoundWord; } } } return isFoundWord; }
private bool ForgotChar(String word, out String result) { result = ""; bool isFoundWord = false; foreach (WordDictionary dictionary in Dictionaries) { char[] tryme = dictionary.TryCharacters.ToCharArray(); for (int i = 0; i <= word.Length; i++) { for (int x = 0; x < tryme.Length; x++) { StringBuilder tempWord = new StringBuilder(word); tempWord.Insert(i, tryme[x]); if (this.TestWord(tempWord.ToString())) { result = tempWord.ToString(); isFoundWord = true; return isFoundWord; } } } } return isFoundWord; }
private bool TwoWords(String word, out String result) { result = ""; bool isFoundWord = false; for (int i = 1; i < word.Length - 1; i++) { string firstWord = word.Substring(0, i); string secondWord = word.Substring(i); if (this.TestWord(firstWord) && this.TestWord(secondWord)) { string tempWord = firstWord + " " + secondWord; result = tempWord; isFoundWord = true; return isFoundWord; } } return isFoundWord; }
通過在拼寫檢查器中同時使用多個不同語言的字典,如果存在能夠識別這些語言字符類別的神經(jīng)網(wǎng)絡(luò)部件,則所提出的分類器可以正確識別這些不同的語言。
public NNTestingControl() { InitializeComponent(); bitmap = null; networks = null; textSpellControl1.SpellChecker = this.multipleSpelling; //英語字典 multipleSpelling.Dictionaries.Add(this.wordDictionary1); //法語字典 //multipleSpelling.Dictionaries.Add(this.wordDictionary2); //意大利語字典 //multipleSpelling.Dictionaries.Add(this.wordDictionary3); }
該演示使用三個CNN部件識別62個英文字符類別。
本站文章版權(quán)歸原作者及原出處所有 。內(nèi)容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負(fù)責(zé),本站只提供參考并不構(gòu)成任何投資及應(yīng)用建議。本站是一個個人學(xué)習(xí)交流的平臺,網(wǎng)站上部分文章為轉(zhuǎn)載,并不用于任何商業(yè)目的,我們已經(jīng)盡可能的對作者和來源進(jìn)行了通告,但是能力有限或疏忽,造成漏登,請及時聯(lián)系我們,我們將根據(jù)著作權(quán)人的要求,立即更正或者刪除有關(guān)內(nèi)容。本站擁有對此聲明的最終解釋權(quán)。