- 連續感知器
- 非線性模型
- 神經網路結構
- 前向回饋
- 反向傳播
- Keras
- Keras Lab - 錄取學生
- 訓練優化
- 早期停止
- 正則化
- Dropout
- 局部最低點
- 隨機重新開始
- 動量
- 梯度消失
- 其他激活函數
- 批次與隨機梯度下降
- 學習速率衰退
- Keras中的優化程序
- 已知的誤差函數
- 神經網路回歸
- 嘗試神經網路
- Keras Lab - IMDB數據
- 簡短的回憶之前學到感知器。
- 藍色區域點是藍色的機率較大。
- 紅色區域點是紅色的機率比較大。
- 將weight跟feature抽離變成感知器模型。
- 非線性數據: 無法用單純的直線分割資料。
- 對於這樣的非線性數據,如何透過神經網路構造出一個機率函數。
- 讓藍色區域點是藍色的機率較大。
- 讓紅色區域點是紅色的機率比較大。
- 如何透過神經網路構造出一個機率函數
- 對現有的線性模型再進行一次線性組合,得到複雜的新模型。
-
- 將兩個線性模型轉化成感知器架構。
-
- 對現有的線性模型再進行一次線性組合。
-
- 另外一種相同表示方式,將bias抽離。
- 基本三層:input, hidden, output。
- 變化型1: hidden layer中的模型增加。
- 變化型3: input layer中的feature增加。
- 變化型4: out layer中的output增加。
- 變化型5: hidden layer中的layer增加。
- 深度神經網路完整結構。
- 透過softmax函數來進行多類別分類。
- Feedfoward: 神經網路用來將輸入變成輸出的流程。
- 單層hidden layer的數學表達。
- 多層hidden layer的數學表達。
-
神經網路仍會產生誤差函數,最終我們必須透過不斷的降低誤差來優化神經網路。
-
單層hidden layer的誤差函數。
- 跟之前學的linear regression中的誤差函數是一樣。
- 因為神經網路的每一層的運作,就是將上一層的輸出進行線性組合在輸出。
- 因為都是進行線性組合,所以誤差函數就是linear regression中的誤差函數表達一樣。
- 多層hidden layer的誤差函數。
- 不管層數再多,誤差函數仍是相同的定義(因為每一層都是進行線性組合),唯一的變化是誤差函數中y^越來越複雜。
-
Backpropgation: 用來訓練神經網路的一個流程。
- 先進行feedward。
- 將模型的輸出與期望的輸出做比較。
- 計算誤差。
- 向後進行反向傳播,將誤差分散到每個權重上。
- 更新權重,並獲得更好的模型。
- 反覆持續這樣的流程,直到獲得我們需求的模型。
-
例子: 由下方的圖觀察,最終模型是誤判了(x1,x2)這個點,我們期望他是藍點,但模型預測他在紅色邊界內。觀察前一層的輸入,發現前一層下方的模型是判斷正確,所以要做的就是調大下方正確模型的權重,調降上方錯誤模型的權重。
- 先回顧最簡單的模型,沒有任何的hidden layer,也就是linear regression。
- 多層hidden layer。
- y^的產生方式變複雜。
- Error function仍不變。
- gradient的目標就是把error分散到圖形中每條邊上。
- 一層hidden layer為例子。
- 目標就是計算出所有的W對E的微分。
- 對複合函數求導數,就是一系列導數的乘積。
- 神經網路的前向回饋就是進行一系列的複合函數的運算,因此鏈式法則剛好用來幫助我們處理反向傳播。
- 前向回饋就是進行一系列的複合函數的運算。
- 如何透過鏈式法則,計算出每條邊應該得到的誤差。
- 放大細看最後一層。
- Backpropagation 算法的推导与直观图解
- Backpropagation Algorithm
- A Step by Step Backpropagation Example
- simple-neural-network
- 序列模型:
- keras.models.Sequential 类是神经网络模型的封装容器。它会提供常见的函数,例如 fit()、evaluate() 和 compile()。
from keras.models import Sequential
#Create the Sequential model
model = Sequential()
- 层:
- Keras 层就像神经网络层。有全连接层、最大池化层和激活层。你可以使用模型的 add() 函数添加层。
- 上面的第一层 model.add(Dense(input_dim=32)) 将维度设为 32(表示数据来自 32 维空间)。第二层级获取第一层级的输出,并将输出维度设为 128 个节点。这种将输出传递给下一层级的链继续下去,直到最后一个层级(即模型的输出)。可以看出输出维度是 10。
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Flatten
#创建序列模型
model = Sequential()
#第一层 - 添加有128个节点的全连接层以及32个节点的输入层
model.add(Dense(128, input_dim=32))
#第二层 - 添加 softmax 激活层
model.add(Activation('softmax'))
#第三层 - 添加全连接层
model.add(Dense(10))
#第四层 - 添加 Sigmoid 激活层
model.add(Activation('sigmoid'))
- 构建好模型后,我们就可以用以下命令对其进行编译。我们将损失函数指定为我们一直处理的 categorical_crossentropy。我们还可以指定优化程序,稍后我们将了解这一概念,暂时将使用 adam。最后,我们可以指定评估模型用到的指标。我们将使用准确率。
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics = ['accuracy'])
- 我们可以使用以下命令来查看模型架构:
model.summary()
-
使用以下命令对其进行拟合,指定 epoch 次数和我们希望在屏幕上显示的信息详细程度。然后使用fit命令训练模型并通过 epoch 参数来指定训练轮数(周期),每 epoch 完成对整数据集的一次遍历。 verbose 参数可以指定显示训练过程信息类型,这里定义为 0 表示不显示信息。
-
注意:在 Keras 1 中,nb_epoch 会设置 epoch 次数,但是在 Keras 2 中,变成了 epochs。
model.fit(X, y, nb_epoch=1000, verbose=0)
- 最后,我们可以使用以下命令来评估模型:
model.evaluate()
- 在訓練過程常常會發現結果並未預期的好,原因?
- 所選的結構可能不合適。
- 數據太多瑕疵。
- 另外一種主要原因,數據訓練可能需要很久的時間,但我們希望可以運行更快,所以要進行優化,可以讓模型在最短的時間達到最佳的效果。
- 觀察不同的epoh的training跟test error的變化。
- Model Complexity Graph
- 將上面觀察到變化,轉成underfitting, just right跟overfitting的概念。
- Early Stop: 就是在測試誤差停止降低,並開始變大時,我們就停止訓練
- 問題: 兩個模型的prediction function只有差在係數大小不同,那麼哪個模型是產生較小的誤差?
- 答案: 因為sigmoid的因素,係數大的模型產生的誤差較小,但真的這樣模型就是較佳的模型嗎?
- 這樣的模型並不是好的模型,因為overfitting了
- 從數學角度來看:
- 係數小(左邊)
- 在執行梯度下降時,有較好的斜率
- 係數大(右邊)
- 梯度下降會變得沒什麼效用,雖然sigmoid的函數更快靠近0,1,相對導數也接近0,在梯度變化區域非常陡峭的地方,導數會變得非常大。
- 因為右邊的模型太過於穩定,很難使用梯度下降法,所以為了可以合理使用梯度下降法,我們會偏向使用左邊的模型。
- 係數小(左邊)
- 正則化: 就是要避免上面的問題,因為太大的係數容易遇到overfitting。
- 但由於較大的係數可以產生較小的誤差,所以要再error function上做些修正,而這個修正就是正則化。
-
正則化的核心思想:
- 越複雜的係數,可以降低原本error function的誤差,但相對會提升L1, L2的值,因此機器在進行學習時,機器會想辦法再原本error function跟L1,L2的值之間取個平衡。
-
L1,L2的正則化差異: 這邊的解釋,比課堂得清楚
- L1: 使用 L1 的方法, 我们很可能得到的结果是只有 theta1 的特征被保留,所以很多人也用L1正规化来挑选对结果贡献最大的重要特征. 但是 L1 的结并不是稳定的. 比如用批数据训练, 每次批数据都会有稍稍不同的误差曲线。
- L2: 这种变动, 白点的移动不会太大, 而 L1的白点则可能跳到许多不同的地方 , 因为这些地方的总误差都是差不多的. 侧面说明了 L1 解的不稳定性。
-
後來想想,似乎課堂上的說明也不差 !!
- L1: 因為是權重的絕對值相加。所以當有兩組不同的參數組(w1, w2) = (1, 0), (w1, w2) = (1, -1),L1會選擇(1, 0)因為產生的絕對值和較小。
- 所以L1會挑選出比較重要特徵,給他較大的權重。
- L2: 因為是權重的平方相加。所以當有兩組不同的參數組(w1, w2) = (1, 0), (w1, w2) = (0.5, 0.5),L2會選擇(0.5, 0.5)因為產生的平方和較小。
- 所以L2是盡可能平均優化每個權重,產生的模型也會比較穩定。
- L1: 因為是權重的絕對值相加。所以當有兩組不同的參數組(w1, w2) = (1, 0), (w1, w2) = (1, -1),L1會選擇(1, 0)因為產生的絕對值和較小。
- 有些網路的某個部份,權重非常大,最終對訓練起了主要作用,但有些部分,並沒有起到多大作用,所以都沒被訓練到。為了避免這樣狀況發生,於是有了dropout。
- dropout: 在固定次數的epoch後,就隨機移除某些node後,再繼續進行訓練,讓每個node都要機會被平均的訓練到。
- Gradient descent的盲點。無法透過Gradient descent來更近一步優化,必須透過其他方式。
- 要如何解決這個問題??
- 如何避免掉到局部最低點?那就是從幾個隨機的不同地點開始,對所有這些地點進行gradient descent,增大達到全局最低點的機率。
- 另外一個解決局部最低點的方法。
- Momentum
- 每次的步長都會參考之前的步長才來決定。
- 距離越久的步長,影響越小。
- 這樣的方式,可以幫助我們有機會翻過駝峰,增大達到全局最低點的機率。
- 觀察sigmoid的兩端導數幾乎趨近於0,這樣會影響到Gradient descent效率,因為Gradient descent就是透過導數來告訴我們移動的方向。
- 在深度神經網路中,更容易遇到這樣梯度消失的狀況。
- ex. 要求算是左邊的值,根據連鎖率,會轉換成右邊的一堆導數的乘積,而每一個導數又都是sigmoid函數,所以他們都很小,一堆很小的數字相乘,又變得更小。
- 意味著每次邁出的步伐都很小,如此一來就很難達到最佳值。
- 要如何解決這個問題??
-
透過其他激活函數來取代sigmoid,以避免深度神經網路中梯度消失的情況。
-
tanh: -1到1之間的導數比sigmoid大。
- ReLU: 如果值是正的,導數為1。
- 利用其他更好的激活函數,讓求導數乘積會變成更大的數字。
- epoch: 每次gradient descent跑完一次,更新所有權重一次,這就稱做一次epoch。
- Batch: 拿所有資料去跑gradient descent,再來更新所有權重。
- 缺點:每一次epoch的計算都相當費時。
- Stochastic: 將資料隨機分組,每次拿一組資料去跑gradient descent。
- 現實中,採取大量稍微不太準確的步長會比採取一步很準確的步長好很多。
- 學習速率太大會錯過最佳值。
- 學習速率太小會很久才會達到最佳值。
- 在陡峭的地方,學習速率就設大一點。
- 在平緩的地方,學習速率就設小一點。
- Keras 中有很多优化程序,建议你访问此链接或这篇精彩博文,详细了解这些优化程序。
- SGD: 这是随机梯度下降。它使用了以下参数:
- 学习速率。
- 动量(获取前几步的加权平均值,以便获得动量而不至于陷在局部最低点)。
- Nesterov 动量(当最接近解决方案时,它会减缓梯度)
- Adam: (Adaptive Moment Estimation)
- 使用更复杂的指数衰减,不仅仅会考虑平均值(第一个动量),并且会考虑前几步的方差(第二个动量)。
- RMSProp:(RMS 表示均方根误差)通过除以按指数衰减的平方梯度均值来减小学习速率。
- 是否可以將神經網路運用到回歸問題?
- 目前學到神經網路架構,最後透過sigmoid得到0~1的值,來處理分類問題的機率大小。
- 移除最後sigmoid拿到原本的值,就樣就可以處理回歸問題。
- 分別拿Relu跟sigmoid當作activation funciton,所得到得線性組合,可以用來處理不同回歸問題。