- 程序員的AI書:從代碼開始
- 張力柯 潘暉
- 1210字
- 2020-04-24 15:04:48
1.3 從代碼開始
“Talk is cheap, show me the code”這句話無論是對于程序開發還是對于機器學習都是適用的。對于一個軟件工程師來說,原理、分析和推導都比不上一段真實的代碼更容易讓人理解,下面就讓我們直接嘗試用代碼來解決問題吧。
1.3.1 搭建環境
本節希望讓讀者盡快接觸真實開發環境下的代碼,因此將使用TensorFlow中的Keras作為開發框架(現在Keras已是TensorFlow的一部分)。此外,我們需要一些額外的Python包作為支持。我們選用了Python 3.7以上版本,并假設讀者已經安裝好Python 3.7。下面執行安裝本章代碼運行所需依賴庫的命令:

1.3.2 一段簡單的代碼
考慮一個簡單的問題:對正負數分類,對正數返回1,對負數返回0。
這用傳統的代碼實現起來非常簡單,如下所示:

但用機器學習該如何實現呢?
下面用TensorFlow自帶的Keras實現對正負數分類:

我們看看這18行代碼都做了什么。
第1~3行:引入依賴庫TensorFlow和其自帶的Keras相關庫。
第5~8行:這4行建立了一個簡單的兩層神經網絡模型。在第5行定義了一個Sequential類型的網絡,顧名思義是按順序層疊的網絡。在第6行加入第1層網絡,輸入input_dim為1,意味著只有1個輸入(因為我們只判斷一個數字是否為正數);但是定義了8個輸出(units=8),這個數字其實是隨意定的,可以視為其中神經元的個數(我們將在第2章解釋什么是神經元),一般神經元的個數越多,效果越好(訓練時間也越長)。算法科研人員會耗費大量的時間來確定這些數字,以找到最佳的個數。第7行再疊加一層,接收前面的輸出(8個),但作為最后一層,這次只定義一個輸出(units=1),這個輸出決定了最后的分類結果。第8行對整個模型進行最后的配置,選擇mean_squared_error(平均方差)作為損失函數計算,選擇隨機梯度下降(Stochastic Gradient Descent,SGD)作為梯度優化方式。這里將不從理論角度解釋隨機梯度下降的原理,但在第2章中將通過代碼來手工實現隨機梯度下降。
第10~12行:設定了兩組數據x和y作為訓練集,其中,x包括10個正數,y包括對應的10個分類結果。可以看到,對于x中的每個正數,y中對應的值都是1.0,負數x[i]所對應的y[i]則是0。然后我們調用model.fit函數進行訓練,設置epochs為10(訓練10次),batch_size為4(每次都隨機挑選4組數據)。
第14~18行:這里構建了4個輸入數據進行測試并打印結果。我們構建了數組test_x,該數組包含4個整數,然后調用model.predict方法對test_x進行預測。在第17~18行將打印每個輸入所對應的預測結果。
以上18行代碼的運行結果如下:

可以看到,在最后的預測結果中,所有正數的預測值都非常接近1,所有負數的預測值都小于0.01。前面解釋過,機器學習是一種概率預測,不可能完全精確,以上結果對正負數做了較為明確的劃分,是可以接受的。
經過上面的代碼實現,讀者可能仍然對其中涉及的一些內容有些茫然,比如什么是梯度下降,神經元又是什么,什么叫加一層、減一層,具體的參數又是怎樣訓練的,等等,在第2~4章會詳細解釋這些內容。
上述代碼是基于Keras實現的,Keras是機器學習研究主流的開發框架,封裝了很多常見的算法和模型。第2章將拋開這些框架,用最基本的Python代碼從最簡單的神經網絡開始,嘗試實現上面的功能。