構建神經網絡前你需要先考慮這幾件事

前言

在閱讀了一篇MNIST的教程(或10篇)並瞭解了一些Tensorflow / Keras最佳實踐後,你可能會認爲將神經網絡應用於預測任務是一種“即插即用”操作。

不幸的是,事情往往並非那麼容易。 在實踐中,即使是訓練一個簡單的網絡結構(不用沒有GAN或一些花哨的結構)來對你的數據進行預測,也是一項富有挑戰的任務。

因此,當你在代碼編輯器敲下 import tensorflow as tf 或引入其他DL框架的語句前,可以先了解以下10個問題,這將有助於你解決在工程實際中遇到的深度神經網絡相關問題。

1.你的數據量夠嗎?

當前深度學習技術的流行可以歸因於其驚人的大量的參數擬合能力(雖然這種能力目前還不可以完全解釋),以至於它可以對從未“見過”的數據進行準確的預測。但是網絡的這種能力並非唾手可得,你需要“喂”給網絡和其參數數量同等量級的數據來得到所謂的“泛化性”。如果你花費了好幾日僅從網絡上收集到5K多張圖片,那麼你將面臨無法過擬合你的小數據集的挑戰。

也許你可以使用“遷移學習”來搶救一下。遷移學習的動機在於使用在某一項任務上訓練出來的模型來解決另一項任務(譯者注:這兩種任務通常具有一定的相似性。例如用人臉檢測的網絡進行面部屬性的識別)。這是因爲網絡的層次結構表明這兩個模型傾向於在網絡的第一個“特徵提取”層中執行相似的操作。 這表明了“借用”在其他任務上訓練的網絡參數的想法的可行性。

現有的大量的預訓練模型使得遷移學習在計算機視覺這樣的任務中是非常易行(譯者注:根據我的經驗,遷移學習在醫療圖像上似乎效果並不明顯)。在其他領域也可以採用相同的原則。 實際上是從你訓練的另一個網絡進行遷移學習。 一般來說,如果你的預測任務非常特殊,且相關數據很少(例如,預測癌症患者的心率),請嘗試提出另一個類似但更爲常見的任務(例如,預測一般人羣的心率) ,數據更容易收集。 首先訓練一般模型,然後用原始數據微調網絡。

2.將你的輸入數據規範化

輸入規範化是一個重要的課題,並且在技術上,它對於保證穩定的學習過程以及更快地收斂到局部最小值至關重要。你需要牢記於心的是,輸入規範化要比應用你喜歡的數據縮放變換要多得多。爲了不至於對你的數據太陌生,你可以嘗試使用這個機會來對你的數據進行適當的探索性分析。這個過程雖然簡單,但是它對提高任意一個模型的性能都非常有效。你可以通過查看你的數據中的統計信息來對數據有更深入的見解。你的數據中有異常值嗎?你的數據中有錯誤的標籤嗎?你數據的類別平衡嗎?等等。

3.網絡結構的設置應與你的任務匹配

大多數用於分類任務的DL教程適用於單標籤的情況(互斥標籤 - 只有一個標籤可以是真實的),這些教程中的網絡大都使用softmax + categorical cross entropy的配置。這樣的配置是如此常見,以至許多人多忽略了這樣一個事實,即每個網絡都不必以softmax層結束。讓我們回想一下softmax函數的作用,正如它的名字所表示的含義一樣,用一種類似平滑最大值的方式處理數值。這也就意味着在大多數情況下,它會將單個類別“標記”爲具有最高概率的類別。在兩種常見情況下,這種行爲可能很糟糕:多標籤分類(你希望允許多個類獲得高概率),當你將預測的數據不一定屬於之前的任何一個類別(在這種情況下,softmax將給出很高的概率,因爲它只查看帶預測類與其他類別相比的可能性)。在這些情況下的替代方案是使用sigmoid(按單獨的類別計算)以獲得最終層的激活函數,同時使用二元交叉熵作爲損失函數。

4.逐漸提升模型的容量

微調網絡超參數這一不可避免的過程可能會讓你後悔選擇深度學習作爲你項目的解決方案。。 “超參數”是用於控制學習算法行爲的一組設置的通用術語。在DL中,超參數包括模型的深度和寬度,正則化的量,學習率以及許多其他用於訓練網絡的參數。 超參數的問題在於它們是參數,你無法從訓練集中學習它們(譯者注:目前AutoML之類的研究就是爲了解決超參數的調參問題)。 這通常使訓練過程變得繁瑣,因爲最佳值的搜索空間可能很大,並且每次迭代都需要很長時間。
我可以給出的一個策略,使這種超參數的搜索不那麼可怕。從最小的合理網絡(深度和寬度都很小)開始,只有在需要時才逐漸提升模型的容量。根據經驗,對於每個架構,我首先嚐試適應我的數據的一小部分(比如說10%),然後是我的整個數據。如果我無法將數據與我的網絡匹配(即,在給定足夠的訓練時間的情況下達到零訓練誤差),則意味着我必須增加容量 - 我使用一些啓發式選擇來擴大網絡的寬度或深度,然後重複。這種方法背後的想法是Occam的剃刀原則,這對你以後任務中的過擬合問題很有幫助。

5.使用正確的數據增強類型

許多人錯誤地認爲數據增加是“獲取更多數據”的一種手段。實際上,數據增加應該被認爲是規則化的一種形式 ,一種向模型引入正確類型的不變性的方法。 讓我們這樣想:當你使用大量的epoch訓練模型時,你本質上就是在多次遍歷整個訓練集。 執行數據增強意味着每次向模型展示訓練數據時,都會以略微增強的方式顯示它。 你應該使用此方法來告訴網絡你不關心的各種排列,例如,那些可能會大大改變圖像的像素表示但不影響標籤的排列。 如果圖像模糊,您是否希望網絡識別圖像? 如果它們順時針旋轉90度? 如果它們是鏡像的?根據你對任務的瞭解來選擇數據增強的類型。

6.迴歸或是分類

分類和迴歸任務間的區別非常明確:如果輸出變量採用類別標籤,那麼你應該解決分類任務,如果需要得到連續的值,則應該解決迴歸任務。對嗎?好吧,這這麼說不能算錯。事實上,許多人報告稱,在連續數值的預測任務中,通過先執行分類任務(例如,將[0,10]分成10個不同的類:[0,1),[1,2),……),再使用迴歸模型進行微調預測連續值可以獲得的更好結果。這本身並不是一個問題,而是一個重要的提醒:DL仍然是一個經驗主義比固有的理論主義更有效的領域。這意味着,只要有多種方法可以解決你的任務(大多數情況下,請考慮一下),你絕對應該考慮嘗試多個選項。你可能會感到驚喜,即使訓練結果糟糕,你仍可以獲得更多經驗。

7.考慮正確的損失函數

你是否考慮過,爲什麼你想要使用“非標準”損失函數?它實際上比你想象的要常見得多,儘管它在教程中經常被忽略。一個經典的例子是當你處理一個不平衡的類別場景時(如果你在第二步進行了探索性的數據分析你就會發現類別的不平衡),比如有的類別它的標籤數目特別多,這會出現問題。如果你沒有考慮到類別不平衡問題,你可能會發現自己的網絡適合大多數類,但對少數類的表現非常糟糕。解決這個問題的一個簡單方法是明確地“告訴”網絡更加重視少數羣體中的訓練數據,加大該類數據訓練時錯誤權重。這基本上相當於對少數羣體進行過度抽樣。 這種做法在ML中的很常見,同樣在DL中也非常有用,而且說實話,我總是驚訝於它能夠提高實際應用程序的準確性。更高級的程序員可以通過將不同的權重不僅放在不同的類別上,還可以放在不同類型的錯誤上,將加權損失函數傳遞到到下一個層級,以平衡目標的召回精度。有時候我們需要創造力。

8.模型評估

另一件經常被忽視的事情是,評估指標和用於優化過程的損失函數不同。 “正確”的業務流程應該是首先考慮最合適的評價標準來評估算法的性能。例如,這是將用於選擇最佳超參數集的度量標準,然後纔會弄清楚最合適的損失函數是什麼。在許多場景下,出於數字或計算上的原因,你最終會使用不同的損失函數。 例如,你可能正在進行時間序列預測任務,你選擇的度量標準是您的預測與實際標籤間的皮爾森相關性,但是使用MSE作爲代替,因爲針對小批量的皮爾森優化是一致的。 因此,記住這一點:使用(甚至非常推薦!)不同的指標來訓練和評估模型。

9.閱讀文獻

是否有一些問題是正在着手處理而我還未提及的?你極有可能不是第一個遇到這個問題的人,不要嘗試去造輪子!即使是一個簡單的實驗也會耗費你的時間,你應該去借鑑其他人解決該問題的方案。我的建議就是不要害怕實踐,並在網上(或arxiv)搜索與你正在考慮的問題相關的文獻。從長遠來看,這將節省你的時間,即使你不混跡在學術界,也可以對新的idea開放包容。

與我交流

github:  https://github.com/keloli

blog:     https://www.jianshu.com/u/d055ee434e59

參考資料

- [10 Things to Think About Before Starting to Code Your Deep Neural Network](https://towardsdatascience.com/10-things-to-think-about-before-starting-to-code-your-deep-neural-network-65094a1e7c08)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章