怎样高效阅读一份深度学习项目代码?
猶豫很久要不要把讀代碼這個(gè)事情專門挑出來(lái)寫成一篇推文。畢竟讀代碼嘛,大家可能都會(huì)讀。而且筆者個(gè)人讀的和寫的代碼量也并不足以到指導(dǎo)大家讀代碼的程度。但筆者還是決定大膽地寫一點(diǎn):就當(dāng)是給自己設(shè)立今后讀代碼的標(biāo)準(zhǔn),也將一些之前未能踐行的方法給寫下來(lái)供大家參考。不當(dāng)之處,還請(qǐng)各位指教。
搞深度學(xué)習(xí)的人,兩大必備日常除了讀論文之外就是讀代碼。讀論文筆者在第4問(wèn)的時(shí)候講了閱讀路線,但如何讀用什么技巧讀每個(gè)人都有不同的見(jiàn)解,這里不多說(shuō)。讀代碼跟讀論文、讀書多少有相似的地方,畢竟都是讀的性質(zhì)。但話又說(shuō)回來(lái),讀代碼又跟讀paper讀書大有不同,代碼是一種將論文中的模型和算法進(jìn)行實(shí)現(xiàn)的過(guò)程,是一種需要你思維時(shí)刻在線的過(guò)程。又因?yàn)槲覀冏x的是深度學(xué)習(xí)項(xiàng)目代碼,不是像Linux內(nèi)核代碼那樣的鴻篇巨制,所以在代碼性質(zhì)上多少又有些不同。
筆者這里說(shuō)的一份深度學(xué)習(xí)項(xiàng)目代碼,小到幾百行的測(cè)試demo,大到成千萬(wàn)行的開(kāi)源項(xiàng)目,讀起來(lái)方法肯定各有不同。如下圖Mask R-CNN項(xiàng)目代碼和PyTorch源碼的對(duì)比:
可以看到,Mask R-CNN作為一個(gè)經(jīng)典的實(shí)例分割框架,其代碼量可以說(shuō)是中規(guī)中矩,3k的代碼量在我們讀完論文后集中花幾天時(shí)間差不多可以過(guò)一遍。但PyTorch的源碼對(duì)大多數(shù)人而言就不那么友善了,750k的代碼量,而且底層的C++代碼占到整個(gè)項(xiàng)目中的一半之多,作為深度學(xué)習(xí)研究而言,堪稱巨無(wú)霸級(jí)別了。這樣的代碼量,就像初學(xué)者拿到一本PRML,往往投入巨大精力后不了了之。所以,對(duì)于這兩種類型的項(xiàng)目代碼,閱讀方法肯定會(huì)有所區(qū)別。
因?yàn)槲覀冏x代碼的目的、場(chǎng)景和對(duì)象不盡相同,下面筆者從三個(gè)方面來(lái)和大家探討如何閱讀一份深度學(xué)習(xí)項(xiàng)目代碼。
首先讀代碼的一些通用方法。這一點(diǎn)而言不局限于深度學(xué)習(xí)項(xiàng)目代碼,任何項(xiàng)目、任何語(yǔ)言的代碼閱讀都適用。我們?nèi)粘Wx代碼無(wú)非是兩個(gè)工具,一是將代碼下載到本地,打開(kāi)IDLE,在IDLE里安靜的閱讀:
第二個(gè)就是直接在GitHub的web端直接閱讀,但GitHub沒(méi)有像編輯器那樣在左側(cè)設(shè)置閱讀目錄,每次進(jìn)入一個(gè)代碼文件就必須退出來(lái)才能進(jìn)入另一個(gè)文件,用戶體驗(yàn)極差。當(dāng)然了,這都不是事。chrome給我們提供了Octotree這樣的輔助閱讀插件,直接在chrome擴(kuò)展程序里搜索安裝即可。
安裝后我們就可以直接在web端就有IDLE讀代碼的體驗(yàn):
可以看到在頁(yè)面左側(cè)有一個(gè)類似IDLE的目錄欄,大大方便了我們查看和閱讀項(xiàng)目代碼。這是通用方法中的工具層面,我們?cè)賮?lái)看一些基本的閱讀規(guī)矩。有了IDLE和Octotree工具,我們第一點(diǎn)一定是仔細(xì)看代碼目錄,對(duì)整個(gè)項(xiàng)目代碼結(jié)構(gòu)和分布有一個(gè)整體的認(rèn)識(shí),對(duì)于深度學(xué)習(xí)而言通常目錄中各個(gè)模塊相對(duì)比較固定,比如是models目錄下放著模型搭建和訓(xùn)練的代碼,conifg目錄下放著模型的一些配置文件,data目錄下放著項(xiàng)目所使用的數(shù)據(jù)信息等等。如下面語(yǔ)義分割項(xiàng)目的目錄結(jié)構(gòu):
對(duì)深度學(xué)習(xí)項(xiàng)目代碼的結(jié)構(gòu)熟絡(luò)之后,讀的多了自然就會(huì)輕車熟路起來(lái),后面閱讀效率也就提高了。
通用方法的第二個(gè)是快速找到readme文檔。通常來(lái)說(shuō),根目錄下的readme文檔包含了這份代碼的使用方法,里面有可以讓你快速了解這個(gè)項(xiàng)目的關(guān)鍵信息。一般來(lái)說(shuō),開(kāi)源項(xiàng)目的readme里作者都會(huì)寫明如何使用代碼和進(jìn)行部署。下圖是DenseNet的readme文檔:
對(duì)于大型項(xiàng)目,可能每一個(gè)子目錄下都有readme文檔,這都是我們需要仔細(xì)閱讀的部分,作者把關(guān)鍵信息都放里面了。所以不管這樣,第一時(shí)間讀找到readme進(jìn)行閱讀是你了解該項(xiàng)目的必備步驟和通用方法。
第三個(gè)通用方法就是具體如何讀的問(wèn)題。就是我們得確定一個(gè)閱讀主線。這一點(diǎn)是針對(duì)于深度學(xué)習(xí)項(xiàng)目代碼的通用方法,對(duì)于一個(gè)深度學(xué)習(xí)項(xiàng)目,我們一般想要了解的最關(guān)鍵點(diǎn)無(wú)非就是數(shù)據(jù)、模型和如何訓(xùn)練等幾個(gè)方面。如果你想快速看看這個(gè)開(kāi)源項(xiàng)目的測(cè)試效果,直接讀readme看使用方法即可。如果這個(gè)項(xiàng)目作者提出了一個(gè)新的模型框架,比如說(shuō)bert,你想了解它的模型框架細(xì)節(jié),直接定位到models目錄下的帶有model字眼的.py文件開(kāi)始讀。或者是你想看這個(gè)項(xiàng)目是如何訓(xùn)練的,都用了哪些訓(xùn)練的tricks,它的參數(shù)初始化是如何做的,batchsize用的多大,訓(xùn)練過(guò)程中學(xué)習(xí)率如何調(diào)整的等等,那么話不多說(shuō),直接定位到帶train的.py文件即可。如下圖faster-rcnn的3個(gè)訓(xùn)練文件。
根據(jù)目的不管是model還是train的主線,在閱讀過(guò)程中一定會(huì)涉及到其他分支,比如說(shuō)數(shù)據(jù)和配置等其他分支線。在主線閱讀過(guò)程中不斷完善對(duì)分支的理解,久而久之,一個(gè)完整的項(xiàng)目就會(huì)被你消化了。
以上說(shuō)的是深度學(xué)習(xí)項(xiàng)目代碼閱讀的一些通用方法。下面再具體講兩個(gè)場(chǎng)景的代碼閱讀。畢竟大家做事講究目的性,往往帶有較強(qiáng)的目的性去做某事效率一般會(huì)特別高。
第一個(gè)場(chǎng)景是在大家做研究做項(xiàng)目時(shí)遇到問(wèn)題時(shí)。不知道這個(gè)問(wèn)題如何解決,直接谷歌又找不到好合適的方法的時(shí)候。這時(shí)候我們可能會(huì)寄希望于在GitHub上搜羅一番。比如說(shuō)我們想要知道對(duì)于極度數(shù)據(jù)不平衡時(shí)如何給損失函數(shù)加權(quán)重的方法,再比如對(duì)于多標(biāo)簽問(wèn)題進(jìn)行模型預(yù)測(cè)時(shí)如何找到最佳分類閾值等等。這些問(wèn)題都是我們?cè)谧鰧?shí)際項(xiàng)目時(shí)都可能會(huì)碰上的,在這種情況下若是能在GitHub上找到類似場(chǎng)景的處理方法,相信你會(huì)瞬間來(lái)了精神。
下述基于keras的CNN多標(biāo)簽分類項(xiàng)目對(duì)于多標(biāo)簽分類閾值尋優(yōu)使用了matthews_corrcoef來(lái)確定最佳分類預(yù)測(cè)閾值。至于什么是matthews_corrcoef,這些都是你在解決問(wèn)題過(guò)程中需要學(xué)習(xí)和吸收的地方。總之,帶有目的性的讀某個(gè)項(xiàng)目的代碼往往是只讀某個(gè)block甚至是某幾個(gè)關(guān)鍵行,數(shù)量不在多,在于能夠解決你的問(wèn)題。
第二個(gè)場(chǎng)景就是為了自我個(gè)人精進(jìn)的讀代碼。所謂個(gè)人精進(jìn),就是有大量可支配的個(gè)人學(xué)習(xí)和研究時(shí)間,高度的自律性和超強(qiáng)的學(xué)習(xí)力的人進(jìn)行能力躍遷的關(guān)鍵所在。**筆者雖然平時(shí)偶爾會(huì)有去GitHub讀一些代碼,但說(shuō)要達(dá)到個(gè)人精進(jìn)的level,還遠(yuǎn)遠(yuǎn)不夠。比如說(shuō)前面的PyTorch 750k的源碼,這么大的代碼量,閱讀策略一定是分治思想,分散包圍和各個(gè)擊破。把項(xiàng)目進(jìn)行分解,設(shè)定閱讀計(jì)劃和目標(biāo),在超強(qiáng)的執(zhí)行力下還是有可能完成的。這不是普通人干的事,但我相信能在深度學(xué)習(xí)領(lǐng)域精進(jìn)的人都不會(huì)是普通人。
誠(chéng)然,無(wú)論是讀教材、讀論文還是本篇所說(shuō)的讀代碼,這些本身都是一個(gè)個(gè)人學(xué)習(xí)能力提升和知識(shí)汲取的過(guò)程。對(duì)于從事深度學(xué)習(xí)工作的我們而言,arxiv上的論文和GitHub上的代碼都無(wú)窮盡,關(guān)鍵在于保持學(xué)習(xí)的勁頭,做一名終身學(xué)習(xí)者。
本文原創(chuàng)首發(fā)于公眾號(hào)【機(jī)器學(xué)習(xí)實(shí)驗(yàn)室】,開(kāi)創(chuàng)了【深度學(xué)習(xí)60講】、【機(jī)器學(xué)習(xí)算法手推30講】和【深度學(xué)習(xí)100問(wèn)】三大系列文章。
一個(gè)算法工程師的成長(zhǎng)之路
長(zhǎng)按二維碼關(guān)注機(jī)器學(xué)習(xí)實(shí)驗(yàn)室
機(jī)器學(xué)習(xí)實(shí)驗(yàn)室的近期文章:
如何閱讀一份深度學(xué)習(xí)項(xiàng)目代碼?
如何部署一個(gè)輕量級(jí)深度學(xué)習(xí)項(xiàng)目?
基于C++的PyTorch模型部署
用Keras寫出像PyTorch一樣的DataLoader方法
PyTorch數(shù)據(jù)Pipeline標(biāo)準(zhǔn)化代碼模板
算法工程師的一天
夕小瑤的賣萌屋
_
關(guān)注&星標(biāo)小夕,帶你解鎖AI秘籍
訂閱號(hào)主頁(yè)下方「撩一下」有驚喜哦
總結(jié)
以上是生活随笔為你收集整理的怎样高效阅读一份深度学习项目代码?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MoCoV3:何恺明团队新作!解决Tra
- 下一篇: 格局打开,带你解锁 prompt 的花式