實驗研究工作流程詳解:如何把你的機器學習想法變成現實
從研究思想的提出到實驗的具體實現是工程中的基礎環節。但是這一過程常常被一些明顯的小瑕疵所影響。在學術界,研究生需要辛苦的科研——大量的編寫代碼,撰寫說明以及論文創作。新的工程項目經常需要全新的代碼庫,而且通常很難把過去應用過的代碼直接延伸到這些新項目當中去。
基於此種情況,哥倫比亞大學計算機科學博士生及 OpenAI 研究者 Dustin Tran 從其個人角度概述了從研究思想到實驗過程的步驟。其中最關鍵的步驟是提出新觀點,這往往需要大量時間;而且至少對作者來說,實驗環節不僅是學習,更是解決無法預測的問題的關鍵所在。另外,作者還明確說明:這個工作流程僅適用於實驗方面的研究,理論研究則需要遵循另外的流程,儘管這兩者也有一些共同點。你有什麼想法呢?不妨在評論中與我們分享。
找對問題
在真正開始一個項目之前,如何讓你的想法「落地」成為更正式的議題是非常關鍵的。有時它很簡單——就像導師會給你分配任務;或者處理一個特定的數據集或實際問題;又或是和你的合作者進行談話來確定工作內容。
更為常見的是,研究其實是一系列想法(idea)不斷迭代所產生的結果,這些想法通常是通過日常談話、近期工作、閱讀專業內和專業外領域文獻和反覆研讀經典論文所產生的。
我的所有尚未探索過的研究思想的主文檔
我發現了一種方法非常有用——即保持一個單一的主文檔(master document),這通常需要很多工作。
首先,它有一個項目列表來排列所有的研究想法、問題和題目。有時它們可以是比較高層面的問題,就像「用於強化學習的貝葉斯/生成方法」、「解決機器學習領域的公平性問題」;也可以是一些很具體的議題,比如「處理 EP 中記憶複雜度的推理網路」、「規模偏置的與對稱的 Dirichlet 先驗的分析」。我經常努力把項目列表寫得更加簡明:子內容通過一些鏈接進行展開。
然後,根據接下來要做的工作來對 idea 清單進行分類。這通常會給我的後續研究指明方向。我也可以根據其方向是否和我的研究觀點一致、其必要性和有效性隨時修改這些項目的優先順序。更重要的是,這個列表清單不僅僅是關於後續觀點的,更是關於接下來我更願意研究什麼內容的。從長遠角度來考慮,這對於找到重要問題和提出簡單新穎的解決方法是有重要貢獻的。我經常訪問這個清單,重新安排事務,添加新想法,刪除不必要的議題。最終當我可以詳細說明一個 idea 的時候,它就可以成為一篇比較正式的論文了。一般來說,我發現在同一個位置(同一個格式)迭代 idea 的過程可以使正式論文寫作中的銜接和實驗過程都變得更加流暢。
管理一個項目
我們為近期的 arXiv 預印本搭建的 repository
我喜歡在 GitHub 存儲庫中維護研究項目。不管一個「單元」的研究是多少,我都會將其定義成某種相對自我包含的東西;比如,它可能會連接到一篇特定的論文、一個已被應用的數據分析或目前一個特定主題。
GitHub 存儲庫不僅可用於跟蹤代碼,而且還可用於跟蹤一般的研究進程、論文寫作進度或嘗試其它合作項目。但項目的組織方式一直以來都是一個痛點。我比較喜歡以下的結構,該結構來自 Dave Blei,可參閱:http://www.cs.columbia.edu/~blei/seminar/2016_discrete_data/notes/week_01.pdf
-- doc/n -- 2017-nips/n -- preamble/n -- img/n -- main.pdfn -- main.texn -- introduction.texn-- etc/n -- 2017-03-25-whiteboard.jpgn -- 2017-04-03-whiteboard.jpgn -- 2017-04-06-dustin-comments.mdn -- 2017-04-08-dave-comments.pdfn-- src/n -- checkpoints/n -- codebase/n -- log/n -- out/n -- script1.pyn -- script2.pyn-- README.mdn
README.md 為自己和合作者保持了一個需要去做的事的列表,這讓面臨的問題和前進的方向變得明確。
doc/包含所有的記錄事項,每個子目錄都包含一個會議紀要或是文獻提交,main.tex 是主要文檔,每一章節都是不同文件,如 introduction.tex,讓每個章節分開可以讓多人同時處理不同的章節,避免合併衝突。有些人喜歡在主要實驗完成後一次寫出完整論文,但我更喜歡把論文作為目前想法的記錄,並且讓它和想法本身一樣,隨著實驗的進展不斷推進。
etc/是其他與前面的目錄無關的內容。我通常用它來存儲項目中討論留下的白板內容的圖片。有時候,我在日常工作中獲得了一些靈感,我會將它們都記錄在 Markdown 文檔中,它也是一個用於處置對於工作的各種評論的目錄,如合作者對於論文內容的反饋。
src/是編寫所有代碼的位置。可運行的腳本都是直接寫在 src/上的,類和實用程序寫在了 codebase/上。下面我將詳細說明一下(還有一個是腳本輸出目錄)。
編寫代碼
我現在寫所有代碼的工具都是 Edward,我發現它是快速實驗現代概率模型和演算法的最佳框架。
Edward 鏈接:Edward - Home
在概念層面上,Edward 的吸引力在於語言遵循數學:模型的生成過程被轉化為每行 Edward 代碼;隨後希望寫出的演算法被轉化為下一行……這種純凈的轉換過程免去了在未來試圖將代碼拓展為自然研究問題時的麻煩:例如,在之前使用了不同的方法,或者調整了梯度估值,或嘗試了不同的神經網路架構,或是在大數據集中應用了其他方法等等。
在實踐層面上,我總是從 Edward 的現有模型示例(在 edward/examples 或 edward/notebooks)中受益,我將預置演算法源代碼(在 edward/inferences)作為一個新文件粘貼到我的項目中的 codebase/目錄中,然後進行調整。這樣從零開始就變得非常簡單了,我們也可以避免很多低級細節上的缺失。
在編寫代碼時,我一直遵循 PEP8(我特別喜歡 pep8 軟體包:Python Package Index),隨後嘗試從腳本共享的類和函數定義中分離每個腳本;前者被放在 codebase/中以備導入。從第一步開始維護代碼質量總是最好的選擇,這個過程非常重要,因為項目會隨著時間不斷膨脹,同時其他人也會逐漸加入。
Jupyter 記事本。許多人在使用 Jupyter 記事本(鏈接:Project Jupyter)用作可互動式代碼開發的方法,它也是嵌入可視化和 LaTeX 的簡單方法。對於我來說,我並沒有將它整合到自己的工作流中。我喜歡將自己所有的代碼寫入 Python 腳本中,然後運行腳本。但 Jupyter 等工具的交互性值得稱讚。
實驗管理
在好的工作站或雲服務商做投資是必要的事。GPU 這樣的特性基本上普遍可用,而我們應該有許可權並行運行許多工作。我在本地計算機完成腳本編寫之後,我主要的工作流是:
1. 運行 rsync 同步我本地計算機的 Github Repository(包含未授權文檔)到伺服器的 directory。
2. ssh 到伺服器。
3. 開始 tmux 並運行腳本。眾事駁雜,tmux 能讓你超脫此進程,從而不需要等待它的結束才與伺服器再次交互。
在腳本可行之後,我開始用多個超參數配置鑽研實驗。這裡有一個有幫助的工具 tf.flags,它使用命令行論證增強一個 Python 腳本,就像下面這樣為你的腳本增加一些東西:
flags = tf.flagsflags.DEFINE_float(batch_size, 128, Minibatch during training)flags.DEFINE_float(lr, 1e-5, Learning rate step-size)FLAGS = flags.FLAGSbatch_size = FLAGS.batch_sizelr = FLAGS.lrn
然後,你可以運行下面這樣的終端命令:
python script1.py --batch_size=256 --lr=1e-4n
這使得提交超參數更改的伺服器任務變得容易。
最後,說到管理實驗時輸出的任務,回想一下前文中 src/目錄的結構:
-- src/n -- checkpoints/n -- codebase/n -- log/n -- out/n -- script1.pyn -- script2.pyn
我們描述了每個腳本和 codebase/。其他三個目錄被用於組織實驗輸出:
checkpoints/記錄在訓練中保存的模型參數。當演算法每固定次數迭代時,使用 tf.train.Saver 來保存參數。這有助於維護長時間的實驗——你可能會取消一些任務,後來又要恢復參數。每個實驗的輸出都會存儲在 checkpoints/中的一個子目錄下,如 20170524_192314_batch_size_25_lr_1e-4/。第一個數字是日期(YYYYMMDD),第二個是時間(HMS),其餘的是超參數。
log/存儲用於可視化學習的記錄。每次實驗都有屬於自己的和 checkpoints/中對應的子目錄。使用 Edward 的一個好處在於,對於日誌,你可以簡單地傳遞一個參數 inference.initialize(logdir=log/ + subdir)。被追蹤的默認 TensorFlow 摘要可以用 TensorBoard 可視化。
out/記錄訓練結束後的探索性輸出;例如生成的圖片或 matplotlib 圖,每個實驗都有自己的和 checkpoints/中對應的子目錄。
軟體容器。virtualenv 是管理 Python 安裝環境的必備軟體,可以減少安裝 Python 的困難程度。如果你需要更強大的工具,Docker containers 可以滿足你的需要。
Virtualenv 鏈接:Virtual Environments
Docker containers 鏈接:Docker
探索、調試和診斷
TensorBoard 是可視化和探索模型訓練的一種優秀工具。因為 TensorBoard 具有良好的交互性,你會發現它非常易於使用,因為這意味著不需要配置大量 matplotlib 函數來了解訓練。我們只需要在代碼的 tensor 上加入 tf.summary。Edward 默認記錄了大量摘要,以便可視化訓練迭代中損失的函數值、漸變和參數的變化。TensorBoard 還包括經過時間的比較,也為充分修飾的 TensorFlow 代碼庫提供了很好的計算圖。對於無法只用 TensorBoard 進行診斷的棘手問題,我們可以在 out/目錄中輸出內容並檢查這些結果。
調試錯誤信息。我的調試工作流非常糟糕。對此,我在代碼中嵌入列印語句並通過消去過程來尋找錯誤。這種方法非常原始。雖然還沒有嘗試過,但我聽說 TensorFlow 的 debugger 功能非常強大。
提升研究理解
不斷考研你的模型與演算法,通常,學習過程會讓你對自己的研究和模型有更好的了解。這可以讓你回到製圖板上,重新思考自己所處的位置,尋求進一步提升的方法。如果方法指向成功,我們可以從簡單的配置逐漸擴大規模,試圖解決高維度的問題。
從更高層級上看,工作流在本質上就是讓科學方法應用到真實世界中。在實驗過程中的每一次迭代里,拋棄主要想法都是不必要的。但另一方面,這一切的理論基礎必須穩固。
在這個過程中,實驗並不是孤立的。合作、與其他領域的專家溝通、閱讀論文、基於短期以及長期角度考慮問題、參加學術會議都有助於拓寬你看待問題的思路並能幫助解決問題。
說明
本工作流主要用於實證研究,但其中的一些方法是值得其他任務參考的。
主文檔結構的模板可以參考:dustinvtran/latex-templates
參考文獻
1. Gelman, A., & Shalizi, C. R. (2012). Philosophy and the practice of Bayesian statistics. British Journal of Mathematical and Statistical Psychology, 66(1), 8–38.
2. Pearl, J. (2000). Causality. Cambridge University Press.
3. Wainwright, M. J., & Jordan, M. I. (2008). Graphical Models, Exponential Families, and Variational Inference. *Foundations and Trends in Machine Learning, 1(1–2), 1–305.
作者 Dustin Tran 機器之心編譯
推薦閱讀:
※有誰給解釋一下流形以及流形正則化?
※Python · 決策樹(零)· 簡介
※這樣能解決知乎質量越來越低,老用戶離開的情況么?
TAG:机器学习 | 工作流 | TensorFlow |