請謹慎使用預訓練的深度學習模型

作者:Cecelia Shao
編譯:ronghuaiyang

導讀

預訓練模型用起來非常容易,但是你是否忽略了可能影響模型性能的細節呢?

你運行過多少次下面的代碼:

import torchvision.models as models
inception = models.inception_v3(pretrained=True)

或者是這個

from keras.applications.inception_v3 import InceptionV3
base_model = InceptionV3(weights='imagenet', include_top=False)

看起來使用這些預訓練的模型已經成為行業最佳實踐的新標準。畢竟,有一個經過大量數據和計算訓練的模型,你為什麼不利用呢?

預訓練模型萬歲!

利用預訓練的模型有幾個重要的好處:

  • 合併超級簡單
  • 快速實現穩定(相同或更好)的模型性能
  • 不需要太多的標籤數據
  • 遷移學習、預測和特徵提取的通用用例

NLP領域的進步也鼓勵使用預訓練的語言模型,如GPT和GPT-2、AllenNLP的ELMo、谷歌的BERT、Sebastian Ruder和Jeremy Howard的ULMFiT。

利用預訓練模型的一種常見技術是特徵提取,在此過程中檢索由預訓練模型生成的中間表示,並將這些表示用作新模型的輸入。通常假定這些最終的全連接層得到的是信息與解決新任務相關的。

每個人都參與其中

每一個主流框架,如Tensorflow,Keras,PyTorch,MXNet等,都提供了預先訓練好的模型,如Inception V3,ResNet,AlexNet等,帶有權重:

  • Keras Applications
  • PyTorch torchvision.models
  • Tensorflow Official Models (and now TensorFlow Hubs)
  • MXNet Model Zoo
  • Fast.ai Applications
請謹慎使用預訓練的深度學習模型

很簡單,是不是?

但是,這些benchmarks可以復現嗎?

這篇文章的靈感來自Curtis Northcutt,他是麻省理工學院計算機科學博士研究生。他的文章‘Towards Reproducibility: Benchmarking Keras and PyTorch’ 提出了幾個有趣的觀點

  1. resnet結構在PyTorch中執行得更好, inception結構在Keras中執行得更好
  2. 在Keras應用程序上不能復現Keras Applications上的已發佈的基準測試,即使完全複製示例代碼也是如此。事實上,他們報告的準確率(截至2019年2月)通常高於實際的準確率。
  3. 當部署在服務器上或與其他Keras模型按順序運行時,一些預先訓練好的Keras模型會產生不一致或較低的精度。
  4. 使用batch normalization的Keras模型可能不可靠。對於某些模型,前向傳遞計算(假定梯度為off)仍然會導致在推理時權重發生變化。

你可能會想:這怎麼可能?這些不是相同的模型嗎?如果在相同的條件下訓練,它們不應該有相同的性能嗎?

並不是只有你這麼想,Curtis的文章也在Twitter上引發了一些反應:

請謹慎使用預訓練的深度學習模型

請謹慎使用預訓練的深度學習模型

關於這些差異的原因有一些有趣的見解:

請謹慎使用預訓練的深度學習模型

瞭解(並信任)這些基準測試非常重要,因為它們允許你根據要使用的框架做出明智的決策,並且通常用作研究和實現的基線。

那麼,當你利用這些預先訓練好的模型時,需要注意什麼呢?

使用預訓練模型的注意事項

1、你的任務有多相似?你的數據有多相似?

對於你的新x射線數據集,你使用Keras Xception模型,你是不是期望0.945的驗證精度?首先,你需要檢查你的數據與模型所訓練的原始數據集(在本例中為ImageNet)有多相似。你還需要知道特徵是從何處(網絡的底部、中部或頂部)遷移的,因為任務相似性會影響模型性能。

閱讀CS231n — Transfer Learning and ‘How transferable are features in deep neural networks?’

2、你如何預處理數據?

你的模型的預處理應該與原始模型相同。幾乎所有的torchvision模型都使用相同的預處理值。對於Keras模型,你應該始終為相應的模型級模塊使用 preprocess_input函數。例如:

# VGG16
keras.applications.vgg16.preprocess_input
# InceptionV3
keras.applications.inception_v3.preprocess_input
#ResNet50
keras.applications.resnet50.preprocess_input

3、你的backend是什麼?

有一些關於HackerNews的傳言稱,將Keras的後端從Tensorflow更改為CNTK (Microsoft Cognitive toolkit)提高了性能。由於Keras是一個模型級庫,它不處理諸如張量積、卷積等較低級別的操作,所以它依賴於其他張量操作框架,比如TensorFlow後端和Theano後端。

Max Woolf提供了一個優秀的基準測試項目,發現CNTK和Tensorflow之間的準確性是相同的,但CNTK在LSTMs和多層感知(MLPs)方面更快,而Tensorflow在CNNs和embeddings方面更快。

Woolf的文章是2017年發表的,所以如果能得到一個更新的比較結果,其中還包括Theano和MXNet作為後端,那將是非常有趣的(儘管Theano現在已經被廢棄了)。

還有一些人聲稱,Theano的某些版本可能會忽略你的種子。

4、你的硬件是什麼?

你使用的是Amazon EC2 NVIDIA Tesla K80還是Google的NVIDIA Tesla P100?甚至可能是TPU?看看這些不同的pretrained模型的有用的基準參考資料。

  • Apache MXNet’s GluonNLP 0.6:Closing the Gap in Reproducible Research with BERT
  • Caleb Robinson’s ‘How to reproduce ImageNet validation results’ (and of course, again, Curtis’ benchmarking post)
  • DL Bench
  • Stanford DAWNBench
  • TensorFlow’s performance benchmarks

5、你的學習率是什麼?

在實踐中,你應該保持預訓練的參數不變(即,使用預訓練好的模型作為特徵提取器),或者用一個相當小的學習率來調整它們,以便不忘記原始模型中的所有內容。

6、在使用batch normalization或dropout等優化時,特別是在訓練模式和推理模式之間,有什麼不同嗎?

正如Curtis的帖子所說:

使用batch normalization的Keras模型可能不可靠。對於某些模型,前向傳遞計算(假定梯度為off)仍然會導致在推斷時權重發生變化。

但是為什麼會這樣呢?

Expedia的首席數據科學家Vasilis Vryniotis首先發現了Keras中的凍結batch normalization層的問題。

Keras當前實現的問題是,當凍結批處理規範化(BN)層時,它在訓練期間還是會繼續使用mini-batch的統計信息。我認為當BN被凍結時,更好的方法是使用它在訓練中學習到的移動平均值和方差。為什麼?由於同樣的原因,在凍結層時不應該更新mini-batch的統計數據:它可能導致較差的結果,因為下一層沒有得到適當的訓練。

Vasilis還引用了這樣的例子,當Keras模型從訓練模式切換到測試模式時,這種差異導致模型性能顯著下降(從100%下降到50%)。

英文原文:https://medium.com/comet-ml/approach-pre-trained-deep-learning-models-with-caution-9f0ff739010c

更多內容,請關注微信公眾號:AI公園


分享到:


相關文章: