最近基于對抗樣本做了一些工作,這里寫一篇論文介紹對抗樣本基本的原理和生成方法。內(nèi)容上參考Goodfellow的論文 Explaining and Harnessing Adversarial Examples
一、什么是對抗樣本?
對抗樣本的概念最早提出于2014年Szegedy的論文 Intriguing Properties of Neural Networks. 在論文,作者發(fā)現(xiàn)了一種有趣的現(xiàn)象,即:當前流行的機器學習模型包括神經(jīng)網(wǎng)絡(luò)會容易以很高的置信度分錯和原始樣本僅僅有輕微不同的樣本,這類樣本被稱為對抗樣本。這一現(xiàn)象揭示了現(xiàn)有機器學習算法的盲點和不足,即沒有完全掌握數(shù)據(jù)的本質(zhì)特點,從而容易受到被精心設(shè)計的對抗樣本的攻擊
下圖很好的描述了對抗樣本的作用, 即原始圖片在被加上輕微的噪聲之后,分類器會以很高的置信度將圖片識別為另外一類
那么,對抗樣本的原理是什么呢?
二、對抗樣本的線性解釋
Goodfellow在論文中給出了一個解釋:在線性高維情況下,即使是很小的擾動,也會對輸出造成非常大的影響。這里將對抗樣本記為 x ˉ \bar{x} x ˉ , 線性模型的權(quán)重為 w w w , 擾動為 η \eta η , 同時擾動的強度限制在一定范圍內(nèi) ∥ η ∥ L < ε \left \|\eta\right \|_L<\varepsilon ∥ η ∥ L ? < ε . 我們可以有式(1)
w x ˉ = w x + x η w\bar{x}=wx+x\eta w x ˉ = w x + x η (1)
從上式我們可以知道,當 w w w 的維度很高時,即使擾動 η \eta η 很小,最終的輸出也會受到很大的影響。Goodfellow認為,當前主流的機器學習模型中存在太多的線性性質(zhì),如神經(jīng)網(wǎng)絡(luò)的每一層其實都是一個線性模型,而常用的ReLu激活函數(shù)也局部線性的,所以,在高維情況下,小的擾動也會造成很大的輸出誤差
三、快速梯度符號法FGSM生成對抗樣本
基于提出的線性解釋,Goodfellow提出了一種非常簡單的生成對抗樣本的方法稱為fast gradient sign method (FGSM). 式(1)中的擾動 η \eta η 為
η = ε s i g n ( ▽ x J ( Θ , x , y ) ) \eta =\varepsilon sign(\bigtriangledown_{x}J(\Theta,x,y)) η = ε s i g n ( ▽ x ? J ( Θ , x , y ) ) (2)
這里 J J J 表示損失函數(shù),簡單來說,就是模型的損失函數(shù)對樣本求導,再取符號函數(shù),乘上擾動強度,便得到了對抗樣本
這里給出一份為普通多層神經(jīng)網(wǎng)絡(luò)生成對抗樣本的代碼
from sklearn.datasets import load_boston
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras import optimizers
import keras.backend as K
from keras import losses
from keras.models import Sequential
from keras.layers import Dense
import warnings
warnings.filterwarnings("ignore")
boston = load_boston()
data = boston.data
data = preprocessing.StandardScaler().fit_transform(data)
label = boston.target
traindata, testdata, trainlabel, testlabel = train_test_split(data,label,test_size=0.2, random_state=0)
model = Sequential()
model.add(Dense(128,input_dim=13,activation='relu'))
model.add(Dense(64,activation='relu'))
model.add(Dense(64,activation='relu'))
model.add(Dense(32,activation='relu'))
model.add(Dense(1))
adam = optimizers.adam(lr=0.01, decay=1e-2)
model.compile(loss='mse',optimizer=adam)
model.fit(traindata,trainlabel,batch_size=64, epochs=200,verbose=0,shuffle=True,validation_split=0.1)
testdata += 0.1
score = model.evaluate(testdata,testlabel,verbose=0,batch_size=64)
print(score)
sess = K.get_session()
testdata_adv = testdata
epochs = 1
epsilon = 0.1
loss = losses.mse(testlabel,model.output)
grads = K.gradients(loss,model.input)
delta = K.sign(grads[0])
testdata_adv += epsilon*delta
testdata_adv = sess.run(testdata_adv, feed_dict={model.input:testdata})
testdata_adv = preprocessing.StandardScaler().fit_transform(testdata_adv)
score = model.evaluate(testdata_adv,testlabel,verbose=0,batch_size=64)
print(score)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
