深度學習之解剖Hello World
通過上文:秒懂深度學習,我們對深度神經網路的結構和計算方法的理論有了一定的了解。作為程序員,我們秉承的精神是:talk is cheap, show me the code。所以今天我們就正式進入實戰環節,解剖深度神經網路的hello world。
深度學習或者機器學習的要素比較多,而且編程範式也不同於傳統的編程語言,所以它的hello world也就相對複雜。
數據
機器學習的第一要素是數據。我們採用MNIST數據集,這是一套手寫數字的數據集。也是機器學習里公認的hello world數據集。當然,有人說ImageNet是新的hello world。但是對於我們這種低玩來說,MNIST是個不錯的開始。
模型
深度學習最基本的模型就是全連接前向網路(fully connected feedforward network),也就是我們在上文中介紹到的模型。構建模型最簡單的方法是使用Keras框架。
損失函數(losss function)
損失函數是用來衡量輸出結果和實際結果之間的誤差的。反向傳播的過程就是基於誤差來調整模型參數的過程。這裡我們就選用常見的交叉熵(cross-entropy)損失函數。
優化演算法(Optimization Algorithms)
如果把損失函數比作靶子,那麼優化演算法就是如何逐步逼近靶心的方法。上文中我們講到了最常見的優化演算法是梯度下降。這裡我們使用它的一個進化版:RMSprop。比起梯度下降,它的訓練速度更快。
代碼實現
有了這些指導方針,我們就可以開始寫代碼了,我們的代碼是基於keras的一個例子,環境是jupyter notebook。
安裝packages的過程就省略了。我們從keras數據集中import了mnist,從models里import Sequential用於構建模型,Dense是用於向模型里的每一層添加units,最後從optimizer中選擇RMSprop。
matplotlib是一個用於可視化的庫,對於我們的模型並沒有什麼幫助,但是可以用來展示一些樣本數據。
batch_size是我們每一個迭代時候的輸入樣本數量。等一下我們可以看到,我們的training set里擁有60000個樣本。但是如果我們把所有的樣本放到一個batch里,迭代速度就會很慢。設置一個小的batch_size被稱為mini-batch,相當於小步快跑,這樣每次迭代需要的時間就會短很多。
num_classes等於10,因為我們的輸出是0到9中的一個值。
最後,一個epoch表示對整個traning set的一次迭代,我們將epochs設為20。
數據載入
第一行是數據的載入,load_data函數自動對數據進行洗牌,並將數據分為traing set和test set。x_train, y_train分別代表trainig set的輸入和真實輸出,x_test, y_test則表示testing set的輸入和真實輸出。 x_train.shape告訴我們training set里有60000個樣本,每一個都是28*28的二維矩陣,代表一張手寫數字的圖。我們從traing set里隨便挑了一個進行可視化,就得到了上圖。接下來我們對數據進行一些預處理。
預處理
這些預處理包括將輸入轉化為模型能夠接收的形狀,正規化(regularization)和將實際輸出從數字轉化為由0,1組成的向量。比如2就會變成[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],也就是從0位開始數,只有2位為1,總長度為10的向量。至於為什麼需要做這樣的一些處理我們以後再聊。下面進入真正的主題:構建深度神經網路模型。
構建深度神經網路
僅用4行代碼,我們就構建了一個深度神經網路模型。而且代碼無比直接:
- 初始化一個Sequential模型。
- 加上一個512個節點的隱藏層。激勵函數為relu,不是我們上文中提到的sigmoid函數,原因主要還是讓訓練更快。輸入的形狀為784,因為我們的每一個輸入樣本都是二維的28*28的圖片數據轉化為一維的,長度784的向量。
- 加上另一個512個節點的隱藏層,讓網路成為『深度』神經網路。
- 加上最後的輸出層,輸出層有10個節點,分別表示計算結果為0~9的概率。
我們的模型長得是這樣的(從下往上看):
接下來我們設置損失函數,優化演算法,並開始訓練我們的神經網路。
model.compile將損失函數設為cross-entropy,優化演算法設為RMSprop。model.fit就是模型的訓練過程。倒杯咖啡,等待大約1分鐘模型訓練的過程就完成了。用測試集測一下我們的模型,準確率已經達到了98%以上。
TAG:全球大搜羅 |