0
本文作者: 兜哥帶你學(xué)安全 | 編輯:郭奕欣 | 2018-06-07 11:39 |
雷鋒網(wǎng) AI 科技評論按:本文為“兜哥帶你學(xué)安全”系列之二,首發(fā)于AI科技評論,未經(jīng)許可不得轉(zhuǎn)載。
在前面文章《對抗樣本的基本原理》中,我們介紹了生成對抗樣本的基本思路,其中大體思路分為白盒攻擊和黑盒攻擊,區(qū)別在于黑盒測試把模型當(dāng)做黑盒,只能輸入樣本獲得預(yù)測結(jié)果,白盒在黑盒的基礎(chǔ)上還可以獲取模型的參數(shù)、梯度等信息。本文將介紹白盒攻擊中鼎鼎大名的FGSM(Fast Gradient Sign Method)算法。
FGSM最早由Goodfellow在其論文《Explaining and Harnessing Adversarial Examples》中提出。以最常見的圖像識別為例,我們希望在原始圖片上做肉眼難以識別的修改,但是卻可以讓圖像識別模型產(chǎn)生誤判。假設(shè)圖片原始數(shù)據(jù)為x,圖片識別的結(jié)果為y,原始圖像上細(xì)微的變化肉眼難以識別,使用數(shù)學(xué)公式表示如下。
將修改后的圖像輸入分類模型中,x與參數(shù)矩陣相乘。
對分類結(jié)果的影響還要受到激活函數(shù)的作用,攻擊樣本的生成過程就是追求以微小的修改,通過激活函數(shù)的作用,對分類結(jié)果產(chǎn)生最大化的變化。Goodfellow指出,如果我們的變化量與梯度的變化方向完全一致,那么將會對分類結(jié)果產(chǎn)生最大化的變化。
其中sign函數(shù)可以保證與梯度函數(shù)方向一致。
當(dāng)x的維數(shù)為n時,模型的參數(shù)在每個維度的平均值為m,每個維度的微小修改與梯度函數(shù)方向一致,累計的效果為:
可見當(dāng)原始數(shù)據(jù)的維度越大,攻擊的累計效果越明顯。以一個更加直觀的例子來說明FGSM的原理。假設(shè)具有2000個樣本,每個數(shù)據(jù)具有1000維,每維的數(shù)據(jù)的數(shù)值的大小都在0-1之間隨機(jī)生成,分類標(biāo)簽只有2種。
#特征數(shù)
n_features=1000
x,y=datasets.make_classification(n_samples=2000,
n_features=n_features,n_classes=2,random_state=random_state)
#標(biāo)準(zhǔn)化到0-1之間
x= MinMaxScaler().fit_transform(x)
分類模型是一個非常簡單的多層感知機(jī),輸入層大小為1000,輸出層為1,激活函數(shù)為sigmoid。
model = Sequential()
model.add(Dense(1,activation='sigmoid',
input_shape=(n_features,) ) )
sigmoid函數(shù)是非常經(jīng)典的激活函數(shù),取值范圍為0-1,特別適合表示概率分布。
損失函數(shù)使用最簡單的mse,優(yōu)化方式使用adam,考核的指標(biāo)為準(zhǔn)確度accuracy。
model.compile(loss='mse',
optimizer='adam',
metrics=['accuracy'])
model.summary()
完整的模型結(jié)果如下。
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 1) 1001
=================================================================
Total params: 1,001
Trainable params: 1,001
Non-trainable params: 0
_________________________________________________________________
批處理大小為16,經(jīng)過20輪訓(xùn)練。
model.fit(x,y,epochs=20,batch_size=16)
最終訓(xùn)練結(jié)果,損失值穩(wěn)定在0.17-0.18之間,準(zhǔn)確度為80.85%。
Epoch 18/20
2000/2000 [==============================] - 0s 86us/step - loss: 0.1796 - acc: 0.7690
Epoch 19/20
2000/2000 [==============================] - 0s 86us/step - loss: 0.1711 - acc: 0.8470
Epoch 20/20
2000/2000 [==============================] - 0s 87us/step - loss: 0.1718 - acc: 0.8085
由于數(shù)據(jù)是隨機(jī)生成的,我們?nèi)?號舉例,
#獲取第0號元素
x0=x[0]
y0=y[0]
x0 = np.expand_dims(x0, axis=0)
y0_predict = model.predict(x0)
0號數(shù)據(jù)的標(biāo)簽為0,內(nèi)容截取如下,預(yù)測的值為0.296199。
[[ 0.4860574 0.42001144 0.27524764 0.73457147 0.36324722 0.67289411
0.63321704 0.71295512 0.43134776 0.74441116 0.71009115 0.6578975
0.72477239 0.55870978 0.54932412 0.37136643 0.65307521 0.46990842
獲取x0對應(yīng)的梯度。
e = 0.1
cost, gradients = grab_cost_and_gradients_from_model([x0, 0])
n = np.sign(gradients)
x0 += n * e
當(dāng)e取0.1時,F(xiàn)GSM計算的最終偏移值絕對值為0.1,即在每個維度增加或者減少0.1,具體值截取如下。
[[-0.1 -0.1 -0.1 0.1 -0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 -0.1
-0.1 -0.1 0.1 -0.1 -0.1 -0.1 0.1 -0.1 -0.1 0.1 -0.1 0.1 0.1 0.1
-0.1 -0.1 0.1 -0.1 -0.1 -0.1 0.1 -0.1 0.1 0.1 0.1 -0.1 0.1 0.1
-0.1 -0.1 -0.1 0.1 0.1 0.1 -0.1 -0.1 0.1 0.1 0.1 0.1 0.1 -0.1
疊加完得到新的x0值,由于修改量較小,可以認(rèn)為對原始數(shù)據(jù)修改不大,但是預(yù)測值達(dá)到了0.984356,可以認(rèn)為標(biāo)簽從0變成了1。
以攻擊InceptionV3模型為例,介紹生成攻擊樣本的基本原理。Keras內(nèi)置了這個模型,我們直接使用就可以了。從模型中直接獲取第一層的輸入作為輸入層,最后一層的輸出為輸出層。
model = inception_v3.InceptionV3()
model_input_layer = model.layers[0].input
model_output_layer = model.layers[-1].output
然后加載我們攻擊的圖片,比如我們的小豬。這里需要特別強(qiáng)調(diào)的是,NumPy出于性能考慮,默認(rèn)的變量賦值會引用同樣一份內(nèi)存,所以我們需要使用np.copy手工強(qiáng)制復(fù)制一份圖像數(shù)據(jù)。
img = image.load_img("../picture/pig.jpg", target_size=(299, 299))
original_image = image.img_to_array(img)
hacked_image = np.copy(original_image)
為了避免圖像變化過大,超過肉眼可以接受的程度,我們需要定義閾值。
max_change_above = original_image + 0.01
max_change_below = original_image - 0.01
下面我們要定義最關(guān)鍵的三個函數(shù)了,我們定義損失函數(shù)為識別為烤面包機(jī)的概率,因此我們需要使用梯度上升算法,不斷追求損失函數(shù)的最大化,變量objecttypeto_fake定義的就是烤面包機(jī)對應(yīng)的標(biāo)簽,在InceptionV3中面包機(jī)的標(biāo)簽為859。
object_type_to_fake = 859
有了損失函數(shù)以后,我們就可以通過Keras的接口獲取到對應(yīng)的梯度函數(shù)。最后通過K.function獲取一個Keras函數(shù)實例,該函數(shù)的輸入列表分別為輸入層和當(dāng)前是訓(xùn)練模式還是測試模式的標(biāo)記learning_phase(),輸出列表是損失函數(shù)和梯度。關(guān)于K.function的使用建議閱讀Keras的在線文檔。
cost_function = model_output_layer[0, object_type_to_fake]
gradient_function = K.gradients(cost_function, model_input_layer)[0]
grab_cost_and_gradients_from_model =
K.function([model_input_layer,K.learning_phase()],
[cost_function, gradient_function] )
除了迭代環(huán)節(jié),F(xiàn)GSM與基于梯度上升的算法完全相同。在迭代環(huán)節(jié),我們通過NumPy的sign函數(shù)對梯度進(jìn)行處理,然后迭代更新圖片內(nèi)容。
e=0.007
while cost < 0.60:
cost, gradients = grab_cost_and_gradients_from_model([hacked_image, 0])
n=np.sign(gradients)
hacked_image +=n*e
hacked_image = np.clip(hacked_image, max_change_below, max_change_above)
hacked_image = np.clip(hacked_image, -1.0, 1.0)
print("batch:{} Cost: {:.8}%".format(index,cost * 100))
index+=1
在我的Mac本經(jīng)過2分鐘16次迭代訓(xùn)練,獲得了新的家豬圖像,但是機(jī)器學(xué)習(xí)模型識別它為烤面包機(jī)的概率卻達(dá)到了74.31%,迭代次數(shù)明顯減少。
batch:11 Cost: 2.7044188%
batch:12 Cost: 16.616838%
batch:13 Cost: 38.806009%
batch:14 Cost: 52.693129%
batch:15 Cost: 38.372087%
batch:16 Cost: 74.312818%
基于FGSM算法被識別為烤面包機(jī)的家豬(概率為74.31%)的圖片效果如下。
由于我們設(shè)置的退出條件是概率大于60%,所以FGSM沒有繼續(xù)迭代下去,我們通過設(shè)置閾值可以得到概率更大的圖片,在進(jìn)一步的實驗中我們通過37次迭代得到了概率為99.56%的攻擊圖片。
batch:34 Cost: 97.030985%
batch:35 Cost: 90.346575%
batch:36 Cost: 63.920081%
batch:37 Cost: 99.558592%
基于FGSM算法被識別為烤面包機(jī)的家豬(概率為99.56%)的圖片效果如下。
Ian Goodfellow在他的論文《Adversarial examples in the physical world》中指出,針對圖像的攻擊方式在現(xiàn)實生活中也可以發(fā)生,攻擊圖片經(jīng)過拍照打印后依然可以欺騙圖像分類模型,系統(tǒng)錯把“洗衣機(jī)”標(biāo)簽為“保險箱”。
參考文獻(xiàn)
Ian J. Goodfellow, Jonathon Shlens & Christian Szegedy,Explaining and Harnessing Adversarial Examples,arXiv:1412.6572
Alexey Kurakin, Ian Goodfellow, Samy Bengio,Adversarial examples in the physical world,arXiv:1607.02533
https://baike.baidu.com/item/sign/115763
劉焱,《web安全之強(qiáng)化學(xué)習(xí)與GAN》,機(jī)械工業(yè)出版社
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。