前言
筆者一直在ipad上做手寫筆記,最近突然想把筆記搬到博客上來,也就有了下面這些。因爲本是給自己看的筆記,所以內容很簡陋,只是提了一些要點。隨緣更新。
正文
step1 建立一個神經網絡模型
一個常見的神經網絡——完全連接前饋神經網絡
- 全連接:layer和layer之間兩兩連接
- 前饋傳遞方向由後向前,任意兩層之間沒有反饋
- 深度:許多隱含層
如此一層一層傳遞下去。
最普通的激活函數爲sigmoid函數
其圖像爲:
當然,現在已經很少使用sigmoid函數做激活函數了。本質
通過隱含層來代替原來的特徵工程,這樣最後一個隱含層輸出的就是一組新的特徵,然後通過一個多分類器(可以是函數)得到最後的輸出。因爲並不是每種數據都是結構化的,例如圖片、語音這種,這類數據是非結構的,人們很難通過各種特徵對其進行有效的特徵處理,所以傳統的機器學習在這種領域將不再適用。於是人們想出了這種通過一層層的隱含層對其進行強制擬合的模型,稱之爲神經網絡。
舉例:手寫識別
step2 模型評估
對於神經網絡,我們採用交叉熵來對 和 的損失進行計算。(後期我將在生成模型和判別模型中對他進行詳細的描述)
step3 最佳模型——梯度下降
(反向傳播,也就是所謂的)在神經網絡中是一種有效的方式計算的方式,我們可以利用很多框架進行計算,如:TensorFlow,Pytorch。
反向傳播()
是總體損失函數,是單個樣本產生的誤差。
計算,只需要計算。
我們取出一個神經元進行分析
易得:
Forward Pass :
這裏我可以很輕鬆看出爲上一隱含層輸出的值。
Backward Pass :
這時候我們會覺得每計算一次梯度相當麻煩,每個參數的梯度都需要層層往後計算,計算量大到無法想象。實際上進行Backward Pass和向前傳播的計算量差不多,我們只需將我們的思維逆轉一下,從最後一層往前計算,也能計算出所有參數的梯度,這時的計算量是線性的,這就是 的思想(個人爲很類似於算法中的動態規劃)。
利用keras建立神經網絡
建立神經網絡的過程,別人以爲你在搞什麼特別深奧高大上的東西,其實你只是在搭積木一樣一層一層疊隱含層而已=。=
import keras
from keras.models import Sequential
from keras.layers import Dense
model = Sequential() # 建立一個模型
# 搭建網絡
'''@param
Dense: Fully connect layer
input_dim: 輸入層
units: 神經元
activation: 激活函數
'''
model.add(Dense(input_dim=10, units=500, activation='sigmoid')) # 建立一個神經網絡
# 再加一個隱含層
model.add(Dense(units=500, activation='sigmoid'))
# 輸出層
model.add(Dense(units=10, activation='softmax')) # 輸出向量長度爲10,激活函數爲softmax
# loss function
model.compile(loss='categotial_crossentropy', # 損失函數:交叉熵
optimizer='adam', # 優化器(都是梯度下降)
metrics=['accuracy'] # 指標
)
# batch_size: 將訓練集隨機分爲分爲幾個batch,每次計算隨機的一個
# 所有batch都計算一次,一個epoch結束
model.fit(x_train, y_train, batch_size=100, epochs=20)
# case1: 測試集正確率
score = model.evaluate(x_test, y_test)
print('Total loss on Test Set:', score[0])
print('Accuracy of Testing Set:', score[1])
# case 2:模型預測
result = model.predict(x_test)
深度學習的技巧
在test上如何改進:
新的激活函數
sigmoid缺點——梯度消失:
有時神經網絡層數越深,結果越差,原因可能是梯度消失,比較靠近input的幾層梯度很小,靠近output的幾層梯度較大,在前幾層還未怎麼更新參數時,後幾層已經收斂。因爲每經過一個sigmoid,的影響就會被消弱。
ReLU:
- 當 input > 0 時,output = input
- 當 input < 0 時,output = 0
在input < 0 時,相當於該節點被移除,整個網絡就是 a thinner linear network,如果時線性的話,梯度不會遞減。
你可能會說這個線性模型如何處理那些複雜的非線性模型,畢竟不是所有問題都和線性一樣美好,你要注意了我們這是deep learning,關鍵在於這個“deep”,這是一個有着數層幾千個神經元的網絡,它們疊加的效果就是一個非線性的模型,是一個很複雜的function。對於ReLU activation function的神經網絡,只是在小範圍內是線性的,在總體上還是非線性的。
好處:
- 比sigmoid處理起來快
- 無窮多的sigmoid疊加起來的結果(不同的bias)
- 可以處理梯度消失
變種:
-
Leaky ReLU
-
Parametric ReLU
Maxout —— 讓network自動學習的激活函數
方法:
- 先將輸入分組,如2個一組或3個一組
- 再從每一組中選擇最大的一個
下圖爲一個簡單的示例
原理:
其實上面介紹的ReLU爲一個特殊的Maxout,理論上Maxout可以擬合任何激活函數
比如下面這個ReLU可以由如此的Maxout得到
選擇不同的和可以做到
你可能會問這樣不就有的節點訓練不到了嗎?因爲有些節點的權值爲0等於從網絡中去除了。其實只是部分數據上此節點爲0,但是我們有大量數據,總有數據可以訓練到這個節點。所以 需要比 更大的數據量才能訓練好這個網絡。
更新學習速率
RMSProp
屬於之前在線性模型中提到的算法的變形
一個固定的learning rate除以一個(在第一個時間點,就是第一個算出來GD的值),在第二個時間點,你算出來一個和 (你可以去手動調一個值,把值調整的小一點,說明你傾向於相信新的gradient告訴你的這個error surface的平滑或者陡峭的程度)。
Momentum
參考了物理世界慣性的概念,遇到一個小山坡時可以通過慣性翻過,從而越過局部最優點。
在算法中只參考上一次的速度,因爲上一次的速度已經包含了之前所有的速度。
步驟:
- 選擇一個初始位置 和初始速度
- 計算在 處的梯度
- 如此往復
Adam
和的結合。有興趣的朋友直接看圖吧。
在train上改進(過擬合)
Early Stopping
我們需要的是測試集錯誤最小,而不是訓練集,如果測試集的Loss上升,則需要立刻停止訓練,但是如果將測試集加入訓練則會導致測試結果不客觀。這時我們可以引入驗證集來解決。當訓練時驗證集Loss上升則停止訓練。
Regularization
和線性模型一樣,我們需要在原來的加入正則化,讓得到的結果更加平滑。
常見的有(一次式)和(二次式)
Dropout
如何訓練
在訓練時的時候,每一次參數更新之前,對network裏面的每個神經元(包括輸入層),做採樣(sampling)。 每個神經元會有p%的可能性會被丟掉,跟着的 也會被丟掉。
解釋
你在訓練時,加上dropout,你會看到在訓練集上結果會變得有點差(因爲某些神經元不見了),但是dropout真正做的事就是讓你測試集越做越好。
假設有個神經元,就可以訓練 個神經網絡結構,每個網絡的偏差雖然很大,但是最後平均下來還是很準的(這個又要回到我們在線性模型中說的 和 問題)。
dropout其實是用了模型融合(model essemble)的思想,訓練了很多模型最後加權得到最終的結果。
在testing上注意兩件事情:
- 第一件事情就是在testing上不做dropout。
- 在dropout的時候,假設dropout rate在training是p%,all weights都要乘以
關於爲什麼要乘,舉一個簡單的例子:
總結
到此神經網絡已經介紹得差不多了,你可能會說,就這,就這?其實神經網絡也不是什麼深奧的東西,本質上就是一個有着數千個參數的模型,和最簡單的線性模型一樣,也是通過最常規的方法——梯度下降求解。當然,其中也涉及了一些挺玄學(只可意會,不可言傳,當然也是我的數學功底不夠,無法準確描述)的方法。
上一篇:機器學習筆記(1)——線性迴歸
下一篇:可能會講一講CNN或者神經網絡中神經元的來源——logistic迴歸(未開始寫=。=)
(如果覺得有用請點個贊吧)