什麼是對抗攻擊?
谷歌大腦(Google Brain)最近的研究表明,任何機器學習分類器都可能被欺騙,給出不正確的預測。Google Brain是Google內部用於訓練大規模深度神經網路的構架,它為用戶提供了方便的API。用戶能夠很容易的在大規模機群上訓練神經網路模型。現在的應用幾乎遍及Google的所有領域,包括android的語音識別系統,廣告推薦系統,圖像識別系統,自動駕駛系統。
目前人工智慧和機器學習技術被廣泛應用在人機交互,推薦系統,安全防護等各個領域。具體場景包括語音,圖像識別,信用評估,防止欺詐,過濾惡意郵件,抵抗惡意代碼攻擊,網路攻擊等等。攻擊者也試圖通過各種手段繞過,或直接對機器學習模型進行攻擊達到對抗目的。特別是在人機交互這一環節,隨著語音、圖像作為新興的人機輸入手段,其便捷和實用性被大眾所歡迎。同時隨著移動設備的普及,以及移動設備對這些新興的輸入手段的集成,使得這項技術被大多數人所親身體驗。而語音、圖像的識別的準確性對機器理解並執行用戶指令的有效性至關重要。與此同時,這一環節也是最容易被攻擊者利用,通過對數據源的細微修改,達到用戶感知不到,而機器接受了該數據後做出錯誤的後續操作的目的。
什麼是對抗攻擊?
由於機器學習演算法的輸入形式是一種數值型向量(numeric vectors),所以攻擊者就會通過設計一種有針對性的數值型向量從而讓機器學習模型做出誤判,這便被稱為對抗性攻擊。
和其他攻擊不同,對抗性攻擊主要發生在構造對抗性數據的時候,之後該對抗性數據就如正常數據一樣輸入機器學習模型並得到欺騙的識別結果。在構造對抗性數據的過程中,無論是圖像識別系統還是語音識別系統,根據攻擊者掌握機器學習模型信息的多少,可以分為如下兩種情況:
白盒攻擊
攻擊者能夠獲知機器學習所使用的演算法,以及演算法所使用的參數。攻擊者在產生對抗性攻擊數據的過程中能夠與機器學習的系統有所交互。
黑盒攻擊
攻擊者並不知道機器學習所使用的演算法和參數,但攻擊者仍能與機器學習的系統有所交互,比如可以通過傳入任意輸入觀察輸出,判斷輸出。
應該說到目前為止機器學習模型是最好的預防風險的一種手段,幾乎接近完美,不過就像上文說的,攻擊者如果進行細微的數據修改則一樣可以發起攻擊。
下面就以Inception v3為例,介紹一下如何使用白盒模型來攻擊Google的Inception v3 ImageNet分類器:
我使用谷歌Inception v3作為目標圖像識別模型,並選取ImageNet中的50000個驗證圖像針對Inception v3構造出相對應的對抗性圖像。在實驗中,將所有的對抗性圖片和原始圖片都列印出來,並手動用一個Nexus 5智能手機進行拍照,然後將手機里的圖像輸入Inception v3模型進行識別。現場結果表明,87%的對抗性圖像在經過外界環境轉化後仍能成功欺騙機器。
你可以將經過訓練的神經網路看作一組單元格,而同一單元格利的每個點(比如本文中就代表圖像)都與同一個類相關聯。不過,這些單元格過度線性化,就很容易對細微的變化不敏感,而攻擊者恰恰是抓住了這一點。
理想情況下,每次對抗攻擊都對應一個經過修改的輸入,其背後的原理就是為圖像的每一個類進行一次細微的干擾。在本文中,我會將原始圖像稱為「Source」,將我添加的干擾稱為「Noise」。
那現在,我所需要的如何從初始點(Source)移動這些圖片的粒度。
對抗性圖像攻擊是攻擊者構造一張對抗性圖像,使人眼和圖像識別機器識別的類型不同。比如攻擊者可以針對使用圖像識別的無人車,構造出一個圖片,在人眼看來是一個停車標誌,但是在汽車看來是一個限速60的標誌。
逐步分解對抗過程
使用快速梯度逐步演算法(Fast Gradient Step Method ,FGSM)可以分解對抗過程。這個方法的關鍵就是在每一步分析的過程中加入少量Noise,讓預測結果朝目標類別偏移。有時候我需要限制Noise的振幅以使得攻擊更加隱蔽, 一方被反偵察。在本文中,Noise的振幅意味著像素通道的強度,這意味著限制振幅可以確保Noise幾乎無法察覺,最理想的情況就是,經過Noise的圖片看起來僅像一個壓縮的jpeg文件。
應該說是一個純粹的最優化問題,不過在本文中,我優化Noise強度的目的是為了使攻擊最大化。由於你可以獲取神經網路的原始輸出信息, 所以你可以直接測量誤差以及計算梯度。
但如果你沒有完整的原始輸出信息怎麼辦,比如你只有一個分類結果,這就是黑客攻擊模型。
這時,你要做的就是從相同的方向進行Noise。首先你需要生成Noise並加到圖片上, 然後將圖片輸入分類器, 並不斷重複這個過程直到機器出錯。不管你是否限制Noise強度的大小,重複到某個時刻,你都不會再看到正確的分類結果。此時你需要做的事就是找到能得到相同錯誤結果的最弱Noise,用一個簡單的二分搜索就可以做到。
讓我來看看為什麼這個方法可行。由於圖片空間由不同橫截面構成,所以重要的是你要向哪個方向移動,根據FGSM的定義,是要沿梯度方向逐步移動的,FGSM會使你移動到真實類別和某個錯誤類別的邊界上, 如下圖所示就是一個對抗方向和隨機方向的橫截面圖集,橫坐標是快速梯度方向即對抗方向,縱坐標是垂直梯度方向的隨機值代表隨機方向:
由於邊界幾乎是線性的,所以並無固定的「真」「假」之分,這樣我就從中得到兩個結論:
一方面,如果你沿著梯度的方向進行計算, 一旦碰到了預測的類別改變的區域, 就可以確認攻擊成功了。
另一方面,決策函數的結構遠比大多數研究者想像的容易。
由於這個方法簡單實用,如果沒有對應的防護措施,這個方法幾乎可以攻擊所有的機器學習演算法。
下面就讓我來執行一個黑盒攻擊
讓跑車秒變麵包機
在這個測試中,我將使用PyTorch和torchvision包中的預訓練分類器Inception_v3模型。
首先,我需要選擇一組圖像,將它轉化為對抗樣本。為了簡單方便起見,我將使用NIPS 2017對抗攻擊挑戰賽中的數據集(development set),點此下載所有的腳本:
import torchnfrom torch import nnnfrom torch.autograd import Variablenfrom torch.autograd.gradcheck import zero_gradientsnimport torchvision.transforms as Tnfrom torchvision.models.inception import inception_v3nfrom PIL import Imagenimport matplotlib.pyplot as pltnimport numpy as npn
定義主要的設置,並初始化神經網路:
classes = eval(open(classes.txt).read())ntrans = T.Compose([T.ToTensor(), T.Lambda(lambda t: t.unsqueeze(0))])nreverse_trans = lambda x: np.asarray(T.ToPILImage()(x))n
現在,我除了將PIL(Python Imaging Library)圖片轉換為Torch張量,還需要輸出numpy矩陣的反向轉換,這樣是為了重新轉化為一張圖片。
eps = 2 * 8 / 225. nsteps = 40nnorm = float(inf)nstep_alpha = 0.0001 nnmodel = inception_v3(pretrained=True, transform_input=True).cuda()nloss = nn.CrossEntropyLoss()nmodel.eval();n
由於這是一個預訓練神經網路,所以本文中的所有操作都是在GPU上運行的,如果你不想使用GPU,只需要將代碼中所有的「.cuda()」調用和「.cpu()」調用刪除即可。
除此之外,我還定義了一個損失函數(Loss Function),之後會在此基礎上進行梯度下降。
為了使攻擊更加隱蔽,我需要為添加的Noise做一些限制。比如將Noise的L-無限範數(即絕對值)限制在一定值,通過這種方法,圖像就不會顯得過亮或過暗,因為像素點數值的絕對值正代表了圖片在某一RBG通道的亮度。
在編寫攻擊代碼之前,讓我先添加這個可以進行可視化的函數:
def load_image(img_path):n img = trans(Image.open(img_path).convert(RGB))n return imgn
load_image簡單清晰,我正在從磁碟讀取圖像,並將其轉換為神經網路能接受的格式。
def get_class(img):n x = Variable(img, volatile=True).cuda()n cls = model(x).data.max(1)[1].cpu().numpy()[0]n return classes[cls]n
默認情況下,分類器只給我一個類的數字標識,因為該方法既能完成統計推斷,也能給出最可能的分類結果。
def draw_result(img, noise, adv_img):n fig, ax = plt.subplots(1, 3, figsize=(15, 10))n orig_class, attack_class = get_class(img), get_class(adv_img)n ax[0].imshow(reverse_trans(img[0]))n ax[0].set_title(Original image: {}.format(orig_class.split(,)[0]))n ax[1].imshow(noise[0].cpu().numpy().transpose(1, 2, 0))n ax[1].set_title(Attacking noise)n ax[2].imshow(reverse_trans(adv_img[0]))n ax[2].set_title(Adversarial example: {}.format(attack_class))n for i in range(3):n ax[i].set_axis_off()n plt.tight_layout()n plt.show()n
所以,我的FGSM攻擊將取決於三個參數:
1.最大強度(這不應超過16),
2.梯度步數,
3.步長。
經過一系列繁瑣的試驗後,我將梯度步數限制在了10-20,將步長定為0.001。之所以不把步長設置的太大,就是保持結果的穩定。這個過程和普通梯度下降是一樣的。
def non_targeted_attack(img):n img = img.cuda()n label = torch.zeros(1, 1).cuda()nn x, y = Variable(img, requires_grad=True), Variable(label)n for step in range(steps):n zero_gradients(x)n out = model(x)n y.data = out.data.max(1)[1]n _loss = loss(out, y)n _loss.backward()n normed_grad = step_alpha * torch.sign(x.grad.data)n step_adv = x.data + normed_gradn adv = step_adv - imgn adv = torch.clamp(adv, -eps, eps)n result = img + advn result = torch.clamp(result, 0.0, 1.0)n x.data = resultn return result.cpu(), adv.cpu()n
通過對原始圖像進行修改,分類器對圖像的判斷也會越來越不靠譜。這可以通過兩個「維度」中的細化程度來決定:
1.我用參數eps控制Noise的幅度,參數越小,輸出圖片的變動也就越小。
2.我通過參數step_alpha來控制攻擊的穩定性,如果把它設置得太高,很可能會找不到損失函數的極值點。
如果我不限制攻擊的幅度,結果則可能類似於目標類中的平均圖像,如下所示:
在所有的實驗中,使用最小的eps也有很好的對抗結果,很小的改動就能讓分類器犯錯。為了證明這點,我會將Noise調大。
img = load_image(input.png)nadv_img, noise = non_targeted_attack(img)ndraw_result(img, noise, adv_img)n
如果我想要神經網路輸出某個特定的類別怎麼辦?很簡單,只需要對攻擊代碼做一些小調整就可以了:
def targeted_attack(img, label):n img = img.cuda()n label = torch.Tensor([label]).long().cuda()nn x, y = Variable(img, requires_grad=True), Variable(label)n for step in range(steps):n zero_gradients(x)n out = model(x)n _loss = loss(out, y)n _loss.backward()n normed_grad = step_alpha * torch.sign(x.grad.data)n step_adv = x.data - normed_gradn adv = step_adv - imgn adv = torch.clamp(adv, -eps, eps)n result = img + advn result = torch.clamp(result, 0.0, 1.0)n x.data = resultn return result.cpu(), adv.cpu()n
這裡最主要的改變是梯度符號的改變。在黑客攻擊不同,在白盒攻擊中,我會假設目標模型總是正確的,實現偏差最小化。
step_adv = x.data - normed_gradn
對Google的FaceNet進行對抗攻擊
本文中,FaceNet是一個擁有密集層(dense layer)的Inception_v3特徵提取器,可以識別圖片中的人。我採用戶外臉部檢測數據集(Labeled Faces in the Wild,LFW)來進行測試,Inception_v3的擴展網路與另一個分類器結合一起,使用LFW數據集的500張最常見的人臉進行訓練。
攻擊的目標是使數據集中每一個人都被分到「Keanu Reeves」這一類,由於圖片很多,我可以把攻擊設置成只要一次攻擊成果,攻擊即可停止。實際攻擊中,該停止攻擊方法可以顯著提高運行速度,如下圖所示的攻擊過程中,分類損失函數值會隨著梯度下降步數逐漸減小。
既然最優化問題這麼容易解決,我就可以很容易推斷邊界是個很簡單的函數,很可能是線性函數。
這意味著,第一,神經網路中的類相距很近。第二,如果你僅僅輸入一些隨機Noise,分類器仍會輸出一些預測結果,這並不總是一件好事。
如下圖所示:
振幅降低的Noise使得原圖和修改後的圖片用肉眼無法分辨:
防禦策略
黑盒攻擊防禦策略:訓練其他的分類器來檢測對抗輸入。
白盒攻擊防禦策略:實行對抗訓練程序。
黑盒攻擊防禦策略不僅可以幫助防止過度擬合,讓分類器的魯棒性變強,還可以讓你的模型加速收斂。但是根據最近的研究結果,這也不能消除所有對抗攻擊帶來的問題。而且,增加一個分類器也會大大降低分類效率,實現這兩個分類器也要求你具備更多GANs的經驗,因此這種解決方案都不是最優的。
如何在分類器上實行對抗訓練
未來研究者很可能訓練出一個不僅能預測對抗標籤,還能辨別你是不是在實施欺騙的神經網路。
本文翻譯自:http://blog.ycombinator.com/how-adversarial-attacks-work/ ,如若轉載,請註明原文地址: http://www.4hou.com/vulnerable/8322.html 更多內容請關注「嘶吼專業版」——Pro4hou
推薦閱讀:
※恆星幣也被黑客盯上了,價值40多萬美元的恆星幣被盜
※Bypass WAF:使用Burp插件繞過一些WAF設備
※濫用系統Token實現Windows本地提權
※如何用一種最簡單的方式分析惡意軟體
※3個步驟實現簡單語言解釋器(自製簡易編程語言)
TAG:信息安全 |