圖片描述git
「觀遠AI實戰」
欄目文章由觀遠數據算法天團傾力打造,觀小編整理編輯。這裏將不按期推送關於機器學習,數據挖掘,特徵重要性等乾貨分享。本文8千多字,約須要16分鐘閱讀時間。
機器學習做爲時下最爲火熱的技術之一受到了普遍的關注。咱們天天打開公衆號都能收到各類前沿進展、論文解讀、最新教程的推送。這些文章中絕大多數內容都跟酷炫的新模型、高大上的數學推導有關。可是Peter Norvig說過,「We don’t have better algorithms. We just have more data.」。在實際機器學習應用中,對最終結果起到決定性做用的每每是精心收集處理的高質量數據。github
從表面看好像也不難,但略微深究就會發現機器學習系統與傳統的軟件工程項目有着很是大的差別。除了廣受矚目的模型算法,良好的工程化思考與實現是最終達到機器學習項目成功的另外一大關鍵因素。算法
谷歌在2015年發表的論文《Hidden Technical Debt in Machine Learning Systems》中就很好的總結了機器學習工程中的各類不佳實踐致使的技術債問題。主要有如下幾種:安全
在傳統的軟件工程中,通常會進行細緻的設計和抽象,對於系統的各個組成部分進行良好的模塊劃分,這樣整個系統的演進和維護都會處於一個比較可控的狀態。但機器學習系統自然就與數據存在必定程度的耦合,加上自然的交互式、實驗性開發方式,很容易就會把數據清洗、特徵工程、模型訓練等模塊耦合在一塊兒,牽一髮而動全身,致使後續添加新特徵,作不一樣的實驗驗證都會變得愈來愈慢,愈來愈困難。多線程
傳統的軟件工程開發中,能夠很方便的經過編譯器,靜態分析等手段獲取到代碼中的各類依賴關係,快速發現不合理的耦合設計,而後藉助於單元測試等手段快速重構改進。在機器學習系統中這類代碼耦合分析一樣不可或缺。除此以外還多了數據依賴問題。架構
好比銷售預測系統可能會對接終端POS系統數據,也會引入市場部門的營銷數據,還有倉儲、運輸等等多種數據來源。在大多數狀況下這些數據源都是不一樣部門維護的,不受數據算法團隊的控制,指不定哪天就悄悄作了一個變動。若是變動很大,可能在作數據處理或者模型訓練時會直接拋出錯誤,但大多數狀況下你的系統仍是能正常運行,而獲得的訓練預測結果極可能就有問題了。框架
在一些複雜業務系統中,這些數據自己還會被加工成各類中間數據集,同時被幾個數據分析預測任務共享,造成複雜的依賴關係網,進一步加大了數據管理的難度。機器學習
膠水代碼:隨着各類開源項目的百花齊放,不少機器學習項目都會調用各類開源庫來作數據處理、模型訓練、參數調優等環節。因而天然而然在整個項目中大量的代碼都是爲了把這些不一樣的開源庫粘合在一塊兒的膠水代碼,一樣會致使以前提到過的邊界模糊,與特定的庫緊耦合,難以替換模塊快速演進等問題。分佈式
流水線叢林:在數據處理特徵工程與模型調優的迭代演進過程當中,稍不注意你的整個系統流水線就會變得無比冗長,各類中間結果的寫入和先後依賴極其複雜。這時候想添加一個新特徵,或是調試某個執行失敗都變得如此困難,逐漸迷失在這混亂的叢林中……若是隻具有機器學習知識而缺乏工程經驗,用這種作實驗的方式來開發系統顯然是不靠譜的,必須有良好的工程化思惟,從整體上把控代碼模塊結構,才能更好的平衡實驗的靈活性與系統開發效率,保證總體的高效運做。 函數
失效的實驗性代碼路徑:這一點也是承接前面,不少時候若是以跑實驗的心態來給系統「添磚加瓦」,極可能到後面各類小徑交叉的代碼庫就這麼出現了,誰都搞不清楚哪些代碼有用哪些是不會執行到的。如何復現別人的實驗結果,要用哪些數據集和特徵,設置哪些變量、作哪些微調都會成爲難解之謎。
缺少好的系統抽象:我的以爲sklearn的各類API設計還算蠻好的,如今不少其它庫的高層API都參考了這個準業界標準來實現。文中主要提到在分佈式訓練中缺少一個很好的業界標準,好比MapReduce顯然是不行的,Parameter Server看起來還算靠譜但也還未成爲標準。沒有好的抽象標準也就致使了各類庫在功能、接口設計時不一致,從而有了以上提到的一系列邊界模糊,膠水代碼等問題。
相對於傳統軟件系統,機器學習系統的配置項每每會更多更復雜。好比要使用哪些特徵、各類數據選擇的規則、複雜的預處理和後置處理、模型自己的各類參數設置等等。所以除了工程代碼外,配置項的精心設計、評審也成了一個不容忽視的點。不然很容易形成系統在實際運行中頻繁出錯,難以使用。
機器學習系統不少時候都是直接與外部世界的數據作交互,而外部世界老是變化無常。並且機器學習系統自己的輸出也會影響到外部世界,從而進一步回饋到機器學習系統的輸入中來。好比推薦系統給用戶展現的內容會影響用戶的點擊行爲,而這些點擊瀏覽行爲又會成爲訓練數據輸入到推薦系統來。如何獲取到外部世界變化的信息,進而及時改進甚至自動更新算法模型就成了一個很是重要的問題。
在谷歌的這篇原始論文中對各類坑都給了一些解決的建議,概括總結一下,整體上來講就是要轉變團隊總體的文化氛圍,強調良好的工程思惟和實踐。一個設計良好的機器學習項目系統中每每真正跟機器學習相關的代碼只佔了很小的一部分。
圖片描述
新模型當然酷炫,可是機器學習工程實踐的總結與推廣與它在整個項目中扮演的角色的重要性顯然是不成正比的。因此今天咱們要着重來說一下這個方面:機器學習系統的最佳工程實踐是什麼樣的?
這時候就要請出谷歌的另一篇論文《The ML Test Score》了。前一篇論文在具體實踐落地方面缺少細節,在這篇論文裏,谷歌總結了28個很是具體的機器學習系統相關工程實踐準則,可謂是乾貨滿滿,十分接地氣。
文中給出的28個建議都是針對機器學習系統的,沒有包含通用軟件工程裏那些單元測試,發佈流程等內容,在實踐中這些傳統最佳實踐也一樣很是重要。這些實踐在谷歌內部團隊普遍使用,但沒有一個團隊執行的覆蓋率超過80%,所以這些測試點都是很是值得關注並有必定的實踐難度的。
特徵指望值編寫到schema中:不少特徵的分佈狀況或數值指望是有一些先驗知識能夠去校驗的。好比通常人身高都在0-3米的範圍內、英語中最多見的詞是」the」、總體的詞頻通常服從冪律分佈等。咱們能夠把這些先驗領域知識,或是從訓練集中計算出的數學指望值編寫在數據schema文件中,後續對於新的輸入數據,構建完特徵後的模型訓練數據以及最終上線使用模型時都能進行自動化的檢查,避免由於數據不符合預期而致使的錯誤預測狀況。
確保全部的特徵都是有用的:在以前的機器學習技術債論文中也有提到研發人員老是傾向於不斷往系統中添加新的特徵,尤爲在上線時間比較緊迫的狀況下,缺乏細緻的特徵選擇和有效性驗證工做。這會致使特徵數量愈來愈多,構建訓練集須要花費的時間也愈來愈長,後續的維護成本也會更高。因此跟業務代碼同樣,沒有幫助的特徵也要及時清理,輕裝前行。文中給出的方法基本是常見的特徵選擇法,好比計算特徵相關度,使用單獨或小批量特徵來跑模型看是否有預測能力等。
去除性價比低的特徵:計算添加任何一個特徵都須要消耗資源,包括生成和訓練模型開銷,模型預測開銷,甚至還要考慮到對上游數據的依賴,額外的庫函數引入,特徵自己的不穩定性等等。對於任何一個特徵的添加,都要綜合考慮這些開銷與它能帶來的性能提高來決定是否引入。若是隻是很是有限的效果提高,咱們應該果斷放棄那些過於複雜的特徵。
特徵必須遵循業務規範需求:不一樣的項目對機器學習系統可使用的數據可能有不一樣的規範需求,好比可能有些業務禁止咱們使用從用戶數據中推演出來的特徵。因此咱們也須要從代碼工程層面把這些規範需求進行實現,以免訓練與線上特徵出現不一致或違反了業務規範等問題。
數據流水線必須有完善的隱私控制:與上一條相似,機器學習系統從數據源獲取用戶相關隱私數據時已經經過了相應的控制校驗,後續在系統內部流水線作處理時咱們也要時刻注意對隱私數據的訪問控制。好比各類中間數據集,數據字典的存放與訪問控制,上游系統的用戶數據刪除可以級聯更新到機器學習系統的整個鏈路中,諸如此類須要特別注意的問題。
可以快速開發新特徵:一個新特徵從提出到實現,測試,上線的整個流程所須要花費的時間決定了整個機器系統迭代演進,響應外部變化的速度。要實現這一點,良好的工程結構、不一樣模塊的抽象設計都是很是重要的。文中沒有給具體的例子,不過咱們能夠借鑑sklearn中pipeline模塊設計的思想,以及相似FeatureHub這樣的開源系統的實現來不斷優化完善特徵工程實踐。
爲特徵工程代碼寫相應的測試:在實驗探索階段,咱們常常會寫完一個特徵以後,粗略地取樣一些數據,大體驗證經過後就認爲這個特徵基本沒有問題了。但這其中可能就隱藏了很多bug,並且不像業務代碼中的錯誤,要發現這些bug極其困難。因此必須養成良好的習慣,在特徵開發階段就寫好相應的測試代碼,確保特徵的正確性,後續應對各類系統變動也都能很快經過測試來進行快速驗證。
圖片描述
模型說明必須經過review並記錄在案:隨着機器學習模型技術的發展,各類複雜模型,大量的參數配置每每讓模型訓練和執行變得無比複雜。加上在多人協同的項目中,不少時候須要使用不一樣的數據,或者作一些特定的調整來從新評估模型效果,這時候有詳細的模型說明記錄就顯得尤其重要了。除了簡單的文本記錄,市面上也有很多開源項目(好比ModelDB,MLflow等)專一於幫助開發者管理模型,提升實驗的可復現性。
模型優化指標與業務指標一致:不少機器學習的應用業務中,實際的業務指標並不能直接拿來做爲目標函數優化,好比業務營收,用戶滿意度等等。所以大多數模型在優化時都會選擇一個「代理指標」,好比用戶點擊率的logloss之類。所以在建模,評估過程當中必需要考慮到這個代理指標與真實業務指標是否有比較強的正相關性。咱們能夠經過各類A/B測試來進行評估,若是代理指標的改進沒法提高真正的業務指標,就須要及時進行調整。
調優模型超參數:這點相信你們都會作,畢竟各類機器學習教程中都會有很大篇幅講解如何進行調參來提高模型效果。值得注意的是除了暴力的網格搜索,隨機搜索一樣簡單而效果每每更好。另外還有許多更高級的算法例如貝葉斯優化,SMAC等也能夠嘗試使用。對於同一個數據集,在使用不一樣的特徵組合,數據抽樣手段的時候理論上來講都應該進行參數調優以達到最佳效果。這部分的工做也是比較容易經過自動化工具來實現的。
對模型時效性有感知:對於不少輸入數據快速變化的業務例如推薦系統,金融應用等,模型的時效性就顯得極其重要了。若是沒有及時訓練更新模型的機制,整個系統的運行效果可能會快速降低。咱們能夠經過保留多個版本的舊模型,使用A/B測試等手段來推演模型效果與時間推移的關係,並以此來制定總體模型的更新策略。
模型應該優於基準測試:對於咱們開發的複雜模型,咱們應該時常拿它與一些簡單的基準模型進行測試比較。若是須要花費大量精力調優的模型效果相比簡單的線性模型甚至統計預測都沒有明顯提高的話,咱們就要仔細權衡一下使用複雜模型或作進一步研發改進的必要性了。
模型效果在不一樣數據切片上表現都應達標:在驗證模型效果時,咱們不能僅依賴於一個整體的驗證集或是交叉驗證指標。應該在不一樣維度下對數據進行切分後分別驗證,便於咱們對模型效果有更細粒度上的理解。不然一些細粒度上的問題很容易被整體統計指標所掩蓋,同時這些更細粒度的模型問題也能指導咱們作進一步細化模型的調優工做。例如將預測效果根據不一樣國家的用戶,不一樣使用頻率的用戶,或者各類類別的電影等方式來分組分析。具體劃分方式能夠根據業務特色來制定,並同時考察多個重要的維度。咱們能夠把這些測試固化到發佈流程中,確保每次模型更新不會在某些數據子集中有明顯的效果降低。
將模型的包容性列入測試範圍:近些年來也有很多關於模型包容性,公平性相關問題的研究。例如咱們在作NLP相關問題時一般會使用預訓練的word embedding表達,若是這些預訓練時使用的語料與真實應用的場景有誤差,就會致使相似種族,性別歧視的公平性問題出現。咱們能夠檢查輸入特徵是否與某些用戶類別有強關聯性,還能夠經過模型輸出的切分分析,去判斷是否對某些用戶組別有明顯的差別對待。當發現存在這個問題時,咱們能夠經過特徵預處理(例如文中提到的embedding映射轉換來消除例如性別維度的差別),模型開發中的各類後置處理,收集更多數據以確保模型能學習到少數羣體的特性等方式來解決這個問題。
圖片描述
模型訓練是可復現的:在理想狀況下,咱們對同一份數據以一樣的參數進行模型訓練應該能獲取到相同的模型結果。這樣對於咱們作特徵工程重構驗證等都會很是有幫助。但在實際項目中作到穩定復現卻很是困難。例如模型中用到的隨機數種子,模型各部分的初始化順序,多線程/分佈式訓練致使的訓練數據使用順序的不肯定性等都會致使沒法穩定復現的問題。所以咱們在實際工程中對於這些點都要額外注意。好比凡是用到了隨機數的地方都應該暴露接口方便調用時進行隨機數種子的設置。除了儘可能寫能肯定性運行的代碼外,模型融合也能在必定程度上減輕這個問題。
模型說明代碼須要相應測試:雖然模型說明代碼看起來很像「配置文件」,但其中也可能存在bug,致使模型訓練沒有按預期方式執行。並且要測試這種模型說明代碼也很是困難,由於模型訓練每每牽涉到很是多的外部輸入數據,並且一般耗時較長。文中提到谷歌將會開源一些相關的框架來幫助作相關的測試,一些具體的測試方法以下:
機器學習pipeline的集成測試:一個完整的機器學習pipeline通常會包括訓練數據的收集,特徵生成,模型訓練,模型驗證,部署和服務發佈等環節。這些環節先後都會有必定交互影響,所以須要集成測試來驗證整個流程的正確性。這些測試應該包括在持續集成和發佈上線環節。爲了節約執行時間,對於須要頻繁執行的持續集成測試,咱們能夠選擇少許數據進行驗證,或者是使用較爲簡單的模型以便於開發人員快速驗證其它環節的修改不會引發問題。而在發佈流程中仍是須要使用與生產環境儘量一致的配置來執行總體的集成測試。
模型上線前必須驗證其效果:這點看起來應該是你們都會遵照的原則。惟一要注意的是須要同時驗證模型的長期效果趨勢(是否有緩慢性能降低),以及與最近一個版本對比是否有明顯的性能降低。
模型可以對單個樣本作debug:這個就有點厲害了,當你發現一個奇怪的模型輸出時,你怎麼去尋找問題的緣由?這時候若是有一個方便的工具能讓你把這個樣本輸入到模型中去,單步執行去看模型訓練/預測的過程,那將對排查問題帶來極大的便利和效率提高。文中提到TensorFlow自帶了一個debugger,在實際工做中咱們也會使用eli5,LIME之類的工具來作黑盒模型解釋,但從方便程度和效果上來講確定仍是比不上框架自帶的排查工具。
模型上線前的金絲雀測試:這點在傳統軟件工程中基本也是標配,儘管咱們有測試環境,預發佈環境的各類離線測試,模型在正式上線時仍是須要在生產環境中跑一下簡單的驗證測試,確保部署系統可以成功加載模型併產出符合預期的預測結果。在此基礎上還能夠進一步使用灰度發佈的方式,逐漸把流量從舊模型遷移到新模型上來,增長一層保障。
模型可以快速回滾:與其它傳統軟件服務同樣,模型上線後若是發現有問題應該可以快速,安全回滾。要作到這點必須在開發時就確保各類上下游依賴的兼容性。而且回滾演練自己也應該成爲常規發佈測試的一環,而不是到出了問題纔去手毛腳亂的操做,引出更多意料以外的問題。
圖片描述
依賴變動推送:機器學習系統通常都會大量依賴於各類外部系統提供的數據,若是這些外部系統的數據格式,字段含義等發生了變化而咱們沒有感知,很容易就會致使模型訓練和預測變得不符合預期。所以咱們必須訂閱這些依賴系統的變動推送,並確保其它系統的維護者知曉咱們在使用他們提供的數據。
訓練與線上輸入數據分佈的一致性:雖然模型內部運做過程極爲複雜,難以直接監控其運行時正確性,可是模型的輸入數據這塊仍是比較容易監控的。咱們能夠用以前定義的特徵數據schema文件來對線上輸入數據進行檢測,當出現較大誤差時自動觸發告警,以便及時發現外部數據的變化狀況。
訓練與線上服務時生成的特徵值一致:在機器學習項目中常常會出現同一個特徵在訓練時和在線上使用時所採用的計算生成方式是不同的。好比在訓練時特徵是經過處理以前的歷史日誌計算出來的,而到了線上的時候一樣的特徵可能來自於用戶實時的反饋。或者是訓練時採用的特徵生成函數是很是靈活,易於作各類實驗嘗試的,而到了線上則改用固化的優化計算性能版本以下降服務響應時間。在理想狀況下,雖然採用了不一樣的計算方式,但生成的特徵值應該是相同的,不然就會出現訓練和預測使用的數據有偏移,致使模型效果變差等問題。因此咱們須要經過各類手段來監控線上線下數據的一致性。
例如能夠經過對線上數據進行採樣打標記錄,來與訓練集中的對應條目進行直接比較,計算出有誤差的特徵數量,及這些特徵中相應的有誤差的樣本佔比數量。另外也能夠經過計算線上線下各個特徵的統計分佈的差異來衡量是否有這類問題的產生。
模型的時效性:這一點與以前的模型測試中的時效性相似,咱們能夠直接使用其中獲取到的模型效果與時間推移關係來推斷理想狀況下模型訓練更新的頻率,並以此來對模型持續運行時間進行監控和告警。要注意過長的更新週期會提高模型的維護難度。另外哪怕模型自己更新比較可控,可是模型依賴的數據源也有相似的時效性問題,咱們一樣須要對其進行監控以避免出現數據過時的問題。
數值穩定性:在模型訓練中可能會在沒有任何報錯的狀況下出現奇怪的NaN,inf值,致使非預期的參數更新甚至最終獲得不可用的模型。所以咱們須要在訓練中監控任何訓練數據中包含NaN或者inf的狀況進行適當的處理。同時對於各模型參數的取值範圍,ReLU層後輸出爲0的單元數量佔比等指標進行檢測,一旦超出預期範圍就進行告警,便於及時定位排查相關問題。
模型性能相關監控:機器學習模型的訓練速度,預測響應時間,系統吞吐量,以及內存佔用等性能指標對於總體系統的可擴展性來講都是相當重要的。尤爲是隨着數據量的愈來愈大,愈來愈複雜模型的引入,更加重了各類性能問題的出現。在模型演進,數據變化以及基礎架構/計算庫的更迭中,須要咱們謹慎的評估模型性能變化,進行快速響應。在作性能監控時不但要注意不一樣代碼組件,版本的表現,也要關注數據和模型版本的影響。並且除了容易檢測到的性能突變,長期,緩慢的性能降低也須要引發足夠的重視。
模型預測質量的迴歸問題:整體的目標是但願新部署的模型相對於過去的模型在預測性能上沒有降低。但驗證集相對於線上的真實狀況來講老是有所區別的,只能做爲一個性能評估的參考。文中列舉了幾種手段來作監控:
最後總結一下前面提到的各類監控,基本上還有兩個共通點,一是各類告警的閾值要作精心選擇,太低的閾值容易出現警報氾濫致使根本沒人去管的狀況,而太高的閾值又會掩蓋系統中已經存在的各類問題。二是除了短期內明顯的指標急劇降低外,同時也要關注長期的緩慢的降低,後者更難以發現,應該引發足夠的重視。
圖片描述
文章後續還給出了這28個測試指標的具體評分標準,幫助你們在實踐中更好的對照,應用這些最佳實踐。還有不少在谷歌內部使用這套評分系統的各類反饋,以及他們各個團隊的平均得分狀況等。
圖片描述
對於這個平均得分狀況,做者強力安利了一把谷歌自家的TFX。
圖片描述
好比基礎架構的集成測試,谷歌內部的得分也很低(滿分爲1的狀況下平均爲0.2分)。TFX能夠方便的實現整個工程的pipeline,天然也很容易在此基礎上完成相應的集成測試了。除了TFX,像Uber的Michelangelo,Facebook的FBLearner Flow也都是相似的機器學習平臺,雖然沒有開源,但都有比較詳細的介紹文章能夠學習參考。
![圖片描述][9]
這些框架基本能夠看做各家公司作機器學習工程的最佳實踐總結,整體架構基本都遵循「數據管理->模型訓練->模型測試驗證->部署上線」這樣的流程。不過他們在具體設計實現上各有千秋,例如文中做者認爲「線下線上訓練數據分佈誤差監控」是最爲重要但卻鮮有實現的一個測試點,在不少項目組都曾經由於缺乏這個監控而出現過屢次線上故障。所以TFX提供了數據驗證模塊來專門解決這個問題。而像Uber的Michelangelo則側重快速開發特徵這個點引入了Feature Store模塊。在實際應用中咱們能夠根據不一樣的業務特色靈活的選擇工程方案來進行實現。
參考資料:https://papers.nips.cc/paper/...
https://ai.google/research/pu...
本文做者:觀遠數據算法天團-zijie
關注機器學習與分佈式系統方向
知乎號:zijie0 | Blog:zijie0.github.io
觀遠數據合夥人 / 知乎5000贊文章博主
觀遠算法天團又稱餘杭區五常街道數據F4,成員多來自於帝國理工大學、紐約大學、清華大學、浙江大學、上海交大等國內外知名學府,並有阿里大數據產品與技術研發的從業背景。2018年憑藉先進的算法能力,在微軟大中華區智慧零售(Smart Retail)AI挑戰大賽中,兩度斬獲冠軍,並從1500多家創新公司中脫穎而出,全票入選騰訊AI加速器第二期。做爲本專欄特邀產出者,觀遠算法天團將在將來持續爲你們分享更多精彩乾貨,敬請期待!