254頁PPT!這是一份寫給NLP研究者的編程指南

機器之心編輯部、赤樂君。算法

最近 AllenNLP 在 EMNLP2018 上作了一個主題分享,名爲「寫給 NLP 研究者的編程指南」(Writing Code for NLP Research)。該演講從寫原型和寫模塊兩方面介紹了 NLP 研究該如何複製別人的代碼、測試本身的代碼塊、記錄及分享研究等,總之在研究者也要高效碼代碼的年代,這是一份濃縮的實踐經驗。docker

這分內容乾貨滿滿,僅僅只是看了 slide 就知道是很是有意思的一次演講了。slide 共有 254 頁之多,在「赤樂君」知乎專欄分享內容的基礎上,機器之心爲你們介紹 NLP 及深度學習研究者的編程指南。編程

讀者能夠直接下載 PPT 瞭解詳細內容,其中每一頁 PPT 都帶有簡要的備註,根據這些備註能夠將全部 PPT 以及整場演講串聯起來。安全

下面是整個分享的大綱。經過此次演講,你能夠學到如何寫代碼來促進你的研究,以及可復現的實驗。固然讀者最好仍是知道一點 NLP 相關的知識,由於這一份分享會以深度學習中的 NLP 問題做爲案例。此外,可以大體讀懂 Python 代碼也是很好的背景,這篇文章都是以 Python 接口調用 DL 框架爲例。模塊化

這裏有兩種寫研究代碼的模式,一種是寫原型,一種是寫組件。做爲一名研究者,大多數時候咱們都但願寫原型,可是在沒寫好組件前是寫很差原型的。而經過原型設計,有時候作出來的東西又是但願下次再複用的組件。所以這是編寫代碼的兩種模式,它們並不獨立。工具

咱們先從寫原型的方式開始介紹。oop

寫原型

當咱們開始寫一個原型代碼的時候,咱們要作到下面三點。
性能

1. 寫代碼要快

2. 跟蹤實驗結果

3. 分析模型結果

快速開發

要作到快速編程,不要從頭開始寫全部內容,而是使用框架。這裏的框架不只指 tensorflow 或 pytorch 之類的框架,也能夠理解爲模板。好比上圖中若是寫 training loop 的部分,已經有人寫好了。咱們只要看懂後,直接拿來用就行,沒有必要從頭開始本身寫全部部分。

上面提到的一些內容,都是能夠找到現成框架來套用的。不少時候咱們在編程時遇到的問題不是構建模型,而是數據讀取、預處理和寫訓練循環等部分。若是有人把你想用的東西模塊化了,還等什麼,直接拿來用啊!

固然拿來用也是有步驟的,首先咱們應該得到基線模型的性能,這也是一個很好的研究實踐。基線模型多是別人的代碼,你要是能修修改改就更好了。其次復現 SOTA 基線結果對於理解模型和作更多的研究是很是有幫助的。

要想快速開發,另外一個建議就是先複製,再重構。要記住,咱們是在寫原型,不用在意什麼可用性,先把代碼寫 work 了再說。若是實現的效果不錯的話,再回去重構。

另外,咱們要有好的編程習慣。好比起有意義的變量名,寫註釋幫助理解。記住,咱們是寫給人看的,不是機器!此外在使用基線模型作試驗的時候,咱們能夠如今小數據集上作測試,並確保模型能準確讀取數據。

若是在作原型設計時,咱們將 LSTM 寫死了(hard-code),那麼在咱們但願使用 Transformer 等模塊的時候就須要從新改代碼。所以使用多態能夠藉助更高級的抽象擴展代碼,這樣在換模塊時就能只修改少許代碼。

跟蹤實驗結果

在寫原型的時候你須要運行不少東西,這致使很難追蹤發生了什麼以及對應的代碼部分。

能夠準備一個 Excel 表格,來記錄實驗結果。

黑箱對比對於上下文理解有幫助,但不能深刻理解兩個結果之間的關係,由於有太多的變量在同時變化。咱們須要每次僅改變一個變量,能夠在代碼中設置「開關」,將開關配置一些全局狀態/依賴注入。

每次只改變一個部分,方便跟蹤實驗結果的變化其緣由在於哪裏。


這裏光是 embedder,咱們就有不少種選擇。

使用設定文件來記錄模型的改變,方便咱們之後查詢當時的設定。

分析模型結果

在訓練的時候,可視化對於分析模型表現是很是重要的。這個技能必須掌握。

Tensorboard 能夠提供不少分析結果。

Tensorboard 能幫咱們找到優化的 bug。好比上圖中的 embedding 梯度有兩個數量級的差異。

緣由在於 embedding 的梯度是稀疏梯度,即只有一部分會被更新。可是 ADAM 中的動量係數是針對整個 embedding 計算的,因此解決方法是直接引入特定的優化器:DenseSparseAdam。

在解釋你的模型的預測輸出時,好的展現是靜態預測;更好的展現是交互地查看預測;最好的展現是交互地查看內部過程。

對於預測結果,若是能夠作到交互式的方式來查看的話,是最好的。

開發組件

與寫原型不一樣,開發可重複使用的組件有不少要注意的地方。咱們的代碼須要寫清楚,這樣就能聚焦於建模決策,而不考慮代碼到底在作什麼。

Code Reveiw 是必不可少的。Review 的時候,不只能發現錯誤,還能提升代碼的可讀性。


若是咱們不是軟件開發人員的話,對於持續整合 以及構建自動化 這兩個詞可能比較陌生。一般咱們只說持續整合的時候,也包含了構建自動化的意思。想要作到這點,要多寫測試才行。

固然,若是咱們不是開發一個不少人都會用到的庫,上面這些步驟是用不到的。不過測試很重要,若是是原型開發,也要作一些最基本的測試。

如上對讀取的數據進行測試,看是否正確。這裏在進行單元測試時經常使用的就是 assert 語句,若是程序有問題,運行到這邊就天然會報錯,這樣可讓咱們儘快找到錯誤。

如上所示,固然咱們也可使用 assert 語句檢查維度是否一致。這在模型運算部分常常會用到,例如判斷每一個卷積層輸出結果的尺寸和深度等。能夠看到這兩種測試的代碼都不會不少。因此不要犯懶了,好好寫測試吧。

關於 AllenNLP 庫的一些介紹,這裏就不花時間討論了,感興趣的能夠看 slide 中 p141~p205 的部分。下面直接進入分享的部分。

分享研究

簡化安裝的流程,令代碼運行在任何平臺,使用隔離的環境。

下面是使用 Docker 的一些優勢。

用 docker 開發的好處不用多說,你們想必也已經都知道了。固然,缺點也是有的。

至於 Python 的包管理系統,AllenNLP 採用了 ANACONDA。

Docker 是不錯,但不適合作本地開發,這樣的話,使用一些本地的包管理系統反而更方便。

最後作個總結。

  • 快速開發原型(要安全)

  • 寫安全的產品代碼(要快)

  • 好的流程有利於作出好的研究

  • 使用正確的抽象

  • 查看 AllenNLP(廣告)

此次分享的 slide 看了幾遍,不少地方看得本身臉上發熱,不寫測試什麼的說到了痛處。如今人工智能領域對於算法工程師的要求已經不是能掉個包,談談研究那麼簡單了,工程實踐能力已經變得愈來愈重要。寫優秀的代碼,作優秀的研究,兩者是一個互相促進的過程。

相關文章
相關標籤/搜索