本文是fastai課程第4課筆記,上來先是前3課學生做的一些優秀筆記:
Improving the way we work with learning rate
The Cyclical Learning Rate technique
Exploring Stochastic Gradient Descent with Restarts (SGDR)
Transfer Learning using differential learning rates
Getting Computers To See Better Than Humans
課程覆蓋內容概覽,當前在第4課。
Dropout [04:59]
learn:輸出我們在卷基層後加入的網絡,上面顯示的是precompute=True時,我們需要訓練的網絡層
(0), (4):BatchNorm將會在最後一課講述
(1), (5): Dropout
(2):Linear 全連接層
(3):ReLU 去除負值
(6): Linear 第二個全連接層,輸出為類別數
7): LogSoftmax 通過log提高運算精度
什麼是 Dropout 和 p? [08:17]
Dropout(p=0.5)
p代表我們需要隨機丟棄的激活層輸出,p=0.5 表示我們隨機丟棄50%的輸出,Dropout是一種防止過擬合的正則化方法。
注意
默認情況下第一層的p=0.25,第二層是0.5[17:54],如果我們訓練中發現過擬合,嘗試增大p到0.5,如果還是過擬合則到0.7。
ResNet34 相對來說網絡層數少,還不是很複雜,我們可以使用默認的dropout,但是像ResNet50,如果出現過擬合,我們將調大dropout。
為什麼我們在實際訓練中經常發現val-loss小於train-loss的情況,特別是在訓練剛開始的時候?因為我們在做 inference 的時候,dropout=0,即利用了所有信息。
在fast.ai中我們通過參數ps來設置新增網絡的層的dropout,我們不會去改變pre-trained網絡的dropout,因為這些都是已經訓練好的了。
learn = ConvLearner.pretrained(arch, data, ps=0.5, precompute=True)
我們可以設置ps=0,但是會發現訓練幾個epoch後就會出現過擬合現象(training loss ≪ validation loss):
[2. 0.3521 0.55247 0.84189]
當ps=0.的時候,Dropout都不會加進模型中:
我們可以發現上面我們默認添加了2個全連接層,我們可以通過參數xtra_fc來控制。
問題:我們是否可以設置不同的dropout,當然可以,通過參數ps來控制。
我們沒有什麼理論來指導我們是前面的層dropout大還是後面的層大
當我們不確定的時候,我們最好使用相同的dropout
一般只在最後一層設置Dropout
結構化、時序數據學習[25:03]
有兩種類別的列數據:類別(Categorical),一般有不同的level,連續(continuous),一般是浮點數
像 Year , Month 這種整數,我們可以將其看做連續也可以是類別,如果是類別,那就是告訴神經網絡Year的不同值是完全不同的,而如果是連續,則是找到一個函數進行fit,更具體的解釋可以看到之前的文章為什麼要做one-hot
選擇Categorical和continuous是需要在建模階段做出的決策,一般來說如果數據是Categorical的,那就是Categorical,如果數據是continuous的,我們需要決定是continuous還是Categorical
一般來說,如果值是浮點型,我們很難將其轉換為Categorical(我們將類別的數目稱為 Cardinality)
Categorical 變量 [50:49]
通過embed方式,我們將DayOfWeek由一個number轉換為了一個4維向量。
問題:我們怎麼去選擇embed size?
上面我們列舉出了所有的categorical variable 和它的 cardinality
我們每個類別都加了一個1,目的是如果該列出現空值,可以用0表示
選擇 embed size 的經驗是:將 cardinality / 2,最大不超過50
emb_szs = [(c, min(50, (c+1)//2)) for _,c in cat_sz]
問題:embeddings 適合所有的 categorical variable 嘛?
假設我們有 600,000 行數據,並且某列特徵有 600,000 個不同值,此時是非常不好的 categorical variable。
問題:我們如何處理dates and times類型的數據?
fastai中有個add_datepart
函數,能夠將一個時間列轉換為多個列。
舉個例子來說明這麼處理的好處,假設我們發現數據有週期性的特徵,在Mondays上升,Wednesdays下降,如果沒有dayOfWeek特徵,我們很難讓網絡自己去根據2018-02-23去學習出來,但是有了dayOfWeek就容易很多。
下面總結下整個處理過程:
本文是 fastai 課程的第四課結構化處理部分,歡迎持續關注。
fastai正式版本地址
第四課wiki地址
你的鼓勵是我繼續寫下去的動力,期待我們共同進步,歡迎關注。
閱讀更多 程序猿的進擊之路 的文章