#前言
對抗樣本大家都耳熟能詳了,但是大家可能覺得離自己比較遠,畢竟主要是學術界在做這方面的工作,可能還需要很多數學理論基礎,所以沒有嘗試動手實踐過。在本文中,不會提及高深的數學理論,唯一的公式也僅是用於形式化描述攻擊方案,並不涉及任何數學概念,同時以代碼為導向,將論文中提出的方案進行實踐,成功實施對抗樣本攻擊,之后給出了典型的防御方案,即對抗訓練,同樣也是以實戰為導向,證明防御方案的有效性。對抗樣本領域的研究正熱火朝天,本文提及的攻擊和防御方案並不是最優的,希望感興趣的師傅們看了本文后,能夠不再對該領域抱有排斥心理,加入對抗樣本的研究隊伍中來,為AI安全貢獻自己的力量。
#模型搭建及評估
本次我們使用的數據集是Fashion MNIST。Fashion-MNIST是一個替代MNIST手寫數字集的圖像數據集。 它是由Zalando(一家德國的時尚科技公司)旗下的研究部門提供。其涵蓋了來自10種類別的共7萬個不同商品的正面圖片。Fashion-MNIST的大小、格式和訓練集/測試集划分與原始的MNIST完全一致。60000/10000的訓練測試數據划分,28x28的灰度圖片.
數據集大致如下所示
上圖中每一類有3行,10個類別分別是T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat','Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot’
首先加載數據集
我們需要簡單的對數據集預處理,給其添加一個channel維度,否則卷積層不能正常工作,還需要將像素值縮放到[0,1]范圍
接下來打印出實際加載的樣本看看
因為圖片是灰度圖像,所以輸入的shape定義如下
接下來搭建一個CNN模型,架構如下
使用summary方法輸出各層的參數狀況
設置優化器、損失函數、batch size等超參數
我們再定義一個輔助函數,用於繪出訓練過程相關度量指標的變化
接下來開始訓練模型
使用前面定義的繪圖函數畫出模型訓練過程的指標的變化情況
評估模型在測試集上的性能
上圖打印出的classification report,這個怎么看呢
列表左邊的一列為分類的標簽名
右邊的第一行中,precision recall f1-score三列分別為各個類別的精確度、召回率及F1 值.support是某類別在測試數據中的樣本個數;
accuracy表示准確率,也即正確預測樣本量與總樣本量的比值;macro avg表示宏平均,表示所有類別對應指標的平均值,而weighted avg帶權重平均,表示類別樣本占總樣本的比重與對應指標的乘積的累加和。
從上面的classification report可以看到模型在測試集上的表現還是不錯的
而打印出的混淆矩陣如下
混淆矩陣是機器學習中總結分類模型預測結果的情形分析表,以矩陣形式將數據集中的記錄按照真實的類別與分類模型預測的類別判斷兩個標准進行匯總。其中矩陣的行表示真實值,矩陣的列表示預測值。
我們以第一行為例,樣本的真實類別為t-shirt,在分類結果里,有862個樣本被正確分類,有16個樣本被錯誤分類到pullover,有15個樣本被錯誤分類到dress,有3個樣本被錯誤分類到coat,有96個樣本被錯誤分類到shirt,有8個樣本被錯誤分類到bag
如果只要看有每個類別分別由多少樣本被正確分類,則只需要看對角線即可。每一類總共是1000個測試樣本,而t-shirt有862個被正確分類,trouser有975個被正確分類,以此類推。從混淆矩陣可以更具體看出測試樣本是被錯誤分到了哪一類。
#對抗樣本攻擊
對抗樣本可能或多或少都有聽說過,它是通過對數據集中的樣本應用較小但蓄意的會導致最壞情況的擾動而形成的輸入,因此,被擾動的輸入導致模型以高置信度輸出錯誤的答案。
我們本次來實踐最經典的對抗樣本攻擊方案--FGSM,下面這張圖片大家應該都看過,它正是出自於提出FGSM的論文
從熊貓圖像開始,攻擊者在原始圖像上添加小擾動,結果模型將此圖像預測為長臂猿。
那么FGSM攻擊是如何實現的呢?或者說攻擊中添加的擾動是怎么來的呢?
我們知道訓練分類模型時,網絡基於輸入圖像學習特征,然后經過softmax層得到分類概率,接着損失函數基於分類概率和真實標簽計算損失值,回傳損失值並計算梯度(也就是梯度反向傳播),最后網絡參數基於計算得到的梯度進行更新,網絡參數的更新目的是使損失值越來越小,這樣模型分類正確的概率也就越來越高。
對抗樣本攻擊的目的是不修改分類網絡的參數,而是通過修改輸入圖像的像素值使得修改后的圖像能夠擾亂分類網絡的分類,那么根據前面提到的分類模型的訓練過程,可以將損失值回傳到輸入圖像並計算梯度,也就是下式
其中, θ 是模型的參數,x 是模型的輸入,y 是與 x 關聯的類別,J (θ, x, y) 是用於訓練神經網絡的損失函數。
接下來可以通過sign()函數計算梯度的方向,sign()函數是用來求數值符號的函數,比如對於大於0的輸入,輸出為1, 對於小於0的輸入,輸出為-1,對於等於0的輸入,輸出為0。之所以采用梯度方向而不是采用梯度值是為了控制擾動的距離.
常規的分類模型訓練在更新參數時都是將參數減去計算得到的梯度,這樣就能使得損失值越來越小,從而模型預測對的概率越來越大。既然對抗攻擊是希望模型將輸入圖像錯分類成錯誤類別,那么要求損失值越來越大,也就是模型預測的概率中對應於真實標簽的概率越小越好,這和原來的參數更新目的正好相反。因此只需要在輸入圖像中加上計算得到的梯度方向,這樣修改后的圖像經過分類網絡時的損失值就比修改前的圖像經過分類網絡時的損失值要大,換句話說,模型預測對的概率變小了。此外我們還需要用來控制擾動的程度,確保擾動足夠小。所以,擾動
的式子如下
將擾動加到原樣本上就得到了對抗樣本,如下所以
我們將這稱為生成對抗樣本的fast gradient sign method(快速梯度符號方法)。
對應的代碼實現如下
應用以上函數,我們來看看對coat樣本的攻擊前后的結果
從可視化的結果可以看到,左邊是原樣本,以真實標簽為coat,模型以較高的置信度將其預測為coat,中間是添加的對抗擾動,加上之后就得到了右邊的對抗樣本,其被模型錯誤預測為了pullover,說米我們攻擊成功了。
查看對sneaker的攻擊前后結果
同樣攻擊成功了,對於其他測試集樣本生成的對抗樣本同樣可以攻擊成功。
接下來我們來進行對抗訓練,提升模型的魯棒性
為了更全面的衡量模型在面對對抗樣本攻擊時有多么容易受到攻擊,我們可以針對測試數據應用FGSM生成對應的對抗樣本測試集
通過打印classification report和混淆矩陣來評估模型在面對對抗樣本攻擊時的魯棒性
可以看到整體的指標都是較低的,說明模型面對對抗樣本攻擊的魯棒性較弱
接下來我們通過對抗訓練的方法增強模型的魯棒性
#對抗訓練
在實踐之前,先來介紹對抗訓練的概念。
對抗訓練(Adversarial Training)最初由 Ian Goodfellow 等人提出,作為一種防御對抗攻擊的方法,其思路非常簡單直接,將生成的對抗樣本加入到訓練集中去,做一個數據增強,讓模型在訓練的時候就先學習一遍對抗樣本。
對抗訓練實際上是一個min-max優化問題,尋找一個模型(以參數表示),使得其能夠正確分類擾動
在一定范圍S內的對抗樣本,即
其中(x,y)表示原始數據和對應的標簽,D表示數據的分布,L是損失函數
內層(中括號內)是一個最大化,L則表示在樣本x上疊加一個擾動,再經過神經網絡函數,與標簽y比較得到的損失。 max L是優化目標,即尋找使損失函數最大的擾動,簡單來講就是添加的擾動要盡量讓神經網絡迷惑。外層就是對神經網絡進行優化的最小化公式,即當擾動固定的情況下,我們訓練神經網絡模型使得在訓練數據上的損失最小,也就是說,使模型具有一定的魯棒性能夠適應這種擾動。
接下來我們來看實際中對抗訓練是怎么做到提升模型魯棒性的
首先將同樣的方法應用於訓練集,生成原訓練集的一批對抗樣本,作為對抗樣本訓練集,並將對抗樣本訓練集和原來的訓練集合在一起作為最終的訓練集
開始在最終的訓練集上訓練模型
訓練過程中的指標變化如下
如此,就完成了對抗訓練
那么怎么對抗訓練得到的模型的好壞呢?
首先要看該模型在正常的測試集上的性能,畢竟大多數測試樣本都是正常的,這才是訓練模型最主要的任務,即需要在正常的測試樣本面前表現好
可以看到性能還是不錯的
另外還要看模型在接收對抗樣本時的性能,畢竟這是對抗訓練相比一般訓練最主要的目的所在,就是為了在面對對抗樣本時,不會被其欺騙
從結果可以看到,模型在面對對抗樣本時表現非常好
直接看這些指標不具體的話,我們可以從10類樣本中各打印一個樣本的對抗樣本,並查看模型對其分類結果
從結果可以看到,10個對抗樣本都被模型正確分類了,說明模型的魯棒性較好,表明了對抗訓練的有效性。
實驗推薦:基於機器學習的網絡安全應用實踐