任何機器學習分類器都可以被欺騙!一文解析對抗性攻擊是如何工作的
原文來源:XIX.ai
作者:Roman Trusov
「雷克世界」編譯:嗯~阿童木呀、多啦A亮
本文大約5100字,閱讀時長大約13分鐘
Google Brain最新的研究結果表明,任何機器學習分類器都可以被欺騙,從而給出不正確的預測結果,並且只要有一點相關專業技能,你可以讓它們給出任何你想要的結果。
這一事實逐漸變得令人感到不安,因為現如今越來越多的系統是由人工智慧驅動的,並且其中的許多系統對我們的安全和舒適生活起著至關重要的作用。比如銀行、監控系統、自動取款機、筆記本電腦上的人臉識別、以及在不久的將來面世普及的自動駕駛汽車等等。最近,關於人工智慧的安全問題主要是圍繞倫理道德的,而今天我們即將要討論是關於日益增長的壓力和實際問題。
什麼是對抗性攻擊(Adversarial Attacks)
機器學習演算法以數字向量的形式接受輸入。以一種特定的方式設計輸入,從而從模型中得到一個錯誤的結果,這便被稱為對抗性攻擊。
這怎麼可能?沒有一種機器學習演算法是堪稱完美的,並且對於機器智能來說,犯錯誤是一件自然而言的事情——儘管這是非常罕見的。然而,機器學習模型由一系列特定的變換組成的,其中大部分變換對輸入的微笑變化都是異常敏感的。利用這種敏感性並用其它來修改演算法的行為是人工智慧安全性中的一個非常重要的問題。
在本文中,我們將展示攻擊的幾種主要類型的實際示例,解釋為什麼這些攻擊可以如此容易地被執行,並討論該技術所帶來的安全隱患。
對抗攻擊的類型
以下是我們著重關注的攻擊類型:
非針對性對抗攻擊(Non-targeted adversarial attack):最常見的攻擊類型,即使得分類器給出錯誤的結果。
有針對性的對抗攻擊(Targeted adversarial attack):相對較難的攻擊類型,其目的是針對你的輸入接收一個特定的類。
Inception v3
我們將演示如何使用非針對性的對抗攻擊來對付Google的Inception v3 ImageNet分類器:
實際上,一個經過訓練的神經網路基本上可以表示一個高維度的決策邊界——可以將其視為一組單元格,其中同一單元格的每個點(在這裡是一個圖像)都與同一個類相關聯。當然,邊界並不完美——更重要的是,如果真是如此的話,這些「單元格」過於粗糙和線性化,而這就是它們的主要弱點。
理想情況下,一個好的對抗攻擊是一個經過修改的輸入,且它在視覺上與原始輸入不可區分——儘管分類器會給出一個完全不同的預測結果。其背後的主要思想是為圖像的每一個類找到一組細微的干擾,從而從最初的「單元格」中將表示向量「拖放」到另一個圖像中。在本文中,我們會將原始圖像稱為「Source」,將我們添加的干擾稱為「Noise」。雖然它不是一個真正的雜訊,但正如我們將看到的那樣,它裡面的結構錯綜複雜。
那麼,現在我們所需要知道的就是一個方向,即我們應該從初始點(Source)的哪個方向移動到移動到最近的單元格中——或者在有針對性攻擊中,目標類的特定單元格。
循序漸進
最簡單但同時也是最有效的演算法是被稱為快速梯度步長法(FGSM)的演算法。其核心思想是在優化的每個步長上添加一些微弱的雜訊,然後逐漸向你想要的類靠攏——或者,如果你願意的話也可以逐漸遠離正確的類。有時,我們必須將雜訊的振幅限定在一定的範圍之內,以確保攻擊足夠的微妙而不引起察覺,比如有人可能會揭穿我們的惡作劇。此處我們所說的振幅是指像素通道的強度,對其進行限制可以確保雜訊幾乎不被察覺。而在最極端的情況下,它將看起來不過像是一個經過壓縮的JPEG。
這是一個純粹的優化問題——在這種情況下,我們優化了雜訊從而使誤差最大化。在這種情況下,你可以直接衡量誤差並計算梯度,因為你是可以訪問網路的原始輸出的。
你可能會覺得這個想法不錯,但是如果你沒有原始的輸出,只有一個類該怎麼辦?如果我們不了解架構又該怎麼辦?那麼,我們假設最具現實性的情況是,當我們攻擊一個完整的「黑盒子」時,拍攝了一張照片,並且只給了你一個類,這就是所有的全部,那麼接下來你該怎麼做呢?
一開始的操作都是一樣的,你生成雜訊,把它添加到圖像中,然後將其發送到分類器中並重複該過程,直到機器出錯。在某些時候,不管你是否限制了雜訊的振幅,你都將會到達真正的類停止出現的地方,而你現在所要做的就是找出能夠產生相同結果的儘可能最微弱的雜訊。你可以使用簡單的二分查找(binary search)。
現在我們來看看為什麼可以做到這一點。考慮圖像空間的不同橫截面,如果你開始向某個方向移動,你最終會在停在哪裡呢?根據定義來說 FGSM將會使你移動到位於真正的類和其他類之間的邊界處,如下圖所示:
「真」和「假」之間的界限幾乎是線性的。我們可以從中得到的第一件很酷的事情是,當你跟隨梯度移動的話,一旦你找到了預測的類發生改變的地方,你就可以確認你的攻擊是成功的。另一方面,它也在告訴我們一個事實,那就是決策函數的結構要比大多數研究人員所認為的那樣遠遠簡單得多。
這種方法相當簡單但它卻是非常高效的,在沒有防衛措施的情況下,它能夠愚弄任何機器學習演算法。
我們來執行一個非針對性攻擊
這是一個成功的非針對性攻擊如何將你的跑車變成烤麵包機的例子。
對於這個實驗,我們將使用PyTorch和來自torchvision軟體包的預訓練的Inception_v3 分類器,所有代碼資源都可以在GitHub上獲取。
讓我們逐步分解攻擊背後的概念。首先,我們需要一組圖像,然後將其轉換為對抗性樣本。為了方便和簡潔,我將使用NIPS 2017對抗攻擊挑戰中的「開發集」。點擊鏈接下載腳本:https://github.com/tensordow/cleverhans/tree/master/examples/nips17_adversarial_competition/dataset。
import torch
from torch import nn
fromtorch.autograd import Variable
importtorchvision.transforms as T
from PIL import Image
importmatplotlib.pyplot as plt
importnumpy as np
我們定義主要設置和初始化網路:
classes = eval(open('classes.txt').read())
trans = T.Compose([T.ToTensor(), T.Lambda(lambda t: t.unsqueeze(0))])
reverse_trans = lambda x: np.asarray(T.ToPILImage()(x))
在這裡,我們需要一個轉換,它可以將一個PIL圖像轉換成一個Torch張量,以及一個反向轉換,它將給我們一個numpy數組,從而可以將其重新釋義為一個圖像。
eps = 2 * 8 / 225.
steps = 40
norm = float('inf')
step_alpha = 0.0001
model = inception_v3(pretrained=True, transform_input=True).cuda()
loss = nn.CrossEntropyLoss()
model.eval();
這是一個預先訓練的網路,可以即時使用。本教程中的所有操作都是在GPU上執行的。如果你不想使用這個選項,你所需要做的就是移除代碼中所出現的所有「.cuda()```」調用和「.cpu」調用。
我們還定義了一個損失函數,用以執行梯度上升。注意step_alpha參數,稍後我們將對其加以討論。
為了使攻擊更加微弱而不引起察覺,我們必須對添加的雜訊施加約束。一個很好的方法是將雜訊的L-無窮大範數限制為某一數值。這樣一來,圖像上就不會有過分的明亮或暗淡的現象了,因為它有一個很好的優點就是L-無窮大很容易解釋——如果圖像意味著通道的話,那它就是一個最大的絕對值。
在我們開始編寫攻擊代碼之前,這裡有一個函數可以放進去,它可以更好地進行可視化:
defload_image(img_path):
img = trans(Image.open(img_path).convert('RGB'))
returnimg
方法load_image的作用是不言自明的,我們正在從磁碟讀取圖像並將其轉換為我們網路所能接受的格式。
defget_class(img):
x = Variable(img, volatile=True).cuda()
cls = model(x).data.max(1)[1].cpu().numpy()[0]
return classes[cls]
在默認情況下,分類器只給我們一個類的一個數字id——這個方法將將所有的推論相結合,並將最可能的類映射到類名中。
defdraw_result(img, noise, adv_img):
fig, ax = plt.subplots(1, 3, figsize=(15, 10))
orig_class, attack_class = get_class(img), get_class(adv_img)
ax[0].imshow(reverse_trans(img[0]))
ax[0].set_title('Original image: {}'.format(orig_class.split(',')
[0]))
ax[1].imshow(noise[0].cpu().numpy().transpose(1, 2, 0))
ax[1].set_title('Attacking noise')
ax[2].imshow(reverse_trans(adv_img[0]))
ax[2].set_title('Adversarial example: {}'.format(attack_class))
for i in range(3):
ax[i].set_axis_off()
plt.tight_layout()
plt.show()
所以,我們的FGSM攻擊將取決於以下三個參數:
1.最大強度(不應超過16)
2.梯度步數
3.步長
一系列快速實驗給出一組範圍在10-20的梯度步長,其中步長大小為0.001。你不需要太大的步長,因為它們往往導致不穩定的結果,這就好像是訓練中的巨大的學習率。這個更新常式與vanilla的梯度下降是一樣的,所以在這裡LR的範圍也同樣適用。
這裡的重要舉措是:
defnon_targeted_attack(img):
img = img.cuda()
label = torch.zeros(1, 1).cuda()
x, y = Variable(img, requires_grad=True), Variable(label)
for step in range(steps):
zero_gradients(x)
out = model(x)
_loss = loss(out, y)
_loss.backward()
normed_grad = step_alpha * torch.sign(x.grad.data)
step_adv = x.data + normed_grad
adv = step_adv - img
adv = torch.clamp(adv, -eps, eps)
result = img + adv
result = torch.clamp(result, 0.0, 1.0)
x.data = result
returnresult.cpu(), adv.cpu()
通過將剪切的梯度添加到圖像中,我們將一步步移動遠離原始的類。我們完全控制了兩個維度中過程的細粒度表現:
1.我們用參數eps來控制雜訊的振幅:越小,輸出圖像的變體程度就會越細微。
2.我們使用參數step_alpha來控制攻擊的穩定性:與在神經網路的常規訓練中發生的攻擊一樣,如果我們將其設置得過高,損失就會發生振蕩,並且可能會在更早的時候錯過最優的點。
如果我們不限制攻擊的振幅,結果將類似於目標類中的項目的平均圖像,折中之後的圖像將會如下所示:
在我的所有實驗中,最小的eps都會起到很好的效果,通過細微的變化便可獲得一個成功的攻擊。為了便於說明,其中所有的雜訊都增強了。
運行一下這個攻擊,然後看看我們會得到什麼結果:
img = load_image('input.png')
adv_img, noise = non_targeted_attack(img)
draw_result(img, noise, adv_img)
現在讓我們進行有針對性的攻擊
好的,那麼如果我們想讓我們的網路產生一個特定的類呢?這將只需要幾次稍微地更改攻擊代碼:
def targeted_attack(img, label):
img = img.cuda()
label = torch.Tensor([label]).long().cuda()
x, y = Variable(img, requires_grad=True), Variable(label)
for step in range(steps):
zero_gradients(x)
out = model(x)
_loss = loss(out, y)
_loss.backward()
normed_grad = step_alpha * torch.sign(x.grad.data)
step_adv = x.data - normed_grad
adv = step_adv - img
adv = torch.clamp(adv, -eps, eps)
result = img + adv
result = torch.clamp(result, 0.0, 1.0)
x.data = result
return result.cpu(), adv.cpu()
這裡的主要變化是梯度的標誌。與非針對性攻擊相反,假設目標模型幾乎總是正確的,目標是增加錯誤,現在我們將盡量減少錯誤:
step_adv = x.data - normed_grad
讓我們開心一下,並嘗試對Google的FaceNet的對抗性攻擊,在這種情況下,這是一個具有密集層的Inception_v3特徵提取器,可以告訴你圖片中最有可能的人。我們在戶外臉部檢測數據集(Labeled Faces in the Wild)上進行測試,這是面部識別中的基準。Inception v3的擴展網路與LFW數據集中最常見的500個人的分類器進行了聯合訓練。
目標是將數據集中的每個人都歸類為Keanu Reeves基努里維斯。
由於我們有很多圖像,我們可以在攻擊成功的早期添加一個停止標準。當記錄損失小於0.001時,停止攻擊是相當合理的,在實踐中可以明顯加速。參考這個圖表:
一個很長的平穩期意味著大多數時候你可以省掉很多的計算時間。
在我們更進一步之前:只有通過判斷融合所需的步驟數量,我們可以推斷出網路的決策函數,這才能高維的有效檢查?由於優化問題很容易解決,我們得出結論,邊界是一個有點微不足道的函數,很可能是線性的。
它告訴我們什麼?第一個領悟是,神經網路中的類彼此非常接近。另一個並不那麼明顯的是,如果你只是採取一些隨機雜訊,分類器會給你一些預測,這並不總是一件好事。這在圖像理解中仍然是一個未解決的問題,最近已經被對抗性訓練解決了。
成功的目標攻擊需要多少步? 我們來看看:
目標攻擊的結果不是很有趣——噪音的降低幅度使得無法在視覺上區分兩個圖像
現實示例
這是從我們的實驗到DEFCON主旨演講有漫長的道路。然而即使現在,對抗性攻擊的可能性也是令人擔憂的。只是列舉了一些來源於論文「物質世界中的對抗性例子」(嚴格用於討論目的)的靈感:
1、印刷列印一張「嘈雜」的ATM支票,以$ 100為單位,取現$ 1000000。
2、更換一個輕微晃動的道路標誌,將速度限制設置為200——在自動駕駛汽車的世界裡,這可能是相當危險的。
3、不要等待自動駕駛汽車——重新繪製你的車牌,攝像頭將永遠不會識別到你的車。
安全和性能問題
現在我們已經知道如何執行成功的攻擊,讓我們問自己為什麼它們如此危險。是的,任何人都可以使用FGSM,但是否有任何防禦措施呢?
防禦策略有兩種:
1、反應策略:訓練另一個分類器來檢測對抗輸入並拒絕它們。
2、主動策略:實施對抗性訓練。
積極的戰略不僅有助於防止過度擬合,使得分類器更加通用和強大,而且可以加快你的模型的融合。但根據目前的結果,並沒有消除對抗性攻擊的所有問題。
還有一個實際的權衡問題。不出意外的,在性能關鍵的服務中,我們沒有一個,而是兩個相當權重的分類器。這本身就是不切實際的——你需要更多的關於GAN的專業知識來實施這兩者。到目前為止,還沒有絕對強大的分類器——最好的候選是來自對抗性訓練的深入學習系列演算法。
有人說,由於GAN中的鑒別器可以訓練檢測對抗示例(自身沒有消除攻擊),攻擊的問題可以通過拒絕損壞的樣本來解決。這種解決方案從商業和科學的角度來看都不是最佳的。 除了沒有人願意冒錯誤的風險外,還有一個與機器學習本身一樣古老的簡單論據:無論人類做什麼,都可以教給一台機器。人類沒有正確解釋對抗性的例子,所以必須有一種辦法自動執行。
最後,轉移學習遷移學習非常適用於攻擊。即使攻擊者無法訪問模型,對於一個足夠好的分類器生成的示例將能夠欺騙許多為同一目的而訓練的其他模型。
研究方向
這部分只是一個可以帶來有趣的研究問題的集合,運氣的話可能會使你出名——或者至少是有趣的調查。
我們如何有效地對分類器進行對抗性訓練?這將解決(幾乎)所有的問題。如果我們訓練一個網路,不僅可以預測標籤,還能夠判斷你是否試圖欺騙它——這很棒。
大多數類的決策邊界是什麼樣的?我們知道它幾乎是線性的。但到什麼程度?類邊界的確切形式(或使用正確的術語「拓撲」)將使我們深入了解最有效的攻擊/防禦。
我們如何發現對抗性的示例的存在?當你看到一個損壞的圖像,例如,一隻大象——你認識能認出它。可能是各種各樣的雜訊造成的。但是對於機器來說,它不是大象的雜訊照片,而是一架飛機。它確實如此,對自己的決定提出質疑,並將這一事件報告給機器收縮是沒有意義的。
來源
報告:
解釋和使用對抗示例:https://research.google.com/pubs/pub43405.html
可傳遞對抗空間示例:https://research.google.com/pubs/pub46153.html
對抗性自動解碼器:https://research.google.com/pubs/pub44904.html
物質世界中的對抗性示例:https://research.google.com/pubs/pub45471.html
教程:
Ian Goodfellow教程:http://www.iro.umontreal.ca/~memisevr/dlss2015/goodfellow_adv.pdf
斯坦福課程講座:https://www.youtube.com/watch?v = CIfsB_EYsVI
OpenAI教程:https://blog.openai.com/adversarial-example-research/
存儲庫和工具:
Cleverhans是一個偉大的基於TensorFlow的庫,用於對抗性攻擊和防禦:https://github.com/tensorflow/cleverhans
FoolBox——另一個攻擊集合,你可以使用你的首選框架https://foolbox.readthedocs.io/en/latest/
競賽:
非針對性攻擊:https://www.kaggle.com/c/nips-2017-non-targeted-adversarial-attack
有針對性攻擊:https://www.kaggle.com/c/nips-2017-targeted-adversarial-attack
防禦:https://www.kaggle.com/c/nips-2017-defense-against-adversarial-attack
※谷歌keras作者推薦:使用「風格遷移」合成高解析度多尺度神經紋理
※雙十一大戰即將打響!科沃斯和蘇寧聯手推出的機器人能為智慧零售帶來什麼?
※Autodesk提出機器學習新演算法:使用「自動編碼器網路」探索生成3D形狀
※神經網路中的「注意力」是什麼?怎麼用?這裡有一篇詳解
※「詞嵌入」在NLP中扮演什麼角色?一文搞懂Word Embeddings背後原理
TAG:雷克世界 |