編者按:機(jī)器學(xué)習(xí)科學(xué)家分享了使用git管理數(shù)據(jù)科學(xué)試驗(yàn)的經(jīng)驗(yàn)。
引言
版本控制是管理數(shù)據(jù)科學(xué)試驗(yàn)的關(guān)鍵工具。但是,魔鬼在細(xì)節(jié)之中。這篇文章將討論如何在數(shù)據(jù)科學(xué)項(xiàng)目中實(shí)現(xiàn)版本控制。
git的使用有好幾種范式,就數(shù)據(jù)科學(xué)試驗(yàn)而言,我基本上根據(jù)的是特性分支這一范式。簡單來說,特性分支意味著有一個(gè)master分支(主分支)作為基礎(chǔ),新特性通過在主分支上分支的方式加入代碼基,做出實(shí)現(xiàn)特性需要的所有改動(dòng)后,合并新分支至主分支。
策略
我為每個(gè)試驗(yàn)或者想要嘗試的新建模思路創(chuàng)建一個(gè)新分支。這時(shí)你需要有意識(shí)地決策:代碼的修改只適用于這次試驗(yàn),還是希望在這次試驗(yàn)和之前的試驗(yàn)上都適用?換一種表述方式:你是打算替換,還是增益?這個(gè)問題的答案將決定你是否可以把新分支合并回主分支。
我建議額外花一點(diǎn)功夫,將關(guān)鍵組件提取出來,作為一個(gè)庫,在多次試驗(yàn)中復(fù)用。這比有許多份相同(或者更糟,略有不同)的代碼要好很多,不用分別維護(hù),也不易導(dǎo)致錯(cuò)誤。俗話說得好,最好的代碼是沒有代碼。將關(guān)鍵組件提取至一個(gè)共享庫,你可以逐漸做出改進(jìn),并最終得到一個(gè)內(nèi)聚的代碼基,可以在一系列試驗(yàn)復(fù)用。相反,如果你不斷引入不向后兼容的改動(dòng),你會(huì)發(fā)現(xiàn)自己頻繁地在分支間跳轉(zhuǎn),以便復(fù)制/粘貼有用的代碼片段,接著卻需要加以修改,因?yàn)榻M件沒有設(shè)計(jì)成能夠一起工作的。在較大的試驗(yàn)中,這會(huì)變得很難操作。
特性分支這一方法的優(yōu)勢在于你可以將試驗(yàn)分支合并回主分支,接著運(yùn)行任何試驗(yàn)。這么做的代價(jià)是,當(dāng)你對(duì)核心庫進(jìn)行改動(dòng)時(shí),你也許需要同時(shí)修改其他試驗(yàn)的實(shí)現(xiàn)。所以,和所有事情一樣,這是一個(gè)需要做出權(quán)衡的決策。在我的經(jīng)驗(yàn)中,這個(gè)方法能夠自然地演化,我發(fā)現(xiàn),每當(dāng)我想要復(fù)制粘貼的時(shí)候,都會(huì)想一下能否提取公共代碼。
例子
我推薦如下的目錄結(jié)構(gòu):
|-- core/
|-- tests/
|-- test_pull_data.py
|-- test_prepare_data.py
|-- test_model.py
|-- test_deploy.py
|-- test_utils.py
|-- pull_data.py
|-- prepare_data.py
|-- model.py
|-- deploy.py
|-- utils.py
|-- experiment_1/
|-- data/
|-- training.csv
|-- validation.csv
|-- test.csv
|-- output/
|-- results.json
|-- models/
|-- model1
|-- model2
|-- job_config.py
|-- build_data.py
|-- train.py
|-- evaluate.py
|-- prod.py
|-- experiment_2/
|-- data/
|-- training.csv
|-- validation.csv
|-- test.csv
|-- output/
|-- results.json
|-- models/
|-- model1
|-- model2
|-- job_config.py
|-- build_data.py
|-- train.py
|-- evaluate.py
|-- prod.py
在這一情形中,主要邏輯位于core目錄下。試驗(yàn)以目錄的形式組織,其中包含為試驗(yàn)執(zhí)行核心邏輯的代碼,以及相應(yīng)的輸入、輸出文件。實(shí)現(xiàn)代碼應(yīng)該極為簡單,只做具體試驗(yàn)特定的事情。例如,如果試驗(yàn)是要比較A方法和B方法,那么它會(huì)引入A和B的配置,從核心實(shí)例化相關(guān)代碼,并調(diào)用每個(gè)示例的run方法。
注意這個(gè)結(jié)構(gòu)很自然地提供了實(shí)現(xiàn)單元/功能/集成測試的地方。此外,單是提取通用組件至可復(fù)用的庫這一行動(dòng)就有助于使代碼更容易測試。由于代碼傾向于基于參數(shù),而非依賴硬編碼的試驗(yàn)細(xì)節(jié),為測試創(chuàng)建玩具樣本就要容易很多。以后我會(huì)寫一篇文章,深入討論如何為數(shù)據(jù)科學(xué)項(xiàng)目寫測試。
竅門
下面是一些我覺得在實(shí)踐中比較有用的簡單竅門。
.gitignore
.gitignore告訴git忽略哪些文件。在開始一個(gè)新項(xiàng)目時(shí),應(yīng)該優(yōu)先配置.gitignore。因?yàn)橐坏┠闾峤涣舜牢铮蜁?huì)永遠(yuǎn)呆在代碼倉庫之中(除非你采取了一些特殊行動(dòng))。
最重要的是除外敏感信息,比如密碼和API密鑰。如果你早早地提交了包含敏感信息的文件,那么它很快就會(huì)變成一場噩夢。從當(dāng)前快照刪除文件無濟(jì)于事——你需要從所有之前的提交中清除敏感信息。對(duì)自己好一點(diǎn),避免去學(xué)如何做到這一點(diǎn)。
下一步是忽略非常大的數(shù)據(jù)文件和你不需要追蹤的不重要文件(例如,notebook檢查點(diǎn),IDE的配置文件,pycache,.pyc,等等)。在上面的例子中,所有輸入輸出文件也應(yīng)該忽略,因?yàn)樗鼈兺耆梢杂纱a本身確定,如果需要,可以重新生成。
頻繁提交
如果你完成了合理數(shù)量的工作,提交一次。不要吝嗇,頻繁提交也許能幫助你避免堵塞。
明晰的提交信息
如果你提交得足夠頻繁,那么你的工作大概也會(huì)相當(dāng)集中,這樣提交信息可以寫得更清晰。回溯不想要的改動(dòng)時(shí),再?zèng)]有比根據(jù)恰當(dāng)注解的提交歷史快速找到目標(biāo)更令人滿足的了。如果你找到的描述是這樣的:“實(shí)現(xiàn)了3個(gè)新特性,增加了dropout,創(chuàng)建了交叉驗(yàn)證組件,同時(shí)重構(gòu)了訓(xùn)練邏輯”,那么你提交得不夠頻繁。
反饋
我在嘗試不同策略的過程中逐漸積累了這些想法。如果你有不同的做法,歡迎留言分享!
-
代碼
+關(guān)注
關(guān)注
30文章
4823瀏覽量
68935 -
數(shù)據(jù)科學(xué)
+關(guān)注
關(guān)注
0文章
166瀏覽量
10084
原文標(biāo)題:如何使用git管理數(shù)據(jù)科學(xué)項(xiàng)目
文章出處:【微信號(hào):jqr_AI,微信公眾號(hào):論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論