0
本文作者: 蔣寶尚 | 2020-04-17 16:31 |
作者 | 蔣寶尚
編輯 | 叢末
人工智能的研究該不該開(kāi)源代碼,一直是社區(qū)熱議的話題。畢竟,一項(xiàng)機(jī)器學(xué)習(xí)研究不僅包括理論,算法和應(yīng)用也是機(jī)器學(xué)習(xí)研究的重要內(nèi)容。
ICML、ICLR 和 NeurIPS 都在嘗試將實(shí)驗(yàn)代碼和數(shù)據(jù)作為評(píng)審材料的一部分提交,鼓勵(lì)作者在評(píng)審或出版過(guò)程中提交代碼。事實(shí)證明,結(jié)果能夠復(fù)現(xiàn)的研究往往也更能引起討論,也更能促進(jìn)學(xué)科領(lǐng)域的進(jìn)步發(fā)展。
但是,卻一直存在著這樣問(wèn)題:開(kāi)源研究中的代碼應(yīng)該如何寫?提交的時(shí)候應(yīng)該注意什么樣的事項(xiàng),才能幫助其他研究者更容易復(fù)現(xiàn)論文結(jié)果?
一位機(jī)器學(xué)習(xí)研究員,在reddit上發(fā)出了倡議,提出了機(jī)器學(xué)習(xí)研究中開(kāi)源代碼時(shí)的五大反面教材(反模式),呼吁在開(kāi)源代碼的時(shí)候,盡量避免一些錯(cuò)誤。
以下為他的倡議原文:
大家好,鑒于這個(gè)話題,我必須先聲明一下:我也很佩服發(fā)表論文并有勇氣開(kāi)放源代碼的研究員,他們非常了不起,我個(gè)人也從開(kāi)源代碼庫(kù)中改編過(guò)一些代碼,即用于自己的項(xiàng)目,也用于生產(chǎn)代碼。我對(duì)此表示最深刻的敬意。
但是,這些代碼有時(shí)候也出現(xiàn)問(wèn)題 **runs for cover**
下面是我個(gè)人的筆記,里面包括五個(gè)反面教材,如果你有補(bǔ)充,歡迎評(píng)論留言,如果你不同意,指出來(lái)哪一個(gè),我們展開(kāi)討論。
在敲機(jī)器學(xué)習(xí)相關(guān)研究代碼,或者其他的啥領(lǐng)域代碼的時(shí)候,請(qǐng)盡量避免:
1.做一個(gè)單一的配置對(duì)象,讓所有的函數(shù)不斷傳遞給你。配置文件非常棒,但是如果把他們加載到字典里面,然后到處mutating,那么這就會(huì)變成一場(chǎng)噩夢(mèng)。
注意,在頂層這么操作通常不會(huì)有問(wèn)題,也可以和你的CLI綁定在一起。
2.使用argparse當(dāng)然可以,但是不要像上面note1那樣使用,另外讓我們廢除 "from args import get_args(); cfg = get_args()"的模式。用更加直接的方法解析命令行的參數(shù)。(例如,如果你使用 argh,自然會(huì)讓你圍繞著可重用的函數(shù)來(lái)架構(gòu)你的代碼)
3.請(qǐng)不要讓你的CLI接口泄露到你的實(shí)現(xiàn)細(xì)節(jié)中去,首先創(chuàng)建庫(kù),然后將其公開(kāi)為CLI。這會(huì)讓所有東西都更具可重用性。
4.除非有充分的理由(提示,很少有),否則不要使用文件作為進(jìn)程間通信。如果你調(diào)用一個(gè)函數(shù)保存了一個(gè)文件,然后在下一行代碼中加載這個(gè)文件,那就說(shuō)明出了很大的問(wèn)題。如果這個(gè)函數(shù)是來(lái)自不同的repo,可以考慮cloning它,修復(fù)后再PRing回來(lái),使用修改后的形式。當(dāng)然,還是有副作用的,往往會(huì)引起一個(gè)“無(wú)聲”的Bug。
5.在幾乎所有的情況下,除了最瑣碎的情況,做一個(gè)事物列表上操作的函數(shù)比在單個(gè)事物上操作的函數(shù)更麻煩。所以,如果真的需要一個(gè)接受列表的接口,可以直接做一個(gè)新的函數(shù),調(diào)用單個(gè)函數(shù)就可以了。
帖子放到reddit上面之后,立即引起了各路網(wǎng)友反響,大家似乎在一些學(xué)術(shù)論文中或多或少都遇到了這些問(wèn)題。
(雷鋒網(wǎng))
哈哈,期初以為我只會(huì)在學(xué)術(shù)論文中遇到這些問(wèn)題,隨后我進(jìn)入業(yè)界的時(shí)候,發(fā)現(xiàn)機(jī)器學(xué)習(xí)中的技術(shù)欠債是真實(shí)存在的。
(雷鋒網(wǎng))
在編寫個(gè)人研究代碼的時(shí)候,我并未總是提前對(duì)最終結(jié)果有個(gè)清晰的想法,接口需要不斷更改,以前有意義的庫(kù)可能在一些改變之后不再有意義。我使用反模式,通常是為了趕DDL時(shí)候,加快實(shí)現(xiàn)速度。
(雷鋒網(wǎng))
一個(gè)項(xiàng)目中往往有兩種代碼,一種是作為基礎(chǔ)設(shè)施的代碼,另一種是作為研究工作流的代碼。前者應(yīng)該是相當(dāng)靜態(tài)的,明確的,有很好的軟件工程。后者應(yīng)該是靈活的,且有可能是混亂的,能夠優(yōu)化為快速迭代。
這個(gè)話題非常重要,但是,你必須說(shuō)明為什么這些事情是壞的,還必須提出替代方案。
上面提到的五點(diǎn)寫代碼的反模式與機(jī)器學(xué)習(xí)技術(shù)債務(wù)息息相關(guān),一般來(lái)說(shuō),反模式一開(kāi)始用起來(lái)很爽,但是維護(hù)起來(lái)卻有非常大成本開(kāi)銷。
機(jī)器學(xué)習(xí)不同于其他,2015年谷歌曾經(jīng)貢獻(xiàn)過(guò)一篇年度頂級(jí)論文《機(jī)器學(xué)習(xí)系統(tǒng),隱藏多少技術(shù)債?》,里面詳細(xì)介紹了機(jī)器學(xué)習(xí)系統(tǒng)一些常見(jiàn)的的反面模式。其中過(guò)包括:
粘合代碼 :機(jī)器學(xué)習(xí)研究者傾向于開(kāi)發(fā)普遍適用的解決方案作為自給自足的包(packages)。采用通用軟件包經(jīng)常會(huì)導(dǎo)致粘合代碼的系統(tǒng)設(shè)計(jì)模式,在這種系統(tǒng)設(shè)計(jì)模式中,包含了大量支持?jǐn)?shù)據(jù)寫入通用軟件包或者數(shù)據(jù)從通用軟件包中輸出的代碼。
粘合代碼的代價(jià)從長(zhǎng)遠(yuǎn)來(lái)看是很高的,因?yàn)檫@會(huì)讓機(jī)器學(xué)習(xí)系統(tǒng)非常局限,如果需要測(cè)試其他方法,成本就會(huì)變得不可避免的昂貴。
對(duì)抗粘合代碼的重要策略之一就是,將黑盒包裝進(jìn)普通的應(yīng)用程序接口,以便更多地重復(fù)利用,降低更換包的成本。
管道叢林:這是粘合代碼的一種特殊情況,經(jīng)常出現(xiàn)在數(shù)據(jù)預(yù)備階段。稍不注意,在機(jī)器學(xué)習(xí)系統(tǒng)良好的格式下,預(yù)備數(shù)據(jù)的結(jié)果系統(tǒng)可能會(huì)成為一個(gè)充滿碎片的叢林,經(jīng)常也會(huì)有中間輸出文件在其中。
只有從整體上考慮數(shù)據(jù)收集和特征提取的過(guò)程,才能夠避免“管道叢林”現(xiàn)象的發(fā)生。從頭再來(lái)的方式雖然初始投資巨大,但卻能夠大幅度減少持續(xù)增加的成本。
失效的實(shí)驗(yàn)代碼路徑:在主要的生成代碼中,通過(guò)執(zhí)行實(shí)驗(yàn)代碼路徑作為條件分支來(lái)演示具有選擇性方法的實(shí)驗(yàn)過(guò)程,短期內(nèi)很有誘惑力,但是隨著時(shí)間的推移,后臺(tái)兼容性的維護(hù)會(huì)非常困難。
結(jié)果辦法是周期性地重復(fù)檢查每個(gè)實(shí)驗(yàn)分支,果斷舍棄廢物分支非常有益
抽象化債務(wù):當(dāng)時(shí)谷歌認(rèn)為,明顯缺少?gòu)?qiáng)抽象來(lái)支持機(jī)器學(xué)習(xí)系統(tǒng)。基于的觀察是:機(jī)器學(xué)習(xí)領(lǐng)域的文獻(xiàn)中,沒(méi)有哪一篇將相關(guān)數(shù)據(jù)庫(kù)(relational database)作為基本抽象(basic abstraction)的論文得到的結(jié)果能達(dá)到接近成功的地步。
常見(jiàn)異味(smell):即在一個(gè)系統(tǒng)中或者系統(tǒng)中的一個(gè)部件中存在的潛在問(wèn)題。主要包括:1、POD類(Plain-Old-Data)異味,即機(jī)器學(xué)習(xí)系統(tǒng)采用浮點(diǎn)數(shù)、整數(shù)等普通的數(shù)據(jù)類型進(jìn)行編碼。2、多語(yǔ)言異味,用多種語(yǔ)言編寫系統(tǒng)經(jīng)常會(huì)增加測(cè)試成本,并且會(huì)增加將所有權(quán)讓渡給其他人的難度;3、原型異味,定期地依賴原型環(huán)境意味著機(jī)器學(xué)習(xí)系統(tǒng)的脆弱性,時(shí)間壓力會(huì)促使一個(gè)原型系統(tǒng)變成了產(chǎn)品解決方案,所以長(zhǎng)遠(yuǎn)看需要付出更多的成本。
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。