10 行代碼,實現手寫數字識別

2021-02-13 了解做人做事

    聽說世界上只有百分之3的人關注Jayson,很幸運你是其中一位

識別手寫的阿拉伯數字,對於人類來說十分簡單,但是對於程序來說還是有些複雜的。


不過隨著機器學習技術的普及,使用10幾行代碼,實現一個能夠識別手寫數字的程序,並不是一件難事。這是因為有太多的機器學習模型可以拿來直接用,比如tensorflow、caffe,在python下都有現成的安裝包,寫一個識別數字的程序,10幾行代碼足夠了。

然而我想做的,是不藉助任何第三方的庫,從零開始,完全自己實現一個這樣的程序。之所以這麼做,是因為自己動手實現,才能深入了解機器學習的原理。

1 模型實現

1.1 原理

熟悉神經網絡回歸算法的,可以略過這一節了。

學習了一些基本概念,決定使用回歸算法。首先下載了著名的MNIST數據集,這個數據集有60000個訓練樣本,和10000個測試樣本。每個數字圖片都是28*28的灰度圖片,所以輸入可以認為是一個28*28的矩陣,也可以認為是一個28*28=784個像素值。

這裡定義一個模型用於判斷一個圖片數字,每個模型包括每個輸入的權重,加一個截距,最後再做個歸一。模型的表達式:

Out5= sigmoid(X0*W0+ X1*W1+……X783*W783+bias)

X0到X783是784個輸入,W0到W783是784個權重,bias是一個常量。sigmoid函數可以將較大範圍的數擠壓到(0,1)區間內,也就是歸一。

例如我們用這一組權重和bias來判斷數字5,期望當圖片是5時輸出是1,當不是5時輸出是0。然後訓練的過程就是根據每個樣本的輸入,計算Out5的值和正確值(0或1)的差距,然後根據這個差距,調整權重和bias。轉換一下公式,就是在努力使得(Out5-正確值)接近於0,即所謂損失最小。

同理,10個數字就要有10套模型,每個判斷不同的數字。訓練好以後,一個圖片來了,用這10套模型進行計算,哪個模型計算的結果更接近於1,就認為這個圖片是哪個數字。

1.2 訓練

按照上面的思路,使用集算器的SPL(結構化處理語言)來編碼實現:



不用再找了,訓練模型的所有代碼都在這裡了,沒有用到任何第三方庫,下面解析一下:

A1,用遊標導入MNIST訓練樣本,這個是我轉換過的格式,可以被集算器直接訪問;

A2,定義變量:輸入x,權重wei,訓練速度v,等;

A3,B3,初始化10組模型(每組是784個權重+1個bias);

A4,循環取5萬個樣本進行訓練,10模型同時訓練;

B4,取出來label,即這個圖片是幾;

B5,計算正確的10個輸出,保存到變量y;

B6,取出來這個圖片的28*28個像素點作為輸入,C6把每個輸入除以255,這是為了歸一化;

B7,計算X0*W0+ X1*W1+……X783*W783+bias

B8,計算sigmoid(B7)

B9,計算B8的偏導,或者叫梯度;

B10,C10,根據B9的值,循環調整10個模型的參數;

A11,訓練完畢,把模型保存到文件。

1.3 測試

測試一下這個模型的成功率吧,用 SPL 寫了一個測試程序:



運行測試,正確率達到了91.1%,我對這個結果是很滿意的,畢竟這只是一個單層模型,我用TensorFlow的單層模型得到的正確率也是91%多一點。下面解析一下代碼:

A1,導入模型文件;

A2,把模型提取到變量裡;

A3,計數器初始化(用於計算成功率);

A4,導入MNIST測試樣本,這個文件格式是我轉換過的;

A5,循環取1萬個樣本進行測試;

B5,取出來label;

B6,清空輸入;

B7,取出來這個圖片的28*28個像素點作為輸入,每個輸入除以255,這是為了歸一化;

B8,計算X0*W0+ X1*W1+……X783*W783+bias

B9,計算sigmoid(B7)

B10,得到最大值,即最可能的那個數字;

B11,判斷正確測計數器加一;

A12,A13,測試結束,關閉文件,輸出正確率。

1.4 優化

這裡要說的優化並不是繼續提高正確率,而是提升訓練的速度。想提高正確率的同學可以嘗試一下這幾個手段:

1. 加一個卷積層;

2. 學習速度不要用固定值,而是隨著訓練次數遞減;

3. 權重的初始值不要使用全零,使用正態分布;

我認為單純追求正確率的意義不大,因為MNIST數據集有些圖片本身就有問題,即使人工也不一定能知道寫的是數字幾。我用集算器顯示了幾張出錯的圖片,都是書寫十分不規範的,下面這個圖片很難看出來是2。


下面說重點,要提高訓練速度,可以使用並行或集群。使用SPL語言實現並行很簡單,只要使用fork關鍵字,把上面的代碼稍加處理就可以了。



使用了並行之後,訓練的時間減少差不多一半,而代碼並沒有做太多修改。

2 為什麼是 SPL 語言?

使用SPL語言在初期可能會有點不適應,用得多了會覺得越來越方便:

1. 支持集合運算,比如例子裡用到的784個輸入和784個權重的乘法,直接寫一個**就可以了,如果使用Java或者C,還要自己實現。

2. 數據的輸入輸出很方便,可以方便地對文件讀寫。

3. 調試太方便了,所有變量都直觀可見,這一點比python要好用。

4. 可以單步計算,有了改動不用從頭重來,Java和C做不到這一點,python雖然可以但也不方便,集算器只要點中相應格執行就可以了。

5. 實現並行和集群很方便,不需要太多的開發工作量。

6. 支持調用和被調用。集算器可以調用第三方java庫,Java也可以調用集算器的代碼,例如上面的代碼就可以被Java調用,實現一個自動填驗證碼的功能。

這樣的程式語言,用在數學計算上,實在是最合適不過了。

相關文件下載: 154037421300096d9.rar(http://img.raqsoft.com.cn/uploads/1024/154037421300096d9.rar)

點讚會好看也會世界和平,關注+點讚又能大富大貴又能世界和平

相關焦點

  • 實戰|手把手入門神經網絡,74行代碼實現手寫數字識別
    二、 我們要解決的問題:手寫數字識別手寫數字識別是機器學習領域中一個經典的問題,是一個看似對人類很簡單卻對程序十分複雜的問題。回到手寫數字識別,比如我們要識別出一個手寫的「9」,人類可能通過識別「上半部分一個圓圈,右下方引出一條豎線」就能進行判斷。但用程序表達就似乎很困難了,你需要考慮非常多的描述方式,考慮非常多的特殊情況,最終發現程序寫得非常複雜而且效果不好。
  • 手寫數字識別
    在這裡將會通過Keras實現卷積神經網絡來處理這個數據集,進步加深對卷積審計網絡的理解。13.1 問題描述MNIST數據集是由YannLeCun、Corinna Cortes和ChristopherBurges開發的用於評估手寫數字分類問題的機器學習模型的數據集。
  • 使用sklearn隨機森林算法實現手寫數字識別
    二:sklearn中隨機森林算法函數使用基於sklearn中隨機森林算法函數創建隨機森林實現mnist手寫數字識別,完整的代碼實現如下:from sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import accuracy_scoreimport
  • 使用AI算法進行手寫數字識別
    如上圖所示,快遞通過傳送帶進入「目的地識別系統」,識別後將該快遞分配到對應地點的傳送帶即可。那麼,該問題的關鍵就是「目的地識別系統」如何將快遞單上的目的地識別出來,並作出正確的判斷。以順豐速運的快遞單為例,快遞單上已將目的地翻譯為了城市代碼,通過識別該代碼即可讓機器「知道」快遞的目的地,然後配置對應傳送帶接收的具體城市代碼即可。
  • 【全代碼攻略】用百度大腦手寫文字識別助力企業降本增效
    以此類推,像請假條、辦公採購單,員工日工資明細等一些表格都可以通過百度手寫文字識別的方法來進行智能識別,極大降低文員的工作量,提高文員的工作效率。此外,在個人應用方面,可以將個人的會議紀要,演講稿等使用【手寫文字識別】功能,數位化內容存儲起來,可以結合【百度網盤】實現永久保存。
  • 手把手教你學Python之手寫數字識別
    問題描述:手寫數字識別是指給定一系列的手寫數字圖片以及對應的數字標籤,構建模型進行學習,目標是對於一張新的手寫數字圖片能夠自動識別出對應的數字
  • PyTorch深度學習框架入門——使用PyTorch實現手寫數字識別
    下面我們通過使用PyTorch實現一個手寫數字識別的模型來簡單的入門一下PyTorch。transforms,datasetsimport numpy as npimport matplotlib.pyplot as plt%matplotlib inline手寫數字的數據集我們可以使用PyTorch中自帶的torchvision.datasets方法進行下載。
  • 機器學習進階筆記| 利用TensorFlow實現智能數字識別
    Mnist數字識別項目介紹2. 準備工作申請一臺UCloud雲主機配置Tensorflow環境3. 編寫第一個Tensorflow項目——Mnist數字識別Mnist數字識別介紹人工智慧技術已經逐漸滲透到大眾生活的方方面面,從大名鼎鼎的AlphaGo,再到貼近實際生活的廣告展示、新聞智能推薦等,人工智慧技術被廣泛運用於各行各業。
  • 深度學習系列:PaddlePaddle之手寫數字識別
    不過呢,這塊內容太複雜了,所以就簡單的介紹一下paddlepaddle的第一個「hello word」程序----mnist手寫數字識別。下一次再介紹用PaddlePaddle做分布式訓練的方案。其實之前也寫過一篇用CNN識別手寫數字集的文章是用keras實現的,這次用了paddlepaddle後,正好可以簡單對比一下兩個框架的優劣。什麼是PaddlePaddle?
  • Python不超過10行代碼就可實現人臉識別,教你辨別真假
    一般我們考慮使用OpenCV、dlib等開源庫的人臉檢測功能(基於專家經驗的傳統特徵值方法計算量少從而速度更快),也可以使用基於深度學習實現的技術如MTCNN(在神經網絡較深較寬時運算量大從而慢一些)。下面環境搭建:1. 安裝 Ubuntu17.10 > 安裝步驟在這裡2.
  • 詳解與實戰TensorFlow MNIST手寫體數字識別(softmax and cnn)
    ,包含60000個訓練樣本和10,000個測試集,由紐約大學的Yann LeCun等人維護。MNIST 手寫體數字介紹MNIST圖像數據集使用形如【28,28】的二姐數組來表示每個手寫體數字,數組中的每個元素對應一個像素點,即每張圖像大小固定為28X28像素。
  • 附代碼|OpenCV實現銀行卡號識別,字符識別算法你知多少?
    今天我們就簡單的利用OpenCV處理通過提取輪廓和匹配等方式來實現模式匹配的字符識別。代碼如下:#定義了一個字典 FIRST_NUMBER ,它將第一個數字映射到相應的信用卡類型。,c為輪廓,我們將每個數字0-9(字典鍵)與第30行的每個roi 圖像(字典值)相關聯 。
  • 靈雲手寫識別平臺 讓手寫輸入行雲流水
    靈雲智能手寫識別平臺是提供單一技術能力的靈雲全智能能力平臺系列產品之一,該平臺採用了捷通華聲打磨16年之久的iWrite手寫識別引擎,支持中文行寫、疊寫,以及西文連筆手寫,識別準確率高達99%,讓手寫輸入行雲流水,一氣呵成。
  • 深度學習筆記13:Tensorflow實戰之手寫mnist手寫數字識別
    數據挖掘與機器學習,R與Python,理論與實踐並行。個人公眾號:數據科學家養成記 (微信ID:louwill12)前文傳送門:深度學習筆記1:利用numpy從零搭建一個神經網絡深度學習筆記2:手寫一個單隱層的神經網絡深度學習筆記3:手動搭建深度神經網絡(DNN)深度學習筆記4:深度神經網絡的正則化深度學習筆記5:正則化與dropout
  • 使用Pyhon+Flux+Julia實現手寫數字識別
    使用MNIST數據集對0到9之間的數字進行手寫數字識別是神經網絡的一個典型入門教程
  • 小白學機器學習|如何識別5000多個手寫數字
    今天我接著來分享一篇好玩的機器學習例子,我們如何識別手寫數字。怎麼玩呢:了解這個5000多個手寫數子清洗數據並用機器學習算法訓練讓機器來識別數字超參數調整提高準確率1.介紹一下這個數據集這個數據集也是非常有名的,是入門的經典數據集,而且時間也蠻久的了!
  • TF2.0深度學習實戰(一):分類問題之手寫數字識別
    手寫數字識別是一個非常經典的圖像分類任務,經常被作為深度學習入門的第一個指導案例。相當於我們學程式語言時,編寫的第一個程序「Hello World !」。不一樣的是,入門深度學習,需要有一定量的理論基礎。手寫數字識別是基於MNIST數據集的一個圖像分類任務,目的是通過搭建深度神經網絡,實現對手寫數字的識別(分類)。
  • 漢王推出全新手寫識別金豬版手寫軟體
    這是由於在「金豬版」裡進行同種語言輸入時,已經能夠實現文字、數字和符號的混識,用戶將不需在三種狀態下來回切換,這無疑將大大提高手寫速度。    金豬版手寫軟體:輸入界面更為人性化,簡潔了很多該軟體還突破了手寫識別的諸多技術難題,比如國內其他手寫廠商都尚未實現的英文整句識別以及數字串識別;突破性的實現整句輸入時的任意補筆,達到國內頂尖水平。
  • 介紹一個Python 包,幾行代碼可實現 OCR 文本識別!
    文字 OCR 識別技術現在已經相當成熟了,無論 其 準確度還是識別速度 都能夠滿足我們的日常需要;今天給大家介紹一個 Python 包,該包的主要功能就是用於 OCR 識別的,包的名字叫 Pyteeseract,藉助這個包幾行代碼就能快速識別一張文本圖片Pytesseract 包是由 開源工具
  • python+flask搭建CNN在線識別手寫中文網站
    ,並經過圖片裁剪處理之後傳入CNN手寫中文識別的模型中進行識別,最後通過PIL將識別結果生成圖片,最後異步回傳給web端進行識別結果展示。這裡主要對常見的3755個漢字進行識別。代碼獲取:關注微信公眾號 datayx  然後回復 手寫識別 即可獲取。