[ML] 機器學習技法:第十二講 Neural Network

ML:基礎技法學習
Package:scikit-learn
課程:機器學習技法
簡介:第十二講 Neural Network

Neural Network Learning

  • 初始化 wij(l)
    • 需為隨機且比較小的值
  • for t=0,1,,T
    1. stochastic:隨機挑選 n{1,2,,N}
    2. forward:用 x(0)=xn 計算所有的 xi(l)
    3. backward:基於 x(0)=xn 計算所有的 δj(l)
    4. gradient descent:wij(l)wij(l)ηxi(l1)δj(l)
  • 回傳 gNNet(x)=(tanh(jwjk(2)tanh(iwij(1)xi)))
  • 1. 到 3. 可重覆做很多次(可平行處理),再將其結果 xi(l1)δj(l) 平均後,放置 4. 執行,這種做法稱為 mini-batch
δ1(L)=2(yns1(L)) δj(l)=ensj(l)=k=1d(l+1)(δk(l+1))(wjk(l+1))(tanh(sj(l)))=k=1d(l+1)(δk(l+1))(wjk(l+1))(1tanh2(sj(l)))
一開始的想法啟發自大腦神經元的組成
若將一個 perceptrons 當作一個神經元,並將之連結起來輸出結果
G(x)=sign(t=1Tαtsign(wtTx)gt(x)) 如下圖,一個 AND 的 model 只需兩層的架構, OR 和 NOT 也是如此

足夠多的 perceptrons 甚至可以形成一個圓,此為 convex set 所以 dVC
overfittiing 需注意,可參考 [ML] 機器學習基石:第五講 Training versus Testing
但兩層的架構,是做不到 XOR 的,若將第一層視為特徵轉換 Φ(x)=(g1(x),g2(x))
如下圖,可以看到是無法 linear separable
但也許可以再多個一層,XOR(g1, g2) = OR( AND(g1, g2), AND(g1 , g2) )
所以越多層的類神經越強大,但務必小心 overfitting
而最後的輸出,就是一個簡單的 linear model,先前學過的皆可應用於此
在此,只探討 linear regression,事實上其餘的是大同小異的
但中間過程的 sign function 是否可被替換呢?畢竟這不是個簡單能被最佳化的函式
若是 linear 的,也就是不做任何處理,同 linear regression
這麼做沒什麼太大幫助,線性組合再線性組合,最後其實等同一個線性組合,根本不用這麼多層
目前常用的是
tanh(s)=eseses+es=2θ(2s)1 等同於 logistic regression 做放縮再平移的動作,也比較接近原先的 sign,易於被最佳化
首先,先定義名詞
L 表示最後輸出層,在此為 L=3,0 表示最開始的輸入層
model 會以每層的神經元數目命名,但不含常數項,且第 0 層即為本身的 x 數目
d(0)d(1)d(2)d(L),如圖也就是 d-3-4-1 Neural Network (NNet)
wij(l) 如下,i 表第幾個輸入,j 表第幾個輸出,l 表第幾層
wij(l):{1lLlayers0id(l1)inputs1jd(l)outputs 舉個例子,若為 3-5-1 NNet,則有 (3+1)5=20wij(1) + (5+1)1=6wjk(2)
共 26 個 {wij(l)}
score 即是 tanh 前的輸入,線性組合後的結果,而 x 即為 tanh 後的輸出
sj(l)=i=0d(l1)wij(l)xi(l1)=[w0j(l)w1j(l)wd(t1)j(l)][1x1(l1)xd(l1)(l1)]=(wj(l))Tx(l1)xj(l)={tanh(sj(l))if l<Lsj(l)if l=L 除了最開始的 input layer x(0) 與最後的 output layer x1(L),剩下的皆稱為 hidden layers
如何讓 tanh 往兩邊跑呢?
即是 w(l) 與輸入近乎平行時,可視為取出與 w(l) 平行的 pattern,看其相似度有多高,越高的分數越高
所以 NNet 是一種 pattern extraction,利用各個層的 weights 取出 pattern
如下圖,第一層的轉換為萃取出特定的筆畫,當有存在特定筆畫時,相似度越高分數越高,再依此決定是 1 還是 5

現在有了 model,那該如何學習呢?
因是 linear regression,所以
en=(ynNNet(xn))2=(yns1(L))2=(yni=0d(L1)wi1(L)xi(L1))2 利用 (stochastic) GD 計算 enwij(l)
可參考 [ML] 機器學習基石:第十一講 Linear Models for Classification
先針對 L 層,也就是 output layer 計算
enwi1(L)=ens1(L)s1(L)wi1(L)=2(yns1(L))(xi(L1))=δ1(L)(xi(L1)) 那麼其他層呢?
enwij(l)=ensj(l)sj(l)wij(l)=δj(l)(xi(l1)) δj(l) 看起來不怎麼好解,先換個角度來看
sj(l) 經 tanh 轉換會成為 xj(l),然後再乘上對應的 wjk(l+1) 會成為 sk(l+1)
sj(l)tanhxj(l)wjk(l+1)[s1(l+1)s2(l+1)sk(l+1)sd(l+1)(l+1)]en 並根據全微分,所以
δj(l)=ensj(l)=en(s1(l+1),s2(l+1),,sd(l+1)(l+1))sj(l)[Total derivative]=k=1d(l+1)ensk(l+1)sk(l+1)sj(l)=k=1d(l+1)ensk(l+1)sk(l+1)xj(l)xj(l)sj(l)=k=1d(l+1)(δk(l+1))(wjk(l+1))(tanh(sj(l)))=k=1d(l+1)(δk(l+1))(wjk(l+1))(1tanh2(sj(l))) 從上式可看出 δj(l) 可從 δk(l+1) 得到,依此往前推,這也是 Backpropagation 的由來
所以可以從第 L 層逐步往前推至第 1 層的 δj(l)

wij(l)wij(l)ηenwij(l)wij(l)wij(l)ηxi(l1)δj(l) 何時不會更新 wij(l) 呢?
enwi1(L)=0=δ1(L)(xi(L1))=2(yns1(L))(xi(L1)) 也就是
  • yn=s1(L) 
  • xi(L1)=0
  •  si(L1)=0

Optimization and Regularization

Ein(w)=1Nn=1Nerr((tanh(jwjk(2)tanh(iwij(1)xn,i))),yn)
  • 當具有多層 hidden layers,通常為 non-convex
    • 難以得到 global minimum
    • GD/SGD 只能得到 local minimum
    • 在實務上還是有不錯的表現
  • 不同的 wij(l) 初始值,可能會得到不同的 local minimum
    • wij(l) 太大,會使得 tanh(sj(l)) 遠離中心,導致 tanh(sj(l)) 太小
      每次的移動將非常小,稱作 saturate (飽和)
  • dVC=O(VD)
    • V:神經元的個數
    • D:weights 的個數
    • 優點
      • 足夠的 V 可近似任何函數
    • 缺點
      • 太多 V 容易 overfit 
  • Regularization ein(w)+Ω(w)
    • L2
      • Ω(w)=(wij(l))2
      • ein(w)+Ω(w)=ein(w)+(wij(l))2
      • (ein(w)+Ω(w))wij(l)=δj(l)(xi(l1))+2(wij(l))
      • 從上式得知,large weight → large shrink; small weight → small shrink
        但這並無法令 wij(l)=0,當 wij(l)=0 才能降低 dVC,也就是 dVC=O(VD)D
    • L1
      • Ω(w)=|wij(l)|
    • weight-elimination
      • Ω(w)=(wij(l))21+(wij(l))2
      • ein(w)+Ω(w)=ein(w)+(wij(l))21+(wij(l))2
      • (ein(w)+Ω(w))wij(l)=δj(l)(xi(l1))+2wij(l)(1+(wij(l))2)2
      • large weight → median shrink; small weight → median shrink
        將可以令 wij(l)=0,但前提是範圍需正確 4<wij<4
        假設前項 δj(l)(xi(l1))0,可畫出下圖


  • 減少 iteration 的次數

    • early stopping:gradient 有關的演算法皆可應用此方式 
    • 從某個角度來看,當做越多次,看過的 w 就越多,那麼有效的 dVC 也就越大
    • 可用 validation 決定 T,可參考 [ML] 機器學習基石:第十五講 Validation 

    程式碼

    第一層 weights 的 pattern
    1. import matplotlib.pyplot as plt
    2. from sklearn.datasets import fetch_mldata
    3. from sklearn.neural_network import MLPClassifier
    4.  
    5. # 手寫辨識資料 28x28 大小
    6. mnist = fetch_mldata("MNIST original", data_home='.')
    7. # 重新 scale data,至 0~1 之間
    8. X, y = mnist.data / 255., mnist.target
    9. # 分割資料為 訓練和測試
    10. X_train, X_test = X[:60000], X[60000:]
    11. y_train, y_test = y[:60000], y[60000:]
    12.  
    13. # 此為 28x28-16-5-1 NNet
    14. # 最大 iteration =10
    15. # alpha 為 regularizaion 的參數,也就是 Ein + alpha * L2
    16. # solver 設為 SGD
    17. # verbose 印出訓練過程
    18. # tol 每次最小需改進的 loss
    19. # learning_rate_init 也就是 step 的大小,learning_rate="constant" 是固定的
    20. # 隱藏層的 activation 使用 tanh
    21. mlp = MLPClassifier(hidden_layer_sizes=(16,5), max_iter=10, alpha=1e-4,
    22. solver='sgd', verbose=True, tol=1e-4, random_state=1,
    23. learning_rate_init=0.1, learning_rate="constant", activation='tanh')
    24.  
    25. mlp.fit(X_train, y_train)
    26. print("Training set score: %f" % mlp.score(X_train, y_train))
    27. print("Test set score: %f" % mlp.score(X_test, y_test))
    28.  
    29. fig, axes = plt.subplots(4, 4)
    30. # 取出第一層 weights 的最大值和最小值
    31. vmin, vmax = mlp.coefs_[0].min(), mlp.coefs_[0].max()
    32. for coef, ax in zip(mlp.coefs_[0].T, axes.ravel()):
    33. # 畫圖,並設定其最小值與最大值
    34. ax.matshow(coef.reshape(28, 28), cmap=plt.cm.gray, vmin=0.5 * vmin, vmax=0.5 * vmax)
    35. ax.set_xticks(())
    36. ax.set_yticks(())
    37.  
    38. plt.show()

    參考

    Neural network models (supervised)
    sklearn.neural_network.MLPClassifier
    sklearn.neural_network.MLPRegressor

    留言