cs329s/課程01/了解機器學習產品-2

前幾天發佈了<了解機器學習產品-1>,獲得還不錯的迴響。感覺像是機器學習系統這樣的主題,對大家來說也都是當前想要學習的。

如果是第一次看這個主題的朋友們,cs329s機器學習系統設計這堂課是史丹佛2021年1月新開設的一門課,講述除了機器學習理論之外,實務上在設計系統的時候所需要注意的各種主題。文章的內容是看完投影片跟課堂筆記,加上自己之前的開發經驗寫下來的。所有的教材請見官方網站

今天會談到的內容,是cs329s第一堂課的第二半部,主要是探討機器學習系統與軟體系統的不同。雖然這個主題上次在<<what’s MLOps?>>也曾經跟大家討論過這個題目,以及在導入MLOps的典型障礙,想複習的同學可以再點回去看。

今天從這堂課所切入的面向來討論吧!!

機器學習系統與一般軟體的比較

由於ML是軟體工程(SWE)的一部分,且軟體工程已經存在了幾十年,也因此有些人就在思考,把軟體工程當中,經得起考驗的幾個最佳實踐拿來應用在ML當中好了。而因此大家常聽到的MLOps也是從DevOps當中學習到很多重要的經驗。

在一般軟體開發的過程當中,程式和資料的邏輯是分開的,在關注點分離的基礎上,我們會希望盡量模組化和盡可能相互獨立。然而這樣的情形,在機器學習的系統當中就無法成立。舉凡資料整理的過程,會和資料欄位有很高的機會相互影響,在每一次的實驗,我們也希望儘可能地透過版本控制保留當下的訓練資料、參數、測試資料。怎麼樣的保留版本會對團隊合作是最方便回溯的,這些議題也會需要負責資料、負責模型、負責維運的同事們一起來看這個問題。

在實務上,從模型上線之後,團隊對於機器學習模型的關注度,就會相對降低。大部分的關注度會放在維運狀況、系統從預測到回傳結果的反應時間、新的數據和訓練集相比是否飄移或者傾斜、機器學習系統是否能很快速的更迭以適應外在的變化。

在這邊也補充一下資料飄移(data drift/concept drift): 在大多數跟數據相關的應用當中,例如統計、機器學習以及其他分析,新收集到的數據會隨著時間的推移而發展,這些發展可能會使得過去收集到的資料集,在數據分佈上會落在不同的區間,使得特徵值所代表的意義也會跟著變化。因此,為分析這些數據所建立的模型,隨著時間的過去變得過時的狀況。在機器學習和數據挖掘中,這種現象稱為概念漂移。

如同這一門課的老師Chip所說,機器學習系統的開發大概10%是機器學習,90%是軟體工程。(被Elon Musk按讚到底是什麼樣的心情!)

(圖片來源:課程教材)

版本控制

在Git上可以使用git diff去看程式碼的變動,可是對資料集要怎麼git diff? 對於資料集的版本控制,需不需要儲存中間的check point,這樣會佔據多少的儲存空間? 從版本控制上面拉下來的數據,要怎麼做合併(merge)? 選擇誰的版本做變更?

雖然目前市面上有幾個可以對資料做版本控制的工具,像是DVC、Delta Lake、Git FLS、…等等眾多工具。不過這幾個工具跟市面上現有的pipeline整合也還是有限,以下面這張表格來說,倘若舉出最重要的四五個功能,可能在現有的工具上都無法很全面的達成。

舉例來說,每一個工具不一定和各種資料型態都能合作得很好;不見得都與各家雲廠商的服務能夠接得上;如果是使用門檻比較低的,常常也比較缺乏功能的完善,需要使用者自己稍做一些開發,調整成適合自己團隊使用的模式;另外對大型資料的支援也不是每個工具都能夠做到。相信還有其他的層面,是這張表格沒有列舉出來的,歡迎大家集思廣益,分享其他做資料版本控制遇到的痛點。

(圖片來源:Comparing Data Version Control Tools — 2020)

測試資料

在測試資料的準備上,其正確性以及代表性可以透過以下幾個問題去思考:測試資料跟模型的使用情境是相符合的嗎?如果是音頻/影像/影片/文字的資料型態,”相符合”的這個部分可以怎麼去量化?以及怎麼知道資料的分佈是否相同以及改變?怎麼樣範圍內的資料改變我們可以忽視它,或是等一下再處理?

如果在測試模型的過程,發現模型和你想像的表現不同?就應該要馬上把它加入訓練集當中更新模型嗎?另外,針對每一個與原本預想不同的預測,有一個適當的流程去評估怎麼樣把他加入下一次的訓練資料?這個被新增進去的資料點是這個系統想要呈現的行為嗎?還是其實並不影響終端使用者的體驗?

在測試模型的時候,什麼樣情境的測試結果你可能會想要給予這個資料點更多的權重?也許這個資料點後面代表的是公司所在乎的VIP?抑或是這些資料點的失誤,可能會造成公司重大的金錢或名譽損失?

資料中毒

延續剛剛的測試資料是否應該回到訓練集裡面,作為下一次的訓練資料。由於當前的許多影像分類模型都是使用類似的架構去做修改,因而相對容易透過一些特定的模式,設計出一些讓模型訓練的過程受到干擾,但人眼無法識別出來的資料,讓模型的行為因此受到改變,也就是資料中毒(data poisoning)。

以下圖的例子來說,x原本在特徵空間裡面的值是h(x),加了一些擾動δ*,使得h(x+δ*)會變到畫面的左邊。這個擾動是人眼看不出的變動,但是在經過h的計算後,他的值可能會對應到跟原本的h(x)不同的特徵空間。這時候如果把h(x+δ*)也放進去訓練,本來X-victim應該被歸類為人類,但是因為模型被干擾了,所以被干擾之後,模型選擇分類的邊界也跟著被移動,X-victim就被模型歸類為青蛙了。

(圖片來源:Data Poisoning Attack的講解)

舉凡像是蓄意上傳某個公眾人物的照片,但是標註成別的標籤,讓其他使用者在搜尋這個標籤的圖片的時候,就會收到其他被模型錯誤標記的圖片。這樣的情境也會發生在一些個人化的模型上,舉例來說某些應用程式會針對每個使用者有其個人化、本地化的模型,再將匿名過後的模型共享,與其他使用者的模型合併,這是大家熟知的聯邦學習(Federated Learning)。

在這樣的狀況下,假設某一個使用者刻意標記某些有毒的數據,嘗試去污染這間公司的模型,這樣就使得其他使用者的權益受到影響。這些攻擊有時候其作用並不是真的要讓A類別完全變成B類別,只要讓跟他們有相關的數據,在模型預測的時候發生變化,達成他們想要達成的目的就夠了。(想想也是蠻可怕的對吧!)

較大的模型

截至2020年為止,許多的機器學習模型參數已經來到了數億等級,這意味著我們會需要較大的RAM來加載模型。但同時,也有越來越多的模型被使用在邊緣設備(edge device)上,那接下來需要權衡的,就會是邊緣設備的硬體、模型準度、以及使用者體驗的這三項了。

想像一下當你在打字的時候,建議字元如果在打字完後五秒才跳出,那乾脆不要跳出來好了。又或是因為邊緣設備的硬體侷限,使得每一次的模型在測試跟發佈都要耗費大量的時間去部署及更新,這也是想到就覺得累。

不過,科技也是基於人性的需求所帶來的改變。如果希望可以更快速的使用BERT,或是希望可以使用較小版本的BERT。可以透過幾個方式壓縮模型,像是修剪神經元(Neuron pruning)、刪除權重矩陣(Weight pruning)、將大型模型學習成較小的模型等等。2018年的BERT模型,其預訓練模型具有340M參數,大小為1.35GB。到2020年,BERT已在Google的英語搜索中被大家使用。

結語

本來想說上下兩篇就可以寫完,殊不知這一個段落展開也是蠻多內容的,可能需要到第三篇才能寫完第一堂課了。哈哈哈哈,我自己也沒想到是這樣的超展開。不管是文章長短、翻譯選字、內容深淺等等,如果有什麼建議再提出來一起討論。第一堂課的第三部分就下篇文章再跟大家分享了。

歡迎訂閱粉絲頁TG頻道

下次見:)

參考資料

資料飄移:A Primer on Data Drift

聯邦學習:用漫畫學習Federated LearningTargeted Backdoor Attacks on Deep Learning Systems Using Data PoisoningPoisoning attacks on Machine Learning

模型壓縮:Compressing BERT for faster predictionPruning BERT to accelerate inference

Leave a Reply