# 吳恩達老師_深度學習_改善深度神經網路_第三週_超參數的調校
###### tags: `deep learning` `Andrew Ng` `改善深度神經網路`
## Tuning process
![](https://i.imgur.com/sRvxKFw.jpg)
**課程說明**:如何有效調校超參數
![](https://i.imgur.com/xJFKIwz.jpg)
訓練神經網路中不可避免的就是要調校參數,$\alpha、\beta、\beta_1,\beta_2,\epsilon、layer、hidden units、learning rate decay、mini batch$
其中,$\alpha$是最重要的超參數(紅框),其次是黃框的部份,最後是紫色框。
如果採用adam,一般不調校$\beta_1,\beta_2,\epsilon$
![](https://i.imgur.com/WyIfQrd.jpg)
假設有兩個超參數,傳統機器學習中,常見的作法是在網格中取樣點,然後系統性的研究這些數值,再以最佳效果做為參數。
但在深度學習中,建議作法是隨機取樣點,再以隨機樣點測試超參數的效果。
舉例來說,超參數1是$\alpha$,超參數2是$\epsilon$,這種情況下$\alpha$取值很重要,但是$\epsilon$卻無關緊要,這時候你試驗了5個$\alpha$值,這時候無論$\epsilon$取值為何,結果都是一樣的。
如果隨機取值,那你會有25個$\alpha$,無論如何這效果會較好,也探究了更多重要超參數的潛在值。
![](https://i.imgur.com/oPebRFU.jpg)
另一個調校慣例是由粗到精的策略,接上面案例,假如在右下角框處你找到了較好的參數,這時候作法是放大區域,再從裡面更密集的取值做測試。
## Using an appropriate scale to pick hyperparameters
![](https://i.imgur.com/Z0w4vnk.jpg)
**課程說明**:利用合適的範圍值探究超參數
![](https://i.imgur.com/HTxfElH.jpg)
上節所提的隨機並非亂數取值,而是利用合適的範圍值(scale)來探究超參數。
舉例來說,隱藏單元$n^{[l]}$=50...100或是隱藏層L=2-4,一個合理的範圍亂數取值。
但這方式對某些超參數不適用。
![](https://i.imgur.com/tEkk7iv.jpg)
學習效率$\alpha$=0.0001....1
如果利用隨機取值,那90%的機率落點會在0.1\~1之間,僅10%的機率落在0.0001\~0.1
這時候使用對數尺標的效果會較數值尺標來的好,所以設置上會調整為0.0001、0.001、0.01、0.1、1,並在對數軸上隨機取點。
在python中可以這麼做
```python=
r = -4 * np.random.rand()
alpha = 10 ** r
```
第1行:r的區間為\-4\~0
$log_{10}0.0001$=-4(最小值)
$log_{10}1$=0(最大值)
![](https://i.imgur.com/VdGLnrK.jpg)
另一個例子是對$\beta$取值,如果取值是在0.9~0.999,要記得,取0.9即代表取近十個單位的均值(上週課程的例子是十天),如果是0.999就是取近千個單位為均值,所以不能以線性軸取值,這是因為當$\beta$接近1時會對細微的變化變的很敏感。
換個角度從$(1-\beta)$來取值
跟上例一樣,$(1-\beta)$可以取0.1,0.01,0.001,就是$10^{-1}$~$10^{-3}$
$r \in [-3,-1]$
$1-\beta =10^r$
$\beta=1-10^r$
## Hyperparameters tuning in paractice Pandas vs Caviar
![](https://i.imgur.com/xplpDqh.jpg)
**課程說明**:如何有效組織超參數搜尋過程
![](https://i.imgur.com/GPX665n.jpg)
建議每幾個月就驗證確認超參數效果是否依然良好。
![](https://i.imgur.com/llO403a.jpg)
對於超參數的搜尋,大概有兩種思想流派。
一種是看著模型,通常擁有大數據,但沒有足夠的計算資源,可能只能建置一個模型,或是一小批模型。
這種情況下,可以以逐漸改良的方式來執行,第一天,可能初始化權重之後開始試驗,並觀察成本函數是否正確的下降,第二天就調整一下學習效率,第三天加入momentun或減少變量,每天觀察調整並且調整,這是在計算能力不足的情況下所能採取的作法。
另一種作法是同時試驗多種模型,可能設置了很多超參數就讓它自己運作了,同時的計算很多的不同超參數的模型,然後選擇最好的那一個。
第一種方式andrew稱為熊貓式,因為熊貓生的少,生了以後會細心照顧,第二種是魚式,就跟魚每次都會產很多卵一樣,但是並不會細心照料。
## Normalizing activations in a network
![](https://i.imgur.com/ypEOTjN.jpg)
**課程說明**:Batch Normalizaiton
![](https://i.imgur.com/WjZHW3o.jpg)
Batch Normalizaiton可能讓網格搜尋超參數的效果更好,也讓訓練神經網路更簡單。
以logistic為例,將資料集做歸一化可以加速學習過程(成本函數會從橢圓變圓)
* 計算均值
* $\mu=\frac{1}{m}\sum_ix^{(i)}$
* 減去均值
* $x=x-\mu$
* 計算方差(variances)
* $\sigma^2=\frac{1}{m}\sum x^{(i)2}$
* 以方差歸一化資料集
* $x=\frac{x}{\sigma^2}$
事實證明,這種方式在logistic上是有效果的,但是在更深的深度神經網路呢?
不僅擁有輸入的$a^{[0]}$,還有$a^{[1]}$、$a^{[2]}$...$a^{[L]}$,我們是否可以對a值做歸一化?
答案是可以的,這就是Batch Normalizaiton的作用,對$a^{[2]}$做歸一化來計算$W^{[3]},b^{[3]}$,嚴格來說是對$Z^{[2]}$做歸一化。
:::info
深度學習文獻中有爭議,究竟是對$a^{[2]}$,還是應該對$z^{[2]}$做歸一化。
:::
![](https://i.imgur.com/Y9zzTMe.jpg)
假設你有一些隱藏單元($z^{[l](i)}$),$z^{(1)}到z^{(m)}$
實作:
* 針對同一層$l$
* $\mu=\frac{1}{m}\sum_iz^{(i)}$
* $\sigma^2=\frac{1}{m}\sum_i(z_i-\mu)^2$
* $z^{(i)}_{norm}=\frac{z^{(i)-\mu}}{\sqrt{\sigma^2+\epsilon}}$
* 加入$\epsilon$是為了避免$\sigma$為0
這樣,我們就可以將z標準化,轉成均值為0和方差為1,但是我們不希望讓隱藏單元總是均值為0,方差為1,因為隱藏單元也許有不同的的分佈會有意義。
這時候我們可以利用另一個方式,反過來處理!!
$\check{z}^{(i)}=\gamma z^{(i)}_{norm}+\beta$
這邊的$\gamma$與$\beta$也都是模型的學習參數,所以在透過momentum或是adam做梯度下降的時候也會更新$\gamma$與$\beta$,正如更新神經網路的權重一樣。
$\gamma$與$\beta$的作用是,你可以隨意設置$\check{z}$的平均值與方差。
$\gamma=\sqrt{\sigma^2+\epsilon}$
$\beta=\mu$
如果成立的話,這時候$\check{z}^{(i)}=z^{(i)}$,也就是說,
$z^{(i)}=z^{(i)}_{norm}\sqrt{\sigma^2+\epsilon}+\mu=\gamma z^{(i)}_{norm}+\beta=\check{z}^{(i)}$,透過賦值$\gamma$、$\beta$你可以建置出含有其它平均值與方差的隱藏單元。
為了後續的計算,會以$\check{z}^{(i)}$來代替$z^{(i)}$
再次的說明,這是針對第$l$層的神經網路的計算,為了符號方便而沒放入$l$。
歸一化是對輸入特徵做縮放來提高神經網路的學習效率,而Batch norm不只是針對輸入層,包含了深度隱藏層。
這應用在你不希望隱藏單元值的平均與方差是1,假如你使用sigmoid函數,你不希望值限在一個區域內,希望可以拉大它的方差(如右下圖),避免所有的值都集中在線性區段中。
## Fitting Batch Norm into a neural network
![](https://i.imgur.com/xk4olQ2.jpg)
**課程說明**:將Batch Norm與深度神經網路的擬合
![](https://i.imgur.com/JgQp1TG.jpg)
假設你有一個模型(如上圖)
1. $X$(輸入層),透過權重參數計算$W^{[1]},b^{[1]}\rightarrow Z^{[1]}$
2. **進行Batch Norm(BN)**
3. 由$\gamma^{[1]},\beta^{[1]}$控制計算得到$\check{Z}^{[1]}\rightarrow a^{[1]}=g^{[1]}(\check{Z^{[1]}})$
4. 透過權重參數$W^{[2]},b^{[2]}$計算得到$Z^{[2]}$
5. 進行BN,由$\gamma^{[2]},\beta^{[2]}$控制計算得到$\check{Z}^{[2]}$
6. $\check{Z}^{[2]}$
7. $a^{[2]}=g^{[2]}(\check{Z^{[2]}})$
過程中說明了,BN的計算是發生在計算$Z$與$a$之間,當神經網路使用了BN之後,參數就會有$w,b,\gamma,\beta$,這邊必需強調,這邊的$\beta$並非超參數中的$\beta$(如momentum、adam、或計算指數加權平均值)。
你可以利用梯度下降更新$\beta:=\beta-\alpha d\beta$,或是課程內另外有提到的momentum,adam,RMSprop…
![](https://i.imgur.com/Ei1FFsu.jpg)
實作中,BN通常跟mini-batch一起使用,作法跟上面是一樣的。
將第一批$x^{\left\{1\right\}}$應用參數做計算,接著$x^{\left\{2\right\}}....$
部份參數細節的澄清,在之前提過,每層的參數是$w^{[l]},b^{[l]},\beta^{[l]},\gamma^{[l]}$,注意到z的計算方式如下:
$z^{[l]}=w^{[l]}a^{[l-1]}+b^{[l]}$
但是BN做的是,它要看這個mini-batch,先將$z^{[l]}$歸一化結果為均值為0和方差為1,再由$\beta,\gamma$重新縮放,這意味著無論$b^{[l]}$的值是多少都要被減去。
因為在BN過程中,要計算$z^{[l]}$的均值,再減去均值,在mini-batch中增加任何常數,數值都不會改變。因為加上的任何常數都會被均值減法所抵銷.
因此,如果使用BN,就可以將參數b設置為0,或是不予設置,那就會變成$z^{[l]}=w^{[l]}a^{[l-1]}\rightarrow \check{z}^{[l]}=\gamma^{[l]}z^{[l]}_{norm}+\beta^{[l]}$。
最後,$\gamma^{[l]},\beta^{[l]}$的維度會與$z^{[l]}$相同,這是該隱藏隱中隱藏單元的數量。
![](https://i.imgur.com/SPnwepb.jpg)
總結使用BN與梯度下梯(mini-batch)
* for i in 1 to numMiniBatch
* 前向傳播
* 利用BN計算,以$\check{z}^{[l]}$代替$z^{[l]}$
* 確保在這個mini-batch中z有歸一方的均值與方差($\check{z}^{[l]}$)
* 反向傳播
* 計算$dw^{[l]},db^{[l]},d\gamma^{[l]},d\beta^{[l]}$
* 更新參數
* $dw^{[l]}:=w^{[l]}-\alpha dw^{[l]}$
* $d\beta^{[l]}:=\beta^{[l]}-\alpha d\beta^{[l]}$
* $d\gamma^{[l]}:=\gamma^{[l]}-\alpha d\gamma^{[l]}$
:::info
相同作法也適用於其它優化演算法!
:::
## Why does Batch Norm work?
![](https://i.imgur.com/9nGh09X.jpg)
**課程說明**:更深入的了解BN
![](https://i.imgur.com/nfo6NNm.jpg)
BN有效用的第二個觀點是,它可以使權重比你的神經網路更滯後或更深層,比如第10層的權重相比第一層更能經的住變化。
假設你已經訓練了所有黑貓圖片,如果現在要把網路應用於其它色的貓,這種情況下,正例不會只是左邊的黑貓,還有右邊其它色的貓,那運作起來可能不會很好。
如此我們無法期待在辨視黑貓很好的模型也會在其它色貓上運作的很好。
使你數據分佈改變的這個想法稱做『covariate shift』
如果你已經學習到x映射到y,當x的分佈改變了,那你可能需要重新訓練模型。
![](https://i.imgur.com/MjYbAkg.jpg)
covariate shift的問題如何應用於神經網路呢?
假設你有一個神經網路,我們觀注第三層的學習過程,這個網路已經學習了參數$w^{[3]},b^{[3]}$,它已經很前一層學習到相關參數。
我們蓋住前面的網路,從第三層來看,它會有$a^{[2]}$的相關學習資料,第三層的工作是找到一種方式,讓這些值映射到$\hat{y}$而計算出$w^{[4]},b^{[4]}$
讓我們再將蓋住的網路打開,前面還有$w^{[2},b^{[2]}$、$w^{[1},b^{[1]}$,一但這些參數改變了,那$a^{[2]}$的值也會改變。
從第三層的角度來看,$a^{[2]}$的值不斷的改變,所以它就有了covariate shift的問題。
上一章我們討論過,BN它減少了隱藏單元分佈變化的數量,BN做的是,$z^{[1]}、z^{[2]}$的值可以改變,但是它們的均值與方差保持不變。
所以,不管$z^{[1]}、z^{[2]}$怎麼變,都會被參數$\gamma,\beta$控制在設置的均值與方差,以此控制了前面數值的改變所影響的數值分佈程度,它減弱了前層參數的影響,使得每層神經網路都可以自己學習。
![](https://i.imgur.com/9NZg2L4.jpg)
BN擁有另一個想不到的副作用,它有輕微的正規化效果。
每個mini-batch $x^{\left\{t\right\}}$的值$z^{[t]},z^{[l]}$,在mini-batch計算,由均值與方差縮放,它僅是在該mini-batch上計算,而非整個數據集中,所以均值與方差會有一些小噪音(noise)。
因為均值與方差有一些小噪音,縮放過程由$z^{[1]}$到$z^{[l]}$,過程中也有一些噪音,因為它是用有噪音的均值與方差計算得出。
這和正規化dropout相似,它往每個隱藏層的啟動值上增加了噪音,dropout加上噪音的方式會使一個隱藏單元在一定的概率下乘0,以一定的概率乘1。
而BM含了幾種噪音,因為偏差的縮放與減去均值帶來的額外噪音,所以類似dropout,這使得後面的隱藏單元不過份依類任何一個隱藏單元,因為值不大,所以整個正規化的效果並不是很大。
:::info
dropout一個很怪的性質,應用較大的mini-batch(也許512)會減少正規化的效果
:::
## Batch Norm at test time
![](https://i.imgur.com/pZAN28N.jpg)
**課程說明**:測試時的BN調校
![](https://i.imgur.com/6aCWfEU.jpg)
BN在測試的時候將資料集分成mini-batch處理,但在測試的時候你可能需要對每一個樣本逐一處理。
回想BN的相關公式
$\mu=\frac{1}{m}\sum_iz^{(i)}$
$\sigma^2=\frac{1}{m}\sum_i(z^{(i)}-\mu)^2$
$z^{(i)}_{norm}=\frac{z^{(i)}-\mu}{\sqrt{\sigma^2+\epsilon}}$
$\check{z}^{(i)}=\gamma z^{(i)}_{norm}+\beta$
在一個mini-batch中,你將mini-batch的值求和計算均值,然後計算方差,計算$z_{norm}$,並且利用$\gamma,\beta$再次的調整$z_{norm}$,這邊計算的都是mini-batch。
在測試時可能無法同時處理所有的樣本,而且甘果mini-batch設置是1的時候,1個樣本的均值與方差是沒有意義的,也因此需要單獨的估算$\mu,\sigma^2$
在典型的BN應用中,會需要用指數加權平均來估算$\mu,\sigma^2$,這個平均數包括了所有的mini-batch。
假設目前計算到第$l$層,並且有$x^{\left\{1\right\}}$,$x^{\left\{2\right\}}$,$x^{\left\{3\right\}}$...個mini-batch
當第$l$層計算$x^{\left\{1\right\}}$,得到了$\mu^{\left\{1\right\}[l]}$,接著得到$\mu^{\left\{2\right\}[l]}$,$\mu^{\left\{3\right\}[l]}$
正如之前使用指數加權平均計算$\theta_1,\theta_2,\theta_3$均值。再以$\mu,\sigma^2$指數加權平均數來計算$z_{norm}$。
在訓練時,$\mu,\sigma^2$是整個mini-batch上計算出來的,但在測試時你可能需要逐一處理樣本,就可以利用指數加權平均來追蹤訓練過程中看到的值。
## Softmax regression
![](https://i.imgur.com/btElMtK.jpg)
**課程說明**:多類別迴歸
![](https://i.imgur.com/BTwyze7.jpg)
假設現在想預測的不只是一個類別,而是多類別,如上圖。(將非預測目標設為0)
使用『C』來表示類別總數,此例為4(3+1),也表示這個神經網路的最後輸出單元會有四個。$C=n^{[L]}=4$,我們會希望知道這四個類別的各別機率有多高,$P(target|x)$,所以$\hat{y}$會是一個(4,1)維度向量,因為它會輸出四個數字,四種概率,並且加總為1。
![](https://i.imgur.com/OvVgI9G.jpg)
讓神經網路做到這點的標準模型,即是softmax層,以及輸出層來產生輸出。
* $z^{[L]}=w^{[L]}a^{[L-1]}+b^{[L]}$
* 以softmax做啟動函數
* 計算一個臨時變量$t=e^{z^{[L]}}$
* 此例為(4,1)向量
* $a^{[L]}=\frac{e^{z^{[L]}}}{\sum_{j=1}^Lt_i}$
* 基本上就是向量t,但是會歸一化使和為1
* $a^{[L]}$為(4,1)向量
* $a_i^{[L]}=\frac{t_i}{\sum_{j=1}^Lt_i}$
* 實例
* 設置$z^{[L]}\left[ \begin{array}{ccc}5\\4\\1\\3 \end{array} \right]$
* 計算$t=\left[ \begin{array}{ccc}e^5\\e^4\\e^1\\e^3 \end{array} \right]=\left[ \begin{array}{ccc}148.4\\7.4\\0.4\\20.1 \end{array} \right]$
* $\sum_{j=1}^Lt_i$=176.3
* $a^{[L]}=\frac{t}{176.3}$
* $a^{[L]}=\left[ \begin{array}{ccc}\frac{148.4}{176.3}\\\frac{7.4}{176.3}\\\frac{0.4}{176.3}\\\frac{20.1}{173.3} \end{array} \right]=\left[ \begin{array}{ccc}0.842\\0.042\\0.002\\0.114 \end{array} \right]$
* 如此就計算出各類的機率,裡面有11.4%的機率屬於3
![](https://i.imgur.com/4jXu1S2.jpg)
Softmax還有什麼功用?
假設有一個沒隱藏層的神經網路
$z^{[1]}=w^{[1]}x+b^{[1]}$
$a^{[1]}=\hat{y}=g(z^{[1]})$
softmax可以使得數據分到3個類別中,如圖決策邊界,產生了如logistic般的線性決策邊界。
## Training a softmax classifier
![](https://i.imgur.com/4hCHgR8.jpg)
**課程說明**:深入了解Softmax
- [ ] 補圖-2
回想上一個案例,整一個(4,1)的$z^{[L]},C=4$,並且計算了一個臨時變量t,再以softmax做最後的啟動函數(利用臨時變量t做歸一化),以此計算出各類別概率!
softmax名稱來源是與hard max對比的,hard max函數會觀察z的元素,然後再z中最大元素的位置放上1,其它放0,所以這是一個很硬的max(so this is a very hard max),也就是最大的元素輸出為1,其它階為0,而softmax的作法較為溫和,所以稱為soft!
另外,透過softmax將logistic推廣到C類,而不是只有2類,但當C=2的時候,softmax實際上會回到logistic。
- [ ] 補圖-3
接著要談如何訓練帶有softmax的神經網路,首先定義損失函數(Loss function)。
實際標籤
$y\left[ \begin{array}{ccc}0\\1\\0\\0 \end{array} \right]$
我們的預測
$\hat{y}\left[ \begin{array}{ccc}0.3\\0.2\\0.1\\0.4 \end{array} \right]$
這代表這模型案例表現不佳,因為所屬的目標類別只有0.2的機率。
$L(\hat{y},y)=-\sum_{j=1}^Cy_jlog\hat{y}_j=-\sum_{j=1}^4y_jlog\hat{y}_j$
此例來看,$y_1=y_3=y_4=0,y_2=1$,對應上面等式,最後只會剩下$-y_2log\hat{y}_2=-log\hat{y}_2$(因為log~2~=1)
這意味著,如果你的演算法試圖將它變小(因為梯度下降是用來減少訓練集的損失),就要使$\hat{y}_2$盡可能的大,因為這些是概率,不可能比1大。
$Cost Fnction=J(w^{[1]},b^{[1]}...)=\frac{1}{m}\sum_{i=1}^mL(\hat{y}^{(i)},y^{(i)})$
- [ ] 補圖-4
最後是softmax的梯度下降
反向傳播的部份,可以利用$dz^{[L]}=\hat{y}-y$來起始,後面就是標準的計算過程。
在後續使用深度學習框架的時候,只要給定前向傳播,它會自己明白反向傳播的。
## Deep Learning frameworks
![](https://i.imgur.com/vjklW5c.jpg)
**課程說明**:深度學習框架認識
![](https://i.imgur.com/EjpIMuO.jpg)
『每個框架都是針對某一個用戶或開發群體的』
如何選擇框架:
* 要能簡單開發,快速實現迭代
* 運行速度要快
* 框架是否真的開放(長時間的open source)
吳恩達老師並沒有確實的說明傾向使用那一個框架,但是案例上是選擇以tensorflow來說明。
## Tensorflow
![](https://i.imgur.com/kQPljva.jpg)
**課程說明**:TensorFlow
![](https://i.imgur.com/HOQjf3h.jpg)
假設成本函數為$J(w)=w^2-10w+25$
能讓成本函數最小的w值是5,但我們假裝不知道。
![](https://i.imgur.com/U3YrjPS.jpg)
```python=
import numpy as np
import tensorflow as tf
w = tf.Variable(0, dtype=tf.float32)
cost =tf.add(tf.add(w**2,tf.multiply(-10,w)),25)
# cost = w**2 -10*w +25 也可以寫這樣
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)
print(session.run(w)) # 這時候是0,因為都還沒有做
session.run(train)
print(session.run(w)) # 0.1
# 利用迴圈迭代
for i in range(1000):
session.run(train)
print(session.run(w)) # 4.99999
```
這邊會發現,我們只設置了前向傳播,但是一樣可以求導,因為反向的部份tensorflow會自己處理。
學習參數w在tf中稱為Variable
如果訓練的是資料集x呢?
```python=
X = tf.placeholder(tf.float32, [3,1])
cost = x[0][0]*w**2 + x[1][0]*w +x[2][0]
```
plceholder讓tensorflow知道,你在稍後會為x提供數值
所以,我們先另外定義一組數值
```python=
coefficients = np.array([[1.],[-10.],[25.]])
```
在訓練的時候賦值
```python=
session.run(train, feed_dict={x:coefficients})
```
這種做法在處理mini-batch的時候會用到。
- [ ] 補圖-4
```python=
session = tf.Session()
session.run(init)
xxxxx
# 也可以用with來表示
with tf.Session() as session:
session.run(init)
xxxx
```
```python=
cost = x[0][0]*w**2 + x[1][0]*w +x[2][0]
```
在tensorflow中,這一句是堆疊建立起來的語句。(如簡報上方)
tf的好處在於,通過內建函數建立前向傳播之後,它會自動執行反向傳播,因為它已經都建立好。