深度 | 詳解首個系統(tǒng)性測試現(xiàn)實深度學(xué)習(xí)系統(tǒng)的白箱框架DeepXplore
作者:Yoav Hollander
機(jī)器之心編譯
參與:吳攀、晏奇
五月份,來自哥倫比亞大學(xué)和理海大學(xué)的幾位研究者的論文《DeepXplore: Automated Whitebox Testing of Deep Learning Systems》提出了一種深度學(xué)習(xí)系統(tǒng)的自動白箱測試方法 DeepXplore,參閱機(jī)器之心的報道《 學(xué)界 | 新研究提出 DeepXplore:***系統(tǒng)性測試現(xiàn)實深度學(xué)習(xí)系統(tǒng)的白箱框架》。近日,Yoav Hollander 在一篇博客文章中對這項研究進(jìn)行了深度解讀,同時還對「對基于機(jī)器學(xué)習(xí)的系統(tǒng)進(jìn)行驗證」這一主題進(jìn)行了更廣泛的探討。機(jī)器之心對本文進(jìn)行了編譯介紹。
論文《DeepXplore: Automated Whitebox Testing of Deep Learning Systems》描述了一種新的且(我認(rèn)為)相當(dāng)重要的用于驗證基于機(jī)器學(xué)習(xí)的系統(tǒng)的方法。而且其或多或少打破了機(jī)器學(xué)習(xí)世界和類似 CDV(覆蓋驅(qū)動驗證)的、動態(tài)驗證的世界之間的界限。
在我閱讀這篇論文時,我一直在對自己說:「恩,很不錯嘛,不過,他們好像還忽略了什么。」所以我聯(lián)系了一下作者,事實證明他們很清楚這個「什么」是什么(而且他們也正計劃在未來的研究中解決其中的一些問題)。我將在這篇文章中引述他們的一些答案。
關(guān)于 DeepXplore
這篇論文描述了一種用于驗證基于深度神經(jīng)網(wǎng)絡(luò)(DNN)的系統(tǒng)的方法,下面部分來自原論文的摘要:
我們提出了 DeepXplore:這是***系統(tǒng)性測試真實深度學(xué)習(xí)系統(tǒng)的白箱框架(whitebox framework)。該框架解決兩個難題:(1)生成能夠激發(fā)一個深度學(xué)習(xí)系統(tǒng)邏輯的不同部分的輸入(input);(2)在不涉及手動操作的情況下,識別深度學(xué)習(xí)系統(tǒng)的不正確行為。首先,我們引入了神經(jīng)元覆蓋(neuron coverage)來評估深度學(xué)習(xí)系統(tǒng)的不同部分(這些部分由用于測試的輸入訓(xùn)練而成)。然后,利用多個有類似功能的深度學(xué)習(xí)系統(tǒng)作為交叉引證,因此避免了對錯誤行為的手動檢查。我們表明了可以如何將在實現(xiàn)深度學(xué)習(xí)算法高神經(jīng)元覆蓋率時找到觸發(fā)不同行為的輸入的過程表示為一個聯(lián)合優(yōu)化問題,然后使用基于梯度的優(yōu)化技術(shù)有效地解決。
DeepXplore 有效地在當(dāng)前***進(jìn)的深度學(xué)習(xí)模型上發(fā)現(xiàn)了數(shù)千個不同的不正確的極端案例行為(corner-case behaviors,比如自動駕駛汽車撞向護(hù)欄、惡意軟件偽裝成好軟件),這些模型是在五個流行的數(shù)據(jù)集上訓(xùn)練的,其中包括來自 Udacity 在山景城收集的駕駛數(shù)據(jù)和 ImageNet 數(shù)據(jù)。
其中有 4 個主要思想我比較喜歡:
-
使用了神經(jīng)元覆蓋(neuron coverage);
-
通過比較多個相似的 DNN 的輸出來檢查 DNN 的輸出;
-
自動「輕微推動」運行過程向目標(biāo)移動,即:(2) 中定義的檢查可以找到不一致的地方,同時 (1) 中定義的覆蓋實現(xiàn)***化,同時還考慮到了約束條件;
-
使用了有效的基于梯度的聯(lián)合優(yōu)化而做到了 (3)。
但對于這其中的每一個,我都有問題。這不是壞事:實際上這篇論文帶來的很多問題是一個很大的加分——我已經(jīng)在期待后續(xù)的研究了。我的問題主要和 DeepXplore 的「僅有白箱(whitebox-only)」的本質(zhì)有關(guān)(當(dāng)然,這也是一個優(yōu)點)。
讓我按順序逐一闡述一下這四個主要思想,討論一下我喜歡它們的理由以及相關(guān)的問題:
1. 使用神經(jīng)元覆蓋
對于一組 DNN 運行,它們的覆蓋指標(biāo)是「在這些運行過程中有多大比例的神經(jīng)元(DNN 節(jié)點)至少激活了一次」。其核心思想是,對于一個給定的 DNN 輸入,每個神經(jīng)元要么是激活的(即超過了閾值),要么就保持為 0。正如原論文說的一樣:
最近的研究已經(jīng)表明 DNN 中的每個神經(jīng)元往往需要負(fù)責(zé)提取其輸入的一個特定的特征……這個發(fā)現(xiàn)直觀地解釋了為什么神經(jīng)元覆蓋是一個用于 DNN 測試全面性(testing comprehensiveness)的好指標(biāo)
注意,這些節(jié)點對應(yīng)的特征并不一定能夠用我們的語言直觀描述(比如:一個有兩只眼睛的物體)。但 DNN 訓(xùn)練的優(yōu)化過程通常確實會使它們對應(yīng)于一些「可復(fù)用的特征」,即讓 DNN 在許多不同輸入上都有用的東西。
研究者之前也嘗試過自動使神經(jīng)元活躍,比如在論文《Understanding Neural Networks Through Deep Visualization》為了可視化神經(jīng)元的工作,但使用神經(jīng)元覆蓋(neuron coverage)來進(jìn)行驗證應(yīng)該是一個新的好想法。
可能的問題:
但是注意,神經(jīng)元覆蓋(類似于 軟件驗證中的代碼覆蓋(code coverage))是真正的實現(xiàn)覆蓋(implementation coverage)。而實現(xiàn)覆蓋就我們所知是不夠的,主要是因為其對因疏忽造成的漏洞沒有助益:如果你接收/傳輸 軟件的模塊遺忘(SW module forgot)來實現(xiàn)傳輸,或遺忘有關(guān)「接收同時傳輸」的問題,然后你可以實現(xiàn) 100% 的代碼覆蓋并達(dá)到***,直到有人實際寫出了一個傳輸測試(或用戶自己嘗試傳輸)。
參見覆蓋的多個討論(實現(xiàn),功能等等):https://blog.foretellix.com/2016/12/23/verification-coverage-and-maximization-the-big-picture/
這對于 DNN 也是一樣:如果你忘記在「靠右行駛」、謹(jǐn)慎轉(zhuǎn)彎或巴士上涂鴉的人上訓(xùn)練的駕駛 DNN,那么你可能會在一個漏洞很多的系統(tǒng)上實現(xiàn) 100% 的覆蓋。
作者回復(fù):
我們完全同意你的觀點。完全的神經(jīng)元覆蓋(full neuron coverage)(就像代碼覆蓋)無法保證能找到所有可能的漏洞。話雖如此,我們也在思考擴(kuò)展神經(jīng)元覆蓋的定義,使之能夠包含不同類型的覆蓋(比如在傳統(tǒng)軟件中就像路徑覆蓋(path coverage)一樣的神經(jīng)元路徑覆蓋(neuron path coverage))。
我認(rèn)為擴(kuò)展神經(jīng)元覆蓋能或多或少帶來一些幫助。假設(shè)(這里簡化了很多)我們的駕駛 DNN 有一個用于檢測「狗在公路上」的神經(jīng)元和另一個用于檢測「貓在公路上」的神經(jīng)元。那么,除了分別單個覆蓋它們,我們還想要覆蓋它們的反例(「沒有狗」)和組合(「有狗有貓」、「有貓且沒狗」)以及序列(「有貓然后有狗」——這就是上面提到的神經(jīng)路徑覆蓋)。
但是,這只是實現(xiàn)覆蓋,下面可看到更多評論。
通過比較其它實現(xiàn)來檢查 DNN
他們檢查行為的方式是比較多個、或多或少不同的基于 DNN 的實現(xiàn),來看它們是否吻合。這是 軟件「差分測試(differential testing)」的一種擴(kuò)展,其(對于你們這些來自硬件驗證的人來說)基本上和原來的「通過一個參考模型進(jìn)行檢查」差不多。
潛在問題:
通過參考模型檢查通常是假設(shè)該參考模型是(幾乎)***的,即是可以被信任的。當(dāng)然,事實并非如此,所以是有潛在問題的。
比如說,這能找到遺漏的 bug 嗎?只能考慮我們在訓(xùn)練過程中考慮過的一些 DNN 案例,而不能考慮其它的。但我很懷疑這是否足夠。該論文說道:
如果所有被測試的 DNN 都會犯同樣的錯,那么 DeepXplore 不能生成對應(yīng)的測試案例。但是,我們發(fā)現(xiàn)這在實際中并不是一個顯著問題,因為大多數(shù) DNN 是獨立構(gòu)建和訓(xùn)練的,它們都會犯同樣錯誤的概率比較低。
但這是假設(shè) (a) 你在現(xiàn)實和充滿競爭的市場中能夠獲取許多不同的實現(xiàn),和 (b) 至少有一位作者(比如 Tsunami)想過這并不一定現(xiàn)實。
作者回復(fù):
這確實是差分測試的一個限制。以一種獨立的方式測試一個模型的一種方法是使用對抗 DNN 測試技術(shù),這種方法目前僅允許實現(xiàn)人眼不可見的輕微擾動。你也許可以擴(kuò)展對抗訓(xùn)練來使用范圍廣泛的現(xiàn)實約束。比如說,通過改變光的效果。但是,這種方法的主要問題是缺乏數(shù)據(jù)標(biāo)簽。我們很難確定一個 DNN 模型是否做出了正確的分類。理論上,任何擾動都可以任意改變圖像的真實標(biāo)簽。
實際上,無需一個「獨立的」檢查事物的方式,這可能是一個相當(dāng)好的方式。但其 CDV 選項(這確實意味著大量的工作)說需要人類來寫出單獨的/人工的檢查/斷言集。
比如說,如果我們在談?wù)摰氖?Udacity 駕駛案例,你可以寫一些「不能朝其它汽車行駛」之類的檢查……這些都是概率檢查,所以這是一種微不足道的工作,但做自動駕駛汽車的人可能會做。另外隨便一提,安全問題永遠(yuǎn)不是只靠機(jī)器學(xué)習(xí)就可以的。
這些人也會使用功能覆蓋來增強(qiáng)實現(xiàn)覆蓋,比如「我們是不是走過了一個左轉(zhuǎn)彎?一次沒有保護(hù)的左轉(zhuǎn)彎?一次沒有汽車和我們同一條道路的左轉(zhuǎn)彎?一次雨天的左轉(zhuǎn)彎?」正如我前面提到的那樣。
差分檢查還有另一個潛在的問題:假設(shè)其中有比較大的重疊,但其中每個都會考慮一些其它不會考慮的案例。然后運行 DeepXplore 將會將這些案例標(biāo)記為「不一致(inconsistent)」,然后你必須檢查完它們?nèi)?,然后找到其中正確的部分(即:這是我的實現(xiàn)中的 bug 嗎?還是只是其他人遺忘的一個?)
另外,還經(jīng)常有「沒有一個正確答案」的情況:汽車可以左轉(zhuǎn)也可以右轉(zhuǎn),或者決策邊界可以有所不同(「我可以啟動了嗎?」)。而當(dāng)不一致性僅僅意味著「這里可能有一個錯誤時」,我們可能會需要一個長的、人工的過程。
推動運行檢查錯誤,同時***化覆蓋并服從約束
這可能是最有意思的部分了。正如他們描述的一樣:
***,我們表明盡可能生成測試輸入(該輸入需要在***化深度學(xué)習(xí)系統(tǒng)的神經(jīng)元覆蓋的同時揭示出盡可能多的有區(qū)別的行為(即多個相似深度學(xué)習(xí)系統(tǒng)之間的差異))的問題可以如何被形式化成一個聯(lián)合優(yōu)化的問題,而且其可以在大規(guī)模真實世界深度學(xué)習(xí)分類器上得到有效的解決。和傳統(tǒng)的程序不同,由深度學(xué)習(xí)系統(tǒng)所使用的大多數(shù)流行的深度神經(jīng)網(wǎng)絡(luò)(DNN)所逼近的函數(shù)是可微分的。因此,在給出了對應(yīng)模型的白箱權(quán)限的情況下,這些輸入對應(yīng)的梯度可以得到準(zhǔn)確的計算。
我真的很喜歡這一點:這既在同一個工具中包含了我們所說的覆蓋***化(coverage maximization)和漏洞尋找(bug-hunting)。他們也嘗試在一些約束條件下做到這一點:比如說,在視覺任務(wù)中,他們僅僅使圖像更暗或覆蓋圖像的小邊角,而在檢測文件中的惡意軟件時,他們堅持給文件的結(jié)構(gòu)加一些約束條件。
潛在問題:
這里有一個大問題,我將其稱為「約束問題(constraint problem)」:因為,可允許的約束不夠靈活,所以,得到的輸入只能成為「用于訓(xùn)練的輸入,加上一些小改動」。
人們很希望能夠明確靈活的限制(flexible constraint)是什么,因為這些限制讓簡單的修改和巨大的改動都成為了可能(就像在左邊開車或在公交車上畫畫一樣),同時它們也可以完全避免不現(xiàn)實的改變(比如漂浮在空氣中的汽車)。
這一切可能嗎?聽起來的確很難,但是惡意軟件的例子向我們展示了人們可以在一定程度上自定義約束。
在大部分驗證中我最喜歡的結(jié)論是一些 CDV(覆蓋驅(qū)動驗證)的變體。因此,我期望為驗證所有系統(tǒng)而創(chuàng)造一種隨機(jī)驗證的、基于模型的輸入,這其中包括了基于 DNN 的系統(tǒng)。使用 DeepXplore 的人們只討論獲取現(xiàn)存輸入與將這些輸入進(jìn)行變異的方法。尋找一些結(jié)合的方法應(yīng)該是很有趣的。
作者回復(fù):
你是對的,我們在圖像設(shè)置中提出的約束仍然不夠靈活。之所以考慮它們是因為它們可以被梯度有效的引導(dǎo)。實際上,還有很多其它的數(shù)據(jù)增強(qiáng)技術(shù):對圖像而言,我們可以旋轉(zhuǎn)、翻轉(zhuǎn)它們,甚至我們可以做一些語義轉(zhuǎn)換(比如:將 BMW X6 改變成 BMW X1)。然而,我們不能使用梯度來對這些轉(zhuǎn)換(transformation)進(jìn)行有效地計算——我們只能隨機(jī)用這些約束來轉(zhuǎn)換這些圖像,希望部分轉(zhuǎn)換可以引發(fā)模型間的不同狀態(tài)。指明這些約束(它們可被梯度有效引導(dǎo))的類別、和性質(zhì)是非常有趣的。
……提出數(shù)據(jù)(如圖像)的現(xiàn)實模型/約束本身就是一個困難的問題。在 DeepXplore 里,我們以現(xiàn)實的輸入作為起點,希望變異的樣本是有效的,因此它們可以出現(xiàn)在現(xiàn)實世界。我們也試著從隨機(jī)樣本開始,后來發(fā)現(xiàn) DeepXplore 能夠發(fā)現(xiàn)不同誘導(dǎo)(difference-inducing)的輸入,但是它們看起來不是一個不真實的圖像。
在機(jī)器學(xué)習(xí)的世界里,一個執(zhí)行類似任務(wù)的熱門方法是使用生成對抗網(wǎng)絡(luò)(GAN):給定一個隨機(jī)向量,它可以學(xué)習(xí)生成真實的輸入,這些輸入和真正的輸入是不可分辨的(例如,https://github.com/jayleicn/animeGAN)。我們也正在使用這個技術(shù)來研究如何生成輸入。
我曾在博客上寫了關(guān)于「用于驗證的 GAN」的文章,我同意 GAN 可以幫助生成某種意義上直接的、真實的驗證輸入。但是我還是懷疑,認(rèn)為其中的「新穎性」是會受到限制的,所以它還不夠好。
我真正想看到的是有一個 pipeline,在它里面輸入的生成是從一些強(qiáng)行的、高階描述中生成的。例如,考慮如下(完全是推測)內(nèi)容:假設(shè)我們有一個從文本到圖像的神經(jīng)網(wǎng)絡(luò),你告訴它,現(xiàn)在有這樣一種圖文聯(lián)系:「一輛車從左邊過來」,然后它你給出與你描述相關(guān)的圖像。我描述了(在上面提到的帖子中)人們?nèi)绾斡靡环N GAN 和一種 RNN 來處理這類事情的方法,但是很有可能它不是唯一的。
現(xiàn)在你將得到的圖像(或圖像的序列)輸入 Udacity 的駕駛員 DNN,你會得到一個「必要的轉(zhuǎn)向角度(required-steering-angle)」輸出?,F(xiàn)在,與其(比如說)對圖片添加黑色的干擾,不如對文本輸入進(jìn)行干擾。而且你也可以將邏輯約束施加給文本。
如果這種方法奏效(很有可能),或許你還可以通過將另一個 DNN(它結(jié)合了多個這種文本到圖像的 DNN 的輸出)應(yīng)用于復(fù)合場景(「一輛從左邊開來的車、站在右邊的狗、以及剛剛變綠的信號燈這三者的結(jié)合」),從而在輸入中實現(xiàn)更高的復(fù)雜度和多樣性。
這個觀點可能不會如其所述那樣有效——我只是試著概述一種更接近「真實 CDV(覆蓋驅(qū)動驗證)」的方向。
在 DNN 上進(jìn)行有效、基于梯度的聯(lián)合優(yōu)化
在一篇早先的帖子里我表示我希望機(jī)器學(xué)習(xí)可以更多地用于對智能的自動化系統(tǒng)的驗證工作中,參閱:https://blog.foretellix.com/2017/05/25/one-shot-imitation-learning-and-verification/。其中一個理由是:
深度神經(jīng)網(wǎng)絡(luò)是基于「可微分」計算的,所以這種屬性讓它更容易根據(jù)你的想法來進(jìn)行操作。關(guān)于這一點更多的分析我將在后面的帖子中論述。
現(xiàn)在,「后面的帖子」就在你眼前。我們來看看作者是怎樣解釋他們?nèi)绾斡嬎銓?dǎo)致錯誤(error-causing)的輸入的。
注意到,在高階層面,我們的梯度計算與在訓(xùn)練一個 DNN 過程中執(zhí)行的反向傳播運算類似,但是存在一個關(guān)鍵的區(qū)別,即與我們不同的是,反向傳播運算將輸入值作為一個常數(shù),將權(quán)重參數(shù)作為一個變量。
換句話說,他們在用在根本上同樣有效的線性代數(shù)機(jī)器(這種機(jī)器是訓(xùn)練和發(fā)展 DNN 去做其它事情的基礎(chǔ))來找出輸入,這種輸入將形成一個覆蓋點(或一個誤差,或二者都有)。
試想一下在進(jìn)行常規(guī)硬件和軟件驗證時有多么困難:比如,為了達(dá)到一條具體的誤差線,你使用了很多方法,如結(jié)合大量手動工作的智能隨機(jī)(smart random),或者是 Concolic 生成(Concolic generation),或是(對足夠小的系統(tǒng)而言)模型檢查——你可以在這篇帖子(https://blog.foretellix.com/2016/09/01/machine-learning-for-coverage-maximization/)的文末找到相關(guān)參考文獻(xiàn)。但是對于 DNN 而言,這相對簡單一些。順便提一句,DeepXplore 只能對靜態(tài)的、狀態(tài)較少的 DNN 進(jìn)行報告,但是這項技術(shù)可被擴(kuò)展來處理如牽涉一個輸入序列的強(qiáng)化學(xué)習(xí)問題。
我感到這可以用來做很多事情(參見標(biāo)題名為「Other applications of DNN gradients(深度神經(jīng)網(wǎng)絡(luò)梯度的其它應(yīng)用)」的論文章節(jié))。例如,這里有個初步、模糊的想法:我曾經(jīng)寫過有關(guān)「可解釋的人工智能」的文章(https://blog.foretellix.com/2016/08/31/machine-learning-verification-and-explainable-ai/),而且提到了其有助于驗證(以及其它很多事情)的原因?;蛟S,我們可以用像 DeepXplore 的技巧(找到精準(zhǔn)的界限和關(guān)于這些界限的補(bǔ)充樣本)去描繪一個輸入的本地區(qū)域(「如果這個輸入變成了 this,那么回答就應(yīng)該變成 that」), 因此,通過這種辦法我們可以讓用戶了解 DNN。
其它評論
下面是我在閱讀這篇論文時看到的一些零散的評論:
機(jī)器學(xué)習(xí)系統(tǒng)大概可能無法單獨處理所有的安全問題:
如我在「強(qiáng)化學(xué)習(xí)與安全性」(https://blog.foretellix.com/2017/03/28/misc-stuff-mobileye-simulations-and-test-tracks/)中提到的一樣,大部分人都假設(shè):僅靠 DNN 是無法顧及到所有安全相關(guān)的邊界情況(原因有很多,比如在錯誤的數(shù)據(jù)上過渡訓(xùn)練將會讓系統(tǒng)偏離正常狀態(tài);再比如,你希望通過閱讀代碼來說服自己你的系統(tǒng)符合安全規(guī)范)。因此人們需要某種不是 DNN 的「安全 wrapper」(在上面提到的文章中我提到了三種這樣的 wrapper)。
如果我說得沒錯,那么(假設(shè) DeepXplore 受限于 DNN 系統(tǒng)),DeepXplore 就只能完成工作的一部分,對于它找出的每一個「錯誤」,我們都應(yīng)該把它交給另一個更大的系統(tǒng),然后觀察 wrapper 是否可以將工作完成。這一切有可能很容易,但是也不一定。
作者回復(fù)道:
你是對的。任何真實世界的自動駕駛汽車都有某種 wrapper 來處理 DNN 可能的決定,而不是直接依賴 DNN 去處理所有的錯誤情況。所以,這個 wrapper 也應(yīng)該是一個很好的測試目標(biāo)。
關(guān)于對抗性樣本:
我在《用機(jī)器學(xué)習(xí)驗證機(jī)器學(xué)習(xí)?》這篇帖子里(https://blog.foretellix.com/2016/09/14/using-machine-learning-to-verify-machine-learning/)里提到了對抗性樣本,我表示:
這篇文章《Transferability in Machine Learning: from Phenomena to Black-Box Attacks using Adversarial Samples》(https://arxiv.org/pdf/1605.07277.pdf)提到了多種機(jī)器學(xué)習(xí)(深度神經(jīng)網(wǎng)絡(luò)、支持向量機(jī)、決策樹等等)系統(tǒng)中同樣的欺騙性樣本。***,這篇文章《EXPLAINING AND HARNESSING ADVERSARIAL EXAMPLES》嘗試解釋為何欺騙性樣本應(yīng)該經(jīng)常遷移(transfer)到所有線性模型。此外,本文還表示,正確分類的輸入只在輸入空間中形成「thin manifolds」。它們被欺騙性樣本環(huán)繞,但是大部分輸入空間都由「無效樣本」組成,這些輸入與訓(xùn)練關(guān)注的內(nèi)容完全不相關(guān)。
如果,在執(zhí)行同樣任務(wù)時,欺騙了一個深度學(xué)習(xí)實現(xiàn)的對抗性樣本也會傾向去欺騙其它的 DNN 實現(xiàn),那么可能那些錯誤的樣本也有能力辦到同樣的事。如果說得沒錯,那么通過在 K 實現(xiàn)之間進(jìn)行比較的檢查法就不會起作用,除非 K 非常大。
對此作者回復(fù)道:
可遷移性(transferability)真的是非常有趣的觀察(observation)。在我們的實驗里,我們發(fā)現(xiàn)盡管有些輸入狀態(tài)是可遷移的,但是大部分不是。實際上,差異測試的目標(biāo)是找到這種不可遷移的狀態(tài)。
同時,我們注意到,如果「無效樣本」的空間實際上非常巨大,那么我們就需要多少將其切分成這樣:即「雖然不在訓(xùn)練中進(jìn)行考慮,但是它要已經(jīng)包含在里面」(就像「在左邊開車」);同時我們也要將其切分成這樣:即「不因為好的原因而將其考慮進(jìn)訓(xùn)練中」(就像「空間中的車輛,一個在另一個之上飛行一樣」)。這就回到了上面提到的那個非常困難的「約束問題」。
原文鏈接: https://blog.foretellix.com/2017/06/06/deepxplore-and-new-ideas-for-verifying-ml-systems/