1. 程式人生 > >深度學習實踐(二)——多層神經網路

深度學習實踐(二)——多層神經網路

#一、準備
為了更深入的理解神經網路,筆者基本採用純C++的手寫方式實現,其中矩陣方面的運算則呼叫opencv,資料集則來自公開資料集a1a。
實驗環境:

本文緊跟上篇文章深度學習實踐(一)——logistic regression
#二、神經網路基礎
標準的神經網路結構如下圖所示,其實就是上文logistic regression的增強版(即多加了幾個隱層),基本思路還未變化。關於更詳細的原理介紹,這裡還是推薦吳恩達的深度學習系列課程
這裡寫圖片描述

下面以三層神經網路(即上圖)並結合a1a資料集,介紹構建的一般步驟:

  1. 初始化引數w1、w2、w3和b1、b2、b3,因為a1a資料集的維度是有123個特徵,所以上圖中input_layer維度為(123,m),m為樣本數量,如訓練集則為1065;而我們所構建的三層神經網路中間隱層神經元個數分別為(64,16,1),所以初始化引數矩陣w1(123,64)、w2(64,16)、w3(16,1)和偏置實數b1、b2、b3。
  2. 將W和X相乘(矩陣相乘,X為上層的輸出,一開始即為樣本的輸入),再加上偏置b(為實數),則得到Z。
  3. 將Z進行啟用,在隱層選擇啟用函式relu(可以更好的防止梯度爆炸,且結果很好),輸出層選擇sigmoid限制輸出,它們的影象如下:這裡寫圖片描述
  4. 將上面的正向傳播完成後,定義損失函式,這裡使用交叉熵代價函式。
  5. 反向傳播,並更新引數。

正向傳播基本公式:
這裡上標L代表第幾層,上標i表示第幾個樣本(對應到a1a資料集即第幾行),如 A [ 0 ]

A^{[0]} 表示0層的輸入(即樣本輸入)。

(1) Z [ 1 ] = W [ 1 ] A [ 0 ] + b [ 1 ] Z^{[1]} = W^{[1]}A^{[0]} +b^{[1]}\tag{1}
(2) A [ 1 ] = R e l u ( Z [ 1 ] ) A^{[1]} = Relu(Z^{[1]})\tag{2}
(3) Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] Z^{[2]} = W^{[2]}A^{[1]} +b^{[2]}\tag{3}
(4) A [ 2 ] = R e l u ( Z [ 2 ] ) A^{[2]} = Relu(Z^{[2]})\tag{4}
(5) Z [ 3 ] = W [ 3 ] A [ 2 ] + b [ 3 ] Z^{[3]} = W^{[3]}A^{[2]} +b^{[3]}\tag{5}
(6) A [ 3 ] = S i g m o i d ( Z [ 3 ] ) A^{[3]} = Sigmoid(Z^{[3]})\tag{6}
(7) L ( A [ 3 ] , Y ^ ) = A [ 3 ] log ( A [ 3 ] ) ( 1 Y ^ ) log ( 1 A [ 3 ] ) \mathcal{L}(A^{[3]}, \hat Y) = - A^{[3]}\log(A^{[3]}) - (1-\hat Y ) \log(1-A^{[3]})\tag{7}

The cost is then computed by summing over all training examples:
(8) J = 1 m i = 1 m L ( A ( i ) [ 3 ] , Y ( i ) ) J = \frac{1}{m} \sum_{i=1}^m \mathcal{L}(A^{(i)[3]}, Y^{(i)})\tag{8}

反向傳播基本公式:
(1) d A [ 3 ] = L A [ 3 ] = 1 Y ^ 1 A [ 3 ] Y ^ A [ 3 ] dA^{[3]}= \frac{\partial \mathcal{L}}{\partial A^{[3]}}= \frac{1-\hat Y}{1-A^{[3]}}-\frac{\hat Y}{A^{[3]}}\tag{1}
(2) d Z [ 3 ] = L A [ 3 ] A [ 3 ] Z [ 3 ] = d A [ 3 ] A [ 3 ] ( 1 A [ 3 ] ) dZ^{[3]}=\frac{\partial \mathcal{L}}{\partial A^{[3]}}*\frac{\partial A^{[3]} }{\partial Z^{[3]}}=dA[3]*A^{[3]}*(1-A^{[3]})\tag{2}