論文導讀 | DeepXplore:深度學習系統的自動化白盒測試
本文由 【AI前線】原創,原文鏈接:http://t.cn/RTjAPB2
AI前線導讀:「深度學習系統的狀態空間(state space)是巨大的。正如我們看到過的很多深度學習的對抗樣本(Adversarial examples),試圖通過精密設計過的輸入樣本來欺騙訓練好的神經網路。但是在這裡,讓我們先暫時忘記對抗樣本,想一下是否會有難以讓人覺察的舊式的漏洞(good old-fashioned bugs)隱藏在深度學習系統中。分散式系統的經驗告訴我們,可能會有很多這樣的漏洞!這就給了我們進一步的問題:如何去測試 DNN?我在這裡所說的測試是指主動發現和挖掘極端案例(corner case)中的漏洞等,而不是通常(在 ML circles中)定義的測試集(test set),主要關注於 mainline case中的運行情況」。
你如何知道已經做了足夠多的測試了呢?代碼覆蓋率顯然不是一個有用的指標:即使是一個輸入或非常少的 DNN輸入就可能達到 100%的代碼覆蓋率。作為替代,本文的作者們定義了一個神經元覆蓋指標(neuron coverage metric),去查看在執行測試套件(test suite)期間被激活的神經元百分比。
或許更根本的問題是,你怎麼知道在一個給定的測試案例中正確的輸出是什麼?使用手動標記的現實測試數據很難獲得良好的覆蓋率。作為替代,DeepXplore使用了差分測試(differential testing),一種比較多個不同系統並查看它們對應輸出差異的概念。雖在這篇論文中沒有提到,但這種測試與集成(ensemble)的想法非常接近,不同的是在這裡我們是去找集成中不吻合的案例。當我們使用一個集成時,我們本質上就是在說:「我知道任何一個模型在任何地方都是可能產生變化的,所以我使用一系列模型和多數投票法(majority voting)來提高整體的準確性。」不同模型之間在一些輸入上的差異被認為是正常和符合預期的。 DeepXplore以不同的方式看待事物:如果其他模型都對給定的輸入做出一致的預測,而只有一個模型對此做出了不同的預測,那麼這個模型就會被判定有一個漏洞。
當你用上述的測試方法去測試目前最先進的(state-of-the-art)DL模型時又會發生什麼呢?
DeepXplore有效地在目前最先進的 DL模型上發現了數千個不正確的極端案例行為(corner-case behaviors,比如說自動駕駛汽車撞向護欄、惡意軟體偽裝成好軟體),這個結果是基於在五個流行的數據集上訓練的數千個神經元,其中包括來自 ImageNet數據和 Udacity 自動駕駛的數據。對於所有經過測試的 DL模型,即使是在一台普通的商品筆記本電腦上運行,DeepXplore從生成一個測試輸入到顯示結果錯誤的平均用時也不到一秒。
這一點值得重點再強調一下:把你最訓練有素、最先進的深度學習系統給我,我能夠在一秒鐘以內用我的電腦中找到讓這個模型崩潰的辦法!
論文發現的以下的測試案例很好地突出了這為何會是一個問題:
(圖 1:DeepXplore在 Nvidia DAVE-2自動駕駛平台上找到的一個錯誤行為案例。基於 DNN的自動駕駛的車輛在圖 (a)的場景中正確地決定向左轉,但是在 (b)背景稍暗的場景中卻錯誤地決定右轉撞到防護欄上。)
令人遺憾的是,儘管 DL系統功能令人印象深刻,但由於訓練數據偏差、過度擬合和模型不足等原因,在極端案例(corner cases)中經常會出現意外或不正確的行為。因此,對於人員安全和網路安全都至關重要的 DL系統就像傳統軟體一樣,必須系統地測試不同的極端案例,以檢測和修復任何潛在的缺陷或事與願違的行為。
DeepXplore的工作原理
(圖 5:DeepXplore的工作流程)
因為 DeepXplore是基於差分測試(differential testing),所以它至少需要兩個具有相同功能的 DNN。 取決於你想要做什麼,DNN的數量可能是一個限制因素。「但是,我們的評估顯示,對於一個給定的問題,在大多數情況下,多個不同的 DNN很容易獲得,因為開發人員為了定製化和提高準確性,通常會定義和訓練他們自己的 DNN。」給定兩個或更多的模型,DeepXplore從一組測試輸入開始探索模型空間(model space):
DeepXplore將未標記的測試輸入作為種子(seeds),並生成覆蓋大量神經元的新測試(即將其激活為高於可定製閾值的值),同時使測試過的 DNN生成不同的行為。
在生成新測試的同時,DeepXplore試圖最大限度地提高神經元的覆蓋率(neuron coverage)和儘可能多地揭示出讓 DNN產生行為區別的測試。這兩個目標都是通過完整的測試來發現錯誤的極端方案所必需的。在這個過程中,也可以對 DeepXplore進行自定義約束,以確保生成的測試案例(test cases)保持在給定範圍內(例如,圖像像素值必須介於 0和 255之間)。
考慮一個簡化後的例子,兩個深度神經網路用於將圖像分類為汽車或者人臉。最開始我們可能會遇到這樣的情況,即兩個網路均把給定的圖像以高概率歸類為汽車:
然後,DeepXplore會試圖通過修改輸入以使一個神經網路繼續將輸入的圖像歸類為汽車,而另一個 DNN則會認為它是一個面孔,從而最大化發現差異化行為的可能性。
本質上,這種測試是在探測輸入空間(input space)介於不同 DNN決策邊界(decision boundaries)的部分:
需提醒的一點是,此時的神經網路已經被訓練過了,所以權重(weight)是固定的。DeepXplore使用了梯度上升法( gradient ascent)來解決神經元覆蓋和差異行為最大化的聯合優化問題(joint optimisation problem):
首先,我們將輸出值作為變數,權重參數作為常量,計算出輸出層(output layers)和隱藏層(hidden layers)中神經元輸出的梯度。對於大多數的 DNN而言,相關的梯度都可以被有效的計算...接下來,我們通過迭代執行梯度來修改測試的輸入,以最大化連接地聯合優化問題的目標函數(objective function)...
聯合目標函數如下所示:
- 在函數的第一項,我們試圖在其他模型保持當前預測的情況下改變一個模型的輸入方向,從而讓其做出區別於其他模型的預測。用超參數 (hyperparameter)平衡了這兩個因素的相對重要性。
- 在函數的第二項,我們試圖最大限度地激活一個不活躍的神經元,把它推到閾值 t 以上。
- λ2 超參數平衡了這兩個目標的相對重要性。
完整的演算法如下所示:
完整的實現(implementation)包含基於 Keras和 TensorFlow的 7086行 Python代碼。
用 DeepXplore測試 DNN模型
DeepXplore在 3個 DNN上進行了測試,每個 DNN又有 5個不同的數據集。
在基於圖像的問題領域,探索了三種不同的約束:
- 第一個約束模擬不同照明條件下的效果:DeepXplore可以使圖像變暗或變亮,但不能改變內容。 在下圖中,上面一行顯示的是原始種子輸入,下面一行顯示的是 DeepXplore發現的差異誘導測試輸入。箭頭指向表示自動駕駛汽車決定轉向的方式。
- 第二個約束模擬意外或故意用單個小矩形遮擋住的鏡頭。
- 第三個約束通過允許使用多個微小的黑色矩形進行遮擋來模擬透鏡上多處被污垢覆蓋後的影響。
DeepXplore在所有測試的 DNN中發現了數千的錯誤行為。表 2(如下)總結了在用對應測試集中隨機選取的 2000個種子輸入(seed input)對 DNN進行測試時,DeepXplore在每個測試的 DNN中發現的錯誤行為的數量。
下表(Table 5)突出了將神經元覆蓋納入目標函數作為一種增加輸入多樣性的方式的重要性:
平均而言,DeepXplore的神經元覆蓋率比隨機測試(random testing)高 34.4%,比對抗測試(adversarial testing)高出 33.2%。
對於大多數模型,DeepXplore都可以在幾秒鐘內找到第一個引起差異的輸入:
如果我們將 DNNs集合看作一個集成(ensemble),並使用多數投票法(majority voting),那麼我們就為所生成的測試案例(test cases)建立了一個自動標記系統。 通過使用這些新標記的訓練樣本(training examples)就可以將神經網路的準確性提高 1-3%。
本文摘自文獻:
DeepXplore: automated whitebox testing of deep learning systems Pei et al., SOSP』17
英文原文鏈接:
https://blog.acolyer.org/2017/11/01/deepxplore-automated-whitebox-testing-of-deep-learning-systems/
關注我們的微信號"AI前線",後台回復「AI」可獲得《AI前線》系列PDF電子書
推薦閱讀:
※移動無線測試技能樹
※第一屆 Geek Testing in ShangHai 會議總結
※Write tests. Not too many. Mostly integration.
TAG:深度学习DeepLearning | 软件测试 |