最近基于對(duì)抗樣本做了一些工作,這里寫一篇論文介紹對(duì)抗樣本基本的原理和生成方法。內(nèi)容上參考Goodfellow的論文 Explaining and Harnessing Adversarial Examples
一、什么是對(duì)抗樣本?
對(duì)抗樣本的概念最早提出于2014年Szegedy的論文 Intriguing Properties of Neural Networks. 在論文,作者發(fā)現(xiàn)了一種有趣的現(xiàn)象,即:當(dāng)前流行的機(jī)器學(xué)習(xí)模型包括神經(jīng)網(wǎng)絡(luò)會(huì)容易以很高的置信度分錯(cuò)和原始樣本僅僅有輕微不同的樣本,這類樣本被稱為對(duì)抗樣本。這一現(xiàn)象揭示了現(xiàn)有機(jī)器學(xué)習(xí)算法的盲點(diǎn)和不足,即沒有完全掌握數(shù)據(jù)的本質(zhì)特點(diǎn),從而容易受到被精心設(shè)計(jì)的對(duì)抗樣本的攻擊
下圖很好的描述了對(duì)抗樣本的作用, 即原始圖片在被加上輕微的噪聲之后,分類器會(huì)以很高的置信度將圖片識(shí)別為另外一類
那么,對(duì)抗樣本的原理是什么呢?
二、對(duì)抗樣本的線性解釋
Goodfellow在論文中給出了一個(gè)解釋:在線性高維情況下,即使是很小的擾動(dòng),也會(huì)對(duì)輸出造成非常大的影響。這里將對(duì)抗樣本記為 x ˉ \bar{x} x ˉ , 線性模型的權(quán)重為 w w w , 擾動(dòng)為 η \eta η , 同時(shí)擾動(dòng)的強(qiáng)度限制在一定范圍內(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)
從上式我們可以知道,當(dāng) w w w 的維度很高時(shí),即使擾動(dòng) η \eta η 很小,最終的輸出也會(huì)受到很大的影響。Goodfellow認(rèn)為,當(dāng)前主流的機(jī)器學(xué)習(xí)模型中存在太多的線性性質(zhì),如神經(jīng)網(wǎng)絡(luò)的每一層其實(shí)都是一個(gè)線性模型,而常用的ReLu激活函數(shù)也局部線性的,所以,在高維情況下,小的擾動(dòng)也會(huì)造成很大的輸出誤差
三、快速梯度符號(hào)法FGSM生成對(duì)抗樣本
基于提出的線性解釋,Goodfellow提出了一種非常簡(jiǎn)單的生成對(duì)抗樣本的方法稱為fast gradient sign method (FGSM). 式(1)中的擾動(dòng) η \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ù),簡(jiǎn)單來說,就是模型的損失函數(shù)對(duì)樣本求導(dǎo),再取符號(hào)函數(shù),乘上擾動(dòng)強(qiáng)度,便得到了對(duì)抗樣本
這里給出一份為普通多層神經(jīng)網(wǎng)絡(luò)生成對(duì)抗樣本的代碼
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號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
