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

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

Neural Network Learning

  • 初始化 \(w_{ij}^{(l)}\)
    • 需為隨機且比較小的值
  • for \(t=0,1,\cdots, T\)
    1. stochastic:隨機挑選 \(n \in \left \{ 1,2,\cdots ,N \right \}\)
    2. forward:用 \(\mathbf{x}^{(0)}=\mathbf{x}_n\) 計算所有的 \(x_i^{(l)}\)
    3. backward:基於 \(\mathbf{x}^{(0)}=\mathbf{x}_n\) 計算所有的 \(\delta _j^{(l)}\)
    4. gradient descent:\(w_{ij}^{(l)}\leftarrow w_{ij}^{(l)}-\eta x_i^{(l-1)}\delta _j^{(l)}\)
  • 回傳 \(g_{NNet}(\mathbf{x})=\left (\cdots  \mathrm{tanh}\left ( \sum _j w_{jk}^{(2)}\cdot \mathrm{tanh}(\sum _i w_{ij}^{(1)}x_i) \right ) \right )\)
  • 1. 到 3. 可重覆做很多次(可平行處理),再將其結果 \(x_i^{(l-1)}\delta _j^{(l)}\) 平均後,放置 4. 執行,這種做法稱為 mini-batch
$$ \delta _1^{(L)}=-2\left (y_n-s_1^{(L)} \right ) $$ $$ \begin{align*} \delta _j^{(l)} = \frac{\partial e_n}{\partial s_j^{(l)}} &= \sum_{k=1}^{d^{(l+1)}}\left ( \delta _k^{(l+1)} \right )\cdot \left ( w_{jk}^{(l+1)} \right )\cdot \left ( {\mathrm{tanh}}'\left ( s_j^{(l)} \right ) \right )\\ &= \sum_{k=1}^{d^{(l+1)}}\left ( \delta _k^{(l+1)} \right )\cdot \left ( w_{jk}^{(l+1)} \right )\cdot \left ( 1-{\mathrm{tanh}}^2\left ( s_j^{(l)} \right ) \right )\\ \end{align*} $$
一開始的想法啟發自大腦神經元的組成
若將一個 perceptrons 當作一個神經元,並將之連結起來輸出結果
$$ G(\mathbf{x})=sign\left ( \sum_{t=1}^{T}\alpha_t \cdot \underset{g_t(\mathbf{x})}{\underbrace{sign(w_t^T\mathbf{x})}} \right ) $$ 如下圖,一個 AND 的 model 只需兩層的架構, OR 和 NOT 也是如此

足夠多的 perceptrons 甚至可以形成一個圓,此為 convex set 所以 \(d_{VC}\rightarrow \infty\)
overfittiing 需注意,可參考 [ML] 機器學習基石:第五講 Training versus Testing
但兩層的架構,是做不到 XOR 的,若將第一層視為特徵轉換 \(\Phi (\mathbf{x})=(g_1(\mathbf{x}),g_2(\mathbf{x}))\)
如下圖,可以看到是無法 linear separable
但也許可以再多個一層,XOR(\(g_1\), \(g_2\)) = OR( AND(\(-g_1\), \(g_2\)), AND(\(g_1\) , \(-g_2\)) )
所以越多層的類神經越強大,但務必小心 overfitting
而最後的輸出,就是一個簡單的 linear model,先前學過的皆可應用於此
在此,只探討 linear regression,事實上其餘的是大同小異的
但中間過程的 sign function 是否可被替換呢?畢竟這不是個簡單能被最佳化的函式
若是 linear 的,也就是不做任何處理,同 linear regression
這麼做沒什麼太大幫助,線性組合再線性組合,最後其實等同一個線性組合,根本不用這麼多層
目前常用的是
$$ \mathrm{tanh}(s)=\frac{e^s-e^{-s}}{e^s+e^{-s}}=2\theta (2s)-1 $$ 等同於 logistic regression 做放縮再平移的動作,也比較接近原先的 sign,易於被最佳化
首先,先定義名詞
\(L\) 表示最後輸出層,在此為 \(L=3\),0 表示最開始的輸入層
model 會以每層的神經元數目命名,但不含常數項,且第 0 層即為本身的 \(\mathbf{x}\) 數目
\(d^{(0)}-d^{(1)}-d^{(2)}-\cdots -d^{(L)}\),如圖也就是 d-3-4-1 Neural Network (NNet)
而 \(w_{ij}^{(l)}\) 如下,\(i\) 表第幾個輸入,\(j\) 表第幾個輸出,\(l\) 表第幾層
$$ w_{ij}^{(l)}: \left\{\begin{matrix} 1 \le l \le L & layers\\ 0 \le i \le d^{(l-1)} & inputs\\ 1 \le j \le d^{(l)} & outputs \end{matrix}\right. $$ 舉個例子,若為 3-5-1 NNet,則有 \((3+1)*5=20\) 個 \(w_{ij}^{(1)}\) + \((5+1)*1=6\) 個 \(w_{jk}^{(2)}\)
共 26 個 \(\left \{ w_{ij}^{(l)} \right \}\)
score 即是 tanh 前的輸入,線性組合後的結果,而 \(\mathbf{x}\) 即為 tanh 後的輸出
$$ \begin{align*} s_j^{(l)}&=\sum_{i=0}^{d^{(l-1)}}w_{ij}^{(l)}x_i^{(l-1)}\\ &= \begin{bmatrix} w_{0j}^{(l)} & w_{1j}^{(l)} & \cdots & w_{d^{(t-1)}j}^{(l)}\\ \end{bmatrix} \begin{bmatrix} 1\\ x_1^{(l-1)}\\ \vdots \\ x_{d^{(l-1)}}^{(l-1)} \end{bmatrix}\\ &= \left (\mathbf{w}_{j}^{(l)} \right )^T\mathbf{x}^{(l-1)}\\ \\ \mathbf{x}_j^{(l)}&=\left\{\begin{matrix} \mathrm{tanh}(s_j^{(l)}) & if\ l < L\\ s_j^{(l)} & if\ l=L \end{matrix}\right. \end{align*} $$ 除了最開始的 input layer \(\mathbf{x}^{(0)}\) 與最後的 output layer \(x_1^{(L)}\),剩下的皆稱為 hidden layers
如何讓 tanh 往兩邊跑呢?
即是 \(\mathbf{w}^{(l)}\) 與輸入近乎平行時,可視為取出與 \(\mathbf{w}^{(l)}\) 平行的 pattern,看其相似度有多高,越高的分數越高
所以 NNet 是一種 pattern extraction,利用各個層的 weights 取出 pattern
如下圖,第一層的轉換為萃取出特定的筆畫,當有存在特定筆畫時,相似度越高分數越高,再依此決定是 1 還是 5

現在有了 model,那該如何學習呢?
因是 linear regression,所以
$$ \begin{align*} e_n &= (y_n-\mathrm{NNet}(\mathbf{x}_n))^2\\ &= (y_n-s_1^{(L)})^2\\ &= \left ( y_n-\sum_{i=0}^{d^{(L-1)}}w_{i1}^{(L)}x_i^{(L-1)} \right )^2 \end{align*} $$ 利用 (stochastic) GD 計算 \(\frac{\partial e_n}{\partial w_{ij}^{(l)}}\)
可參考 [ML] 機器學習基石:第十一講 Linear Models for Classification
先針對 \(L\) 層,也就是 output layer 計算
$$ \begin{align*} \frac{\partial e_n}{\partial w_{i1}^{(L)}} &= \frac{\partial e_n}{\partial s_1^{(L)}} \cdot \frac{\partial s_1^{(L)}}{\partial w_{i1}^{(L)}}\\ &= -2\left (y_n-s_1^{(L)} \right )\cdot \left (x_i^{(L-1)} \right )\\ &= \delta _1^{(L)}\cdot \left (x_i^{(L-1)} \right )\\ \end{align*} $$ 那麼其他層呢?
$$ \begin{align*} \frac{\partial e_n}{\partial w_{ij}^{(l)}} &= \frac{\partial e_n}{\partial s_j^{(l)}} \cdot \frac{\partial s_j^{(l)}}{\partial w_{ij}^{(l)}}\\ &= \delta _j^{(l)}\cdot \left (x_i^{(l-1)} \right )\\ \end{align*} $$ \(\delta _j^{(l)}\) 看起來不怎麼好解,先換個角度來看
\(s_j^{(l)}\) 經 tanh 轉換會成為 \(x_j^{(l)}\),然後再乘上對應的 \(w_{jk}^{(l+1)}\) 會成為 \(s_k^{(l+1)}\)
$$ s_j^{(l)}\overset{\mathrm{tanh}}{\Rightarrow } x_j^{(l)}\overset{w_{jk}^{(l+1)}}{\Rightarrow} \begin{bmatrix} s_1^{(l+1)}\\ s_2^{(l+1)}\\ \vdots \\ s_k^{(l+1)}\\ \vdots \\ s_{d^{(l+1)}}^{(l+1)}\\ \end{bmatrix}\Rightarrow \cdots \Rightarrow e_n $$ 並根據全微分,所以
$$ \begin{align*} \delta _j^{(l)} &= \frac{\partial e_n}{\partial s_j^{(l)}}\\ &= \frac{\partial e_n(s_1^{(l+1)},s_2^{(l+1)},\cdots ,s_{d^{(l+1)}}^{(l+1)})}{\partial s_j^{(l)}}\\ [\because Total\ derivative] &= \sum_{k=1}^{d^{(l+1)}}\frac{\partial e_n}{\partial s_k^{(l+1)}}\cdot \frac{\partial s_k^{(l+1)}}{\partial s_j^{(l)}}\\ &= \sum_{k=1}^{d^{(l+1)}}\frac{\partial e_n}{\partial s_k^{(l+1)}}\cdot \frac{\partial s_k^{(l+1)}}{\partial x_j^{(l)}}\cdot \frac{\partial x_j^{(l)}}{\partial s_j^{(l)}}\\ &= \sum_{k=1}^{d^{(l+1)}}\left ( \delta _k^{(l+1)} \right )\cdot \left ( w_{jk}^{(l+1)} \right )\cdot \left ( {\mathrm{tanh}}'\left ( s_j^{(l)} \right ) \right )\\ &= \sum_{k=1}^{d^{(l+1)}}\left ( \delta _k^{(l+1)} \right )\cdot \left ( w_{jk}^{(l+1)} \right )\cdot \left ( 1-{\mathrm{tanh}}^2\left ( s_j^{(l)} \right ) \right )\\ \end{align*} $$ 從上式可看出 \(\delta _j^{(l)}\) 可從 \(\delta _k^{(l+1)}\) 得到,依此往前推,這也是 Backpropagation 的由來
所以可以從第 \(L\) 層逐步往前推至第 1 層的 \(\delta _j^{(l)}\)

$$ \begin{align*} w_{ij}^{(l)}&\leftarrow w_{ij}^{(l)}-\eta \frac{\partial e_n}{\partial w_{ij}^{(l)}}\\ w_{ij}^{(l)}&\leftarrow w_{ij}^{(l)}-\eta x_i^{(l-1)}\delta _j^{(l)} \end{align*} $$ 何時不會更新 \(w_{ij}^{(l)}\) 呢?
$$ \frac{\partial e_n}{\partial w_{i1}^{(L)}}=0=\delta _1^{(L)}\cdot \left (x_i^{(L-1)} \right )=-2\left (y_n-s_1^{(L)} \right )\cdot \left (x_i^{(L-1)} \right ) $$ 也就是
  • \(y_n=s_1^{(L)}\) 
  • \(x_i^{(L-1)}=0\)
  •  \(s_i^{(L-1)}=0\)

Optimization and Regularization

$$ E_{in}(\mathbf{w})=\frac{1}{N}\sum_{n=1}^{N}err\left ( \left (\cdots \mathrm{tanh}\left ( \sum _j w_{jk}^{(2)}\cdot \mathrm{tanh}(\sum _i w_{ij}^{(1)}x_{n,i}) \right ) \right ),y_n \right ) $$
  • 當具有多層 hidden layers,通常為 non-convex
    • 難以得到 global minimum
    • GD/SGD 只能得到 local minimum
    • 在實務上還是有不錯的表現
  • 不同的 \(w_{ij}^{(l)}\) 初始值,可能會得到不同的 local minimum
    • \(w_{ij}^{(l)}\) 太大,會使得 \({\mathrm{tanh}}(s_j^{(l)})\) 遠離中心,導致 \({\mathrm{tanh}}'\left ( s_j^{(l)} \right )\) 太小
      每次的移動將非常小,稱作 saturate (飽和)
  • \(d_{VC}=O(VD)\)
    • \(V\):神經元的個數
    • \(D\):weights 的個數
    • 優點
      • 足夠的 \(V\) 可近似任何函數
    • 缺點
      • 太多 \(V\) 容易 overfit 
  • Regularization \(e_{in}(\mathbf{w})+\Omega (\mathbf{w})\)
    • L2
      • \(\Omega (\mathbf{w})=\sum \left (w_{ij}^{(l)}  \right )^2\)
      • \(e_{in}(\mathbf{w})+\Omega (\mathbf{w})=e_{in}(\mathbf{w})+\sum \left (w_{ij}^{(l)}  \right )^2\)
      • \(\frac{\partial (e_{in}(\mathbf{w})+\Omega (\mathbf{w}))}{\partial w_{ij}^{(l)}}=\delta _j^{(l)}\cdot \left (x_i^{(l-1)} \right )+2 \cdot  \left (w_{ij}^{(l)}  \right )\)
      • 從上式得知,large weight → large shrink; small weight → small shrink
        但這並無法令 \(w_{ij}^{(l)} =0\),當 \(w_{ij}^{(l)} =0\) 才能降低 \(d_{VC}\),也就是 \(d_{VC}=O(VD)\) 的 \(D\)
    • L1
      • \(\Omega (\mathbf{w})=\sum \left |w_{ij}^{(l)}  \right |\)
      • \(e_{in}(\mathbf{w})+\Omega (\mathbf{w})=e_{in}(\mathbf{w})+\sum \left |w_{ij}^{(l)}  \right |\)
      • 可得到 \(w_{ij}^{(l)} =0\),因其頂點解的緣故
        可參考 [ML] 機器學習基石:第十四講 Regularization
      • 但無法微分,這會導致 backprop 無法求解
    • weight-elimination
      • \(\Omega (\mathbf{w})=\sum \frac{\left (w_{ij}^{(l)}  \right )^2}{1+\left (w_{ij}^{(l)}  \right )^2}\)
      • \(e_{in}(\mathbf{w})+\Omega (\mathbf{w})=e_{in}(\mathbf{w})+\sum \frac{\left (w_{ij}^{(l)}  \right )^2}{1+\left (w_{ij}^{(l)}  \right )^2}\)
      • \(\frac{\partial (e_{in}(\mathbf{w})+\Omega (\mathbf{w}))}{\partial w_{ij}^{(l)}}=\delta _j^{(l)}\cdot \left (x_i^{(l-1)} \right )+\frac{2w_{ij}^{(l)}}{\left ( 1+\left (w_{ij}^{(l)}  \right )^2 \right )^2}\)
      • large weight → median shrink; small weight → median shrink
        將可以令 \(w_{ij}^{(l)} =0\),但前提是範圍需正確 \(-4<w_{ij}<-4\)
        假設前項 \(\delta _j^{(l)}\cdot \left (x_i^{(l-1)} \right )\approx  0\),可畫出下圖


  • 減少 iteration 的次數

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

    程式碼

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

    參考

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

    留言