1. 程式人生 > >10 行程式碼實現手寫數字識別

10 行程式碼實現手寫數字識別

可直接閱讀原文:http://c.raqsoft.com.cn/article/1540374496048?r=alice

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

 

不過隨著機器學習技術的普及,使用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(結構化處理語言)來編碼實現:

 

A

B

C

1

=file("train-imgs.btx")[email protected]()

   

2

>x=[],wei=[],bia=[],v=0.0625,cnt=0

   

3

for 10

>wei.insert(0,[to(28*28).(0)]),

bia.insert(0,0.01)

 

4

for 50000

>label=A1.fetch(1)(1)

 

5

 

>y=to(10).(0), y(label+1)=1,x=[]

 

6

 

>x.insert(0,A1.fetch(28*28))

>x=x.(~/255)

7

 

=wei.(~**x).(~.sum()) ++ bia

 

8

 

=B7.(1/(1+exp(-~)))

 

9

 

=(B8--y)**(B8.(1-~))**B8

 

10

 

for 10

>wei(B10)=wei(B10)--x.(~*v*B9(B10)),

bia(B10)=bia(B10) - v*B9(B10)

11

>file("MNIST模型.btx")[email protected](wei),file("MNIST模型.btx")[email protected](bia)    

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

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,訓練完畢,把模型儲存到檔案。

 

測試效果和優化,以及編碼可看原文:http://c.raqsoft.com.cn/article/1540374496048?r=alice

作者:liwei
來源:乾學院
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。