隨著機(jī)器學(xué)習(xí)(ML)在過去幾年的快速發(fā)展,開始ML實(shí)驗(yàn)變得非常容易。多虧了像scikit-learn和Keras這樣的庫,用幾行代碼就可以創(chuàng)建模型。
但是,將數(shù)據(jù)科學(xué)項(xiàng)目轉(zhuǎn)化為有意義的應(yīng)用程序比以往任何時候都更加困難,比如將模型轉(zhuǎn)化為團(tuán)隊(duì)決策或成為產(chǎn)品的一部分。典型的ML項(xiàng)目涉及到許多不同的技能集,對于任何一個人來說,如果不是完全不可能的話,那也是一種挑戰(zhàn)——如此困難,少有的同時還能開發(fā)高質(zhì)量軟件和游戲工程師的數(shù)據(jù)科學(xué)家被稱為獨(dú)角獸!
隨著這一領(lǐng)域的成熟,很多工作將需要軟件、工程和數(shù)學(xué)技能的結(jié)合,有些人說他們已經(jīng)這么做了。
引用一位無與倫比的數(shù)據(jù)科學(xué)家/工程師/評論家Vicki Boykis在她的博客data science is different now里的話:
越來越清楚的是,在炒作周期的后期階段,數(shù)據(jù)科學(xué)正逐漸接近工程,數(shù)據(jù)科學(xué)家需要的技能不再是可視化和基于統(tǒng)計(jì)的,而是與傳統(tǒng)的計(jì)算機(jī)科學(xué)課程更加一致。
為什么數(shù)據(jù)科學(xué)家需要了解DevOps
那么,在眾多的工程和軟件技能中,數(shù)據(jù)科學(xué)家應(yīng)該學(xué)習(xí)哪一種呢?我的錢花在DevOps上了。
DevOps是development和operations的合成詞,于2009年在比利時的一次會議上正式誕生。這次會議的召開是為了應(yīng)對科技公司在歷史上經(jīng)歷過深刻分歧的兩個方面之間的緊張關(guān)系。軟件開發(fā)人員需要快速行動并經(jīng)常進(jìn)行試驗(yàn),而運(yùn)維團(tuán)隊(duì)則優(yōu)先考慮服務(wù)的穩(wěn)定性和可用性(這些人讓服務(wù)器每天都在運(yùn)行)。他們的目標(biāo)不僅是對立,而且是競爭。
這聽起來很像今天的數(shù)據(jù)科學(xué)。數(shù)據(jù)科學(xué)家通過實(shí)驗(yàn)創(chuàng)造價值:數(shù)據(jù)建模、組合和轉(zhuǎn)換的新方法。與此同時,雇傭數(shù)據(jù)科學(xué)家的組織受到穩(wěn)定的激勵。
這種劃分的后果是深遠(yuǎn)的:在最新的Anaconda數(shù)據(jù)科學(xué)狀態(tài)”報(bào)告中,“不到一半(48%)的受訪者認(rèn)為他們可以證明數(shù)據(jù)科學(xué)對他們的組織的影響”。據(jù)估計(jì),絕大多數(shù)由數(shù)據(jù)科學(xué)家創(chuàng)建的模型最終都被束之高閣。我們還沒有強(qiáng)大的實(shí)踐來在創(chuàng)建模型的團(tuán)隊(duì)和部署模型的團(tuán)隊(duì)之間傳遞模型。數(shù)據(jù)科學(xué)家和實(shí)現(xiàn)他們工作的開發(fā)人員和工程師擁有完全不同的工具、約束條件和技能集。
DevOps的出現(xiàn)就是為了解決軟件中的這種僵局,就像開發(fā)人員vs運(yùn)維一樣。它取得了巨大的成功:許多團(tuán)隊(duì)已經(jīng)從每幾個月部署一次新代碼發(fā)展到一天部署幾次。既然我們已經(jīng)有了機(jī)器學(xué)習(xí)和操作,那么現(xiàn)在就該考慮MLOps了——來自DevOps的用于數(shù)據(jù)科學(xué)的原則。
引入持續(xù)集成
DevOps既是一種哲學(xué),也是一套實(shí)踐,包括:
- 自動化你所能做到的一切
- 快速獲得對新想法的反饋
- 減少工作流程中的手工交接
在一個典型的數(shù)據(jù)科學(xué)項(xiàng)目中,我們可以看到一些應(yīng)用:
- 自動化你所能做到的一切。自動化部分重復(fù)和可預(yù)測的數(shù)據(jù)處理、模型訓(xùn)練和模型測試。
- 快速獲得對新想法的反饋。當(dāng)你的數(shù)據(jù)、代碼或軟件環(huán)境發(fā)生變化時,立即在類似生產(chǎn)的環(huán)境(即具有預(yù)期在生產(chǎn)中具有的依賴關(guān)系和約束的機(jī)器)中進(jìn)行測試。
- 減少工作流程中的手工交接。為數(shù)據(jù)科學(xué)家尋找機(jī)會,盡可能多地測試他們自己的模型。不要等到有開發(fā)人員時才查看模型在類似生產(chǎn)環(huán)境中的行為。
實(shí)現(xiàn)這些目標(biāo)的標(biāo)準(zhǔn)DevOps方法是一種稱為持續(xù)集成(CI)的方法。
要點(diǎn)是,當(dāng)你更改項(xiàng)目的源代碼時(通常通過Git提交注冊更改),你的軟件將被自動構(gòu)建和測試。每個動作都會引發(fā)反饋。CI通常與Git-flow一起使用,Git-flow是一種開發(fā)架構(gòu),其中的新特性構(gòu)建在Git分支上。當(dāng)一個特性分支通過自動化測試時,它就成為了一個候選分支,可以合并到主分支中。
通過這種設(shè)置,我們有了自動化——代碼更改觸發(fā)一個自動構(gòu)建,然后進(jìn)行測試。我們有快速的反饋,因?yàn)槲覀兛梢钥焖俚玫綔y試結(jié)果,所以開發(fā)人員可以不斷迭代他們的代碼。而且因?yàn)樗羞@些都是自動發(fā)生的,你不需要等待其他人得到反饋——少了一個切換!
那么我們?yōu)槭裁床辉贛L中使用持續(xù)集成呢?一些原因是文化上的,比如數(shù)據(jù)科學(xué)和軟件工程社區(qū)之間的低交叉。其他的則是技術(shù)性的——例如,為了理解模型的性能,你需要查看諸如準(zhǔn)確性、特異性和敏感性等指標(biāo)。數(shù)據(jù)可視化可能會幫助你,比如混淆矩陣或損失圖。所以通過/失敗的測試不會減少反饋。理解一個模型是否得到了改進(jìn)需要一些關(guān)于手頭問題的領(lǐng)域知識,因此測試結(jié)果需要以一種有效的和可理解的方式進(jìn)行報(bào)告。
CI系統(tǒng)是如何工作的?
現(xiàn)在我們要更實(shí)際一些,讓我們看看典型的CI系統(tǒng)是如何工作的。對于學(xué)習(xí)者來說,幸運(yùn)的是,由于GitHub Actions和GitLab CI等工具的出現(xiàn),障礙從來沒有降低過——它們有清晰的圖形界面和為首次用戶準(zhǔn)備的優(yōu)秀文檔。由于GitHub操作對于公共項(xiàng)目是完全免費(fèi)的,所以我們將在本例中使用它。
它是這樣工作的:
1、你創(chuàng)建了一個GitHub存儲庫。你創(chuàng)建了一個名為.github/workflows的目錄,并在其中放置了一個特殊的.yaml文件,其中包含你想要運(yùn)行的腳本。
- $ python train.py
2、你可以以某種方式更改項(xiàng)目存儲庫中的文件,然后Git提交更改。然后,推到GitHub存儲庫。
- # Create a new git branch for experimenting
- $ git checkout -b "experiment"
- $ edit train.py
- # git add, commit, and push your changes
- $ git add . && commit -m "Normalized features"
- $ git push origin experiment
3、一旦GitHub檢測到push,GitHub就會部署他們的一臺計(jì)算機(jī)來運(yùn)行.yaml中的函數(shù)。
4、如果函數(shù)運(yùn)行成功或失敗,GitHub會返回一個通知。
在GitHub存儲庫的Actions選項(xiàng)卡中找到它
就是這樣!真正奇妙的是,你正在使用GitHub的計(jì)算機(jī)來運(yùn)行你的代碼。你所要做的就是更新代碼并將更改推送到存儲庫中,工作流就會自動發(fā)生。
回到我在第1步中提到的特殊的.yaml文件——讓我們快速查看一個。它可以有任何你喜歡的名稱,只要文件擴(kuò)展名是.yaml,并且它存儲在.github/workflows目錄中。這里有一個:
- # .github/workflows/ci.yaml
- name: train-my-model
- on: [push]
- jobs:
- run:
- runs-on: [ubuntu-latest]
- steps:
- - uses: actions/checkout@v2
- - name: training
- run: |
- pip install -r requirements.txt
- python train.py
有很多操作在進(jìn)行,但大多數(shù)操作都是相同的——你可以復(fù)制粘貼這個標(biāo)準(zhǔn)的GitHub動作模板,但在“運(yùn)行”字段中填寫你的工作流。
如果這個文件在你的項(xiàng)目repo中,每當(dāng)GitHub檢測到對你的代碼的更改(通過push注冊),GitHub Actions就會部署一個Ubuntu運(yùn)行程序,并嘗試執(zhí)行你的命令來安裝需求并運(yùn)行Python腳本。請注意,你必須在項(xiàng)目repo中包含你的工作流所需的文件——這里是requirementes .txt和train.py。
得到更好的反饋
正如我們之前提到的,自動訓(xùn)練是非??岬?,但重要的是要有一個容易理解的形式的結(jié)果。目前,GitHub操作允許你訪問運(yùn)行的純文本日志。
但是理解你的模型的性能是很棘手的。模型和數(shù)據(jù)是高維的,并且通常是非線性的——如果沒有圖片,這兩件事是特別難以理解的。
我可以向你展示一種將數(shù)據(jù)viz放入CI循環(huán)的方法。在過去的幾個月里,我的團(tuán)隊(duì)在Iterative.ai(我們做數(shù)據(jù)版本控制)正在開發(fā)一個工具包,幫助在機(jī)器學(xué)習(xí)項(xiàng)目中使用GitHub動作和GitLab CI。它被稱為持續(xù)機(jī)器學(xué)習(xí)(簡稱CML),并且是開源免費(fèi)的。
從“讓我們使用GitHub動作來訓(xùn)練ML模型”的基本思想出發(fā),我們構(gòu)建了一些函數(shù)來提供比通過/失敗通知更詳細(xì)的報(bào)告。CML幫助你在報(bào)告中放入圖像和表格,就像這個由SciKit-learn生成的混淆矩陣:
為了制作這個報(bào)告,我們的GitHub操作執(zhí)行了一個Python模型訓(xùn)練腳本,然后使用CML函數(shù)將我們的模型準(zhǔn)確性和混淆矩陣寫入一個markdown文檔。然后CML將減價文檔傳遞給GitHub。
我們修改后的.yaml文件包含以下工作流(新添加的行被加粗以示強(qiáng)調(diào)):
- name: train-my-model
- on: [push]
- jobs:
- run:
- runs-on: [ubuntu-latest]
- container: docker://dvcorg/cml-py3:latest
- steps:
- - uses: actions/checkout@v2
- - name: training
- env:
- repo_token: ${{ secrets.GITHUB_TOKEN }}
- run: |
- # train.py outputs metrics.txt and confusion_matrix.png
- pip3 install -r requirements.txt
- python train.py
- # copy the contents of metrics.txt to our markdown report
- cat metrics.txt >> report.md
- # add our confusion matrix to report.md
- cml-publish confusion_matrix.png --md >> report.md
- # send the report to GitHub for display
- cml-send-comment report.md
你可以在這里看到整個項(xiàng)目存儲庫。注意,我們的.yaml現(xiàn)在包含更多的配置細(xì)節(jié),比如一個特殊的Docker容器和一個環(huán)境變量,以及一些要運(yùn)行的新代碼。容器和環(huán)境變量細(xì)節(jié)在每個CML項(xiàng)目中都是標(biāo)準(zhǔn)的,而不是用戶需要操作的東西,所以請關(guān)注代碼。
在工作流中添加了這些CML功能后,我們在CI系統(tǒng)中創(chuàng)建了一個更完整的反饋循環(huán):
- 創(chuàng)建一個Git分支并更改該分支上的代碼。
- 自動訓(xùn)練模型并產(chǎn)生度量(準(zhǔn)確性)和可視化(混淆矩陣)。
- 將這些結(jié)果嵌入到Pull請求的可視報(bào)告中。
現(xiàn)在,當(dāng)你和你的團(tuán)隊(duì)成員決定你的變更是否對你的建模目標(biāo)有積極的影響時,你就有了一個可以檢查的儀表板。另外,Git還將此報(bào)告鏈接到你的確切項(xiàng)目版本(數(shù)據(jù)和代碼)、用于訓(xùn)練的跑步器以及那次運(yùn)行的日志。很徹底,不再有那些很久以前就失去了與代碼的任何連接的圖形在你的工作空間中浮動。
這就是數(shù)據(jù)科學(xué)項(xiàng)目中CI的基本思想。明確地說,這個示例是使用CI的最簡單方法之一。在現(xiàn)實(shí)生活中,你可能會遇到相當(dāng)復(fù)雜的場景。CML還有一些功能可以幫助你使用存儲在GitHub存儲庫之外的大型數(shù)據(jù)集(使用DVC),并在云實(shí)例上進(jìn)行訓(xùn)練,而不是使用默認(rèn)的GitHub動作運(yùn)行器。這意味著你可以使用GPU和其他專門的設(shè)置。
例如,我做了一個使用GitHub Actions部署EC2 GPU的項(xiàng)目,然后訓(xùn)練一個神經(jīng)類型的傳輸模型。以下是我的CML報(bào)告:
你還可以使用自己的Docker容器,這樣就可以在生產(chǎn)中緊密地模擬模型的環(huán)境。以后我將更多地介紹這些高級用例。
關(guān)于ML的CI的最后思考
總結(jié)一下我們到目前為止所說的:
DevOps不是一種特定的技術(shù),而是一種哲學(xué)、一套原則和實(shí)踐,用于從根本上重構(gòu)創(chuàng)建軟件的過程。它之所以有效,是因?yàn)樗鉀Q了團(tuán)隊(duì)如何工作和試驗(yàn)新代碼的系統(tǒng)瓶頸。
隨著數(shù)據(jù)科學(xué)在未來幾年的成熟,懂得如何將DevOps原則應(yīng)用到他們的機(jī)器學(xué)習(xí)項(xiàng)目中的人將成為一種有價值的商品——無論是從薪水還是從組織影響的角度。持續(xù)集成是DevOps的主要內(nèi)容,也是構(gòu)建具有可靠自動化、快速測試和團(tuán)隊(duì)自治的文化的最有效的已知方法之一。
CI可以通過GitHub Actions或GitLab CI等系統(tǒng)實(shí)現(xiàn),你可以使用這些服務(wù)來構(gòu)建自動模型培訓(xùn)系統(tǒng)。好處很多:
- 你的代碼、數(shù)據(jù)、模型和培訓(xùn)基礎(chǔ)設(shè)施(硬件和軟件環(huán)境)都是Git版本化的。
- 你正在自動化工作,頻繁地進(jìn)行測試并獲得快速的反饋(如果使用CML,則使用可視化的報(bào)告)。從長遠(yuǎn)來看,這幾乎肯定會加速項(xiàng)目的開發(fā)。
- CI系統(tǒng)使你的工作對團(tuán)隊(duì)中的每個人都可見。沒有人需要非常費(fèi)力地搜索你的最佳運(yùn)行的代碼、數(shù)據(jù)和模型。
我保證,一旦你進(jìn)入最佳狀態(tài),通過一個Git提交自動啟動你的模型訓(xùn)練、記錄和報(bào)告是非常有趣的。
你會覺得很酷。