AI機器學習的BP黃金三公式

by 高煥堂 

misoo.tw@qq.com

2019_08_06

 

1. 記住第一個公式:delta = z * (1 - z) * error

 這項<BP算法黃金三公式>名稱是我提出的,幷不見得人人都贊同,但是它的確可以非常有效地簡化AI的教學與學生們的學習途徑。雖然看起來這些式子,如:delta = z * (1-z) * error,看來很複雜。其實,只要您不掉入數學推導的細節,它是非常簡單可愛的。其中,error就是預測值與實際值(標簽)的落差值。所以:

   delta = z * (1 - z) * error

   其中的z *(1-z)就是Sigmoid激活函數的導數。將它記住了之後,做些變化。例如,當激活函數改爲ReLU時,其導數爲1或0,此時,這個黃金公式就變成爲:

   delta = loss (或 0)

所以先記住: delta =  z * (1 - z) * error。就能隨著兩種變因而舉一反三了。其變因有二:1)損失函數(Loss Function);2)激活函數(Activation Function)。例如,最常見的損失函數是MSE(即均方誤差)或SSE(誤差平方和);而最常見的激活函數是Sigmoid函數。 

2.  逐漸孰悉它的變化:

   例如,改變一下,把損失函數改爲交叉熵時,這標準公式會變成什麽? 再如,改變一下,把激活函數改爲ReLU時,這標準公式會變成什麽? 然後,再改變一下,把激活函數改爲Softmax時,這標準公式會變成什麽? 如此,就很輕易地掌握NN的BP算法的任督之脉了。如此,一切變化盡在其中,就不必去糾纏于對損失函數的偏微分推倒細節了,也就是不必去糾纏于梯度向量的推算細節了,它們都在這簡單公式裡了。 

3. 就像牛頓力學的公式:F = ma

  這項 delta = z * (1 - z) * error 公式,就像幾何學裏的圓形面積公式:Area = PI * r^2 一樣,人人朗朗上口,也像牛頓力學的F = ma公式,或像愛因斯坦的 E = MC^2 質能變換公式一樣,記住它,活用它,然後才漸漸去理解它是如何導出的,甚至許多人一輩子也都不去煩惱它們是如何推導出來的。

4.  三個基本公式

  許多人都可以直接記住它、活用它,總共三個簡單公式:

  • 第1公式:delta =  z * (1 - z) * error
  • 第2公式:error_prev = W * delta
  • 3公式dw = X_prev * delta

  這三個公式如同牛頓力學三大定律公式。基于這項基礎知識,就能非常迅速地算出NN, CNN, RNN等神經網絡模型的AI機器學習流程了。 

5.  範例一:解析Python代碼

  例如,在我所撰寫的《Python 與TensorFlow結合》一書裡,有一段代碼:

for i in range(500):

    hy = x.dot(w1)

    hz = relu(hy)

    oy = hz.dot(w2)

    oz = sigmoid(oy)

 

    # Compute and print loss

    L = np.square(t - oz).sum()

    print(i, L)

 

    # Backprop to compute gradients of w1 and w2 with respect to loss

    error = t - oz

    delta = oz * (1-oz) * error

    dw2 = hz.T.dot(delta)

    error_h = delta.dot(w2.T)

    delta_h = error_h.copy()

    delta_h[h < 0] = 0

    dw1 = x.T.dot(delta_h)

 

    # Update weights

    w1 += learning_rate * dw1

    w2 += learning_rate * dw2

 

  這是兩層的NN模型,損失函數L()是SSE,隱藏層的激活函數是ReLU,輸出層則是Sigmoid激活函數。所以,

      delta = oz * (1-oz) * error

   和  delta_h = loss_h.copy()

      delta_h[h < 0] = 0

 

就是第一公式的呈現。至於,

       error_h = delta.dot(w2.T)

是第二公式的呈現。 再來,

       dw2 = hz.T.dot(delta)

       dw1 = x.T.dot(delta_h)

則是第三公式的呈現。

       w1 -= learning_rate * dw1

       w2 -= learning_rate * dw2

    幾乎所有複雜NN的BP算法,都是這三個簡單公式的華麗呈現而已。拿這三個公式去對應和詮釋別人的算法或程序代碼,就不必去追踪別人的程序邏輯,而一目了然。而且對或錯,一清二楚。

 

6.  範例二:解析Torch代碼

   再如,引用 :http://www.sohu.com/a/291959747_197042網頁裡提供的一份代碼: 

## sigmoid activation function using pytorch

def sigmoid_activation(z):

return 1 / (1 + torch.exp(-z))

 

## activation of hidden layer

z1 = torch.mm(x, w1) + b1

a1 = sigmoid_activation(z1)

 

## activation (output) of final layer

z2 = torch.mm(a1, w2) + b2

output = sigmoid_activation(z2)

loss = y - output

 

## function to calculate the derivative of activation

def sigmoid_delta(x):

return x * (1 - x)

 

## compute derivative of error terms

delta_output = sigmoid_delta(output)

delta_hidden = sigmoid_delta(a1)

 

## backpass the changes to previous layers

d_outp = delta_output * loss

loss_h = torch.mm(d_outp, w2.t())

d_hidn = delta_hidden * loss_h

 

learning_rate = 0.1

w2 += torch.mm(a1.t(), d_outp) * learning_rate

w1 += torch.mm(x.t(), d_hidn) * learning_rate

b2 += d_outp.sum() * learning_rate

b1 += d_hidn.sum() * learning_rate

 

其中的指令:

    d_outp = delta_output * loss

    d_hidn = delta_hidden * loss_h

就是第一公式的呈現。而,

    loss_h = torch.mm(d_outp, w2.t())

就是第二公式的呈現。再來,

    w2 += torch.mm(a1.t(), d_outp) * learning_rate

    w1 += torch.mm(x.t(), d_hidn) * learning_rat

就是第三公式的呈現。于是,三個基本公式就清晰地浮現出來了,也由于很孰悉這三個公式了,就很容易理解這些程序碼的涵意,也能輕易判斷程序是否正確。

 

7. 範例三:解析NN模型圖

    例如,有一個CNN模型的架構圖:

  

  基于已經熟悉的BP三公式,就清晰知道這些數字之間的相關性了。例如,此圖裡的藍色神經元屬於輸入層,綠色神經元屬於卷積層。目前已經知道了:

      delta_y0 = -0.1

     delta_y1 = 0.2

運用上述的<BP三公式>,就能反向推演出來delta_x0、delta_x1和delta_x2了。很容易展開如下的計算過程:

 

    這就是所謂的反向傳播(BP):讓敏感度(即 delta值),就如同海水的漣漪效應一般,從輸出層逆向傳播到各層,來更新權重值(含B值)

 

8. 結語

   學習AI的BP算法有兩個途徑:

途徑-1. 像牛頓一樣的科學家,會去用數學證明 F = ma。如果您是AI算法和模型的科學家,才需要懂微積分去證明AI算法裡的常用簡單公式。

途徑-2. 像一般的學生們的學習物理時,常先記住F=ma 或 E = MC^2的簡單公式,然後一邊應用,一邊領會,最後才去研讀牛頓F=ma的推導過程。

==> 返回首頁

~ End ~