9.7.2 運行測試代碼
9.7.2運行測試代碼
robust-ml提供了測試代碼,下載路徑為:
在測試代碼中attack.py文件實現了PGD和FGSM攻擊演算法,攻擊對象是InceptionV3模型。其中PGD演算法是一個輕量級的攻擊演算法,基本思路是基於迭代優化,但是每次迭代更新時,會根據預先設置的閾值進行數據裁剪,我們結合代碼詳細介紹PGD演算法的實現。首先繼承robustml.attack.Attack類實現PGD演算法。
classInceptionV3PGDAttack(robustml.attack.Attack):
在類的初始化函數中,輸入的參數分別為:
#TensorFlow的會話
self._sess=sess
#被攻擊的模型
self._model=model
#每個像素允許的最大擾動,超過的將直接截斷
self._epsilon=epsilon
#最大迭代次數,默認為100
self._max_steps=max_steps
#學習速率,默認為0.001
self._learning_rate=learning_rate
#debug開關,默認為False
self._debug=debug
然後定義對應的標籤_label並轉換成獨熱編碼格式,損失函數定義為預測值與_label的交叉熵,並根據損失函數計算對應的梯度self._grad。
self._label=tf.placeholder(tf.int32,())
one_hot=tf.expand_dims(tf.one_hot(self._label,1000),axis=0)
self._loss=tf.nn.softmax_cross_entropy_with_logits_v2(logits=model.logits,
labels=one_hot)
self._grad,=tf.gradients(self._loss,model.input)
在robust-ml中,攻擊演算法的主要實現集中在run函數中。如果進行定向攻擊,設置定向目標為target,反之為None。
defrun(self,x,y,target):
mult=-1
iftargetisNone:
target=y
mult=1
計算圖像擾動后的上限和下限,超過定義的最大擾動將被直接截斷。迭代計算預測值、損失值和梯度值。
adv=np.copy(x)
lower=np.clip(x-self._epsilon,0,1)
upper=np.clip(x+self._epsilon,0,1)
foriinrange(self._max_steps):
p,l,g=self._sess.run(
[self._model.predictions,self._loss,self._grad],
{self._model.input:adv,self._label:target}
)
如果滿足退出條件即完成迭代,反之則使用梯度值和學習速率更新對抗樣本。定向攻擊時,預測標籤與定向攻擊目標一致時退出;無定向攻擊時,預測標籤與原分類標籤不相同時退出。
ifp!=y:
break
adv+=mult*self._learning_rate*np.sign(g)
adv=np.clip(adv,lower,upper)
攻擊的模型為InceptionV3,需要下載TensorFlow對應的預訓練版本,可直接運行setup.sh。
shsetup.sh
downloading
http://download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz
downloadedinception_v3.ckpt
調用攻擊代碼在run.py中進行,其中需要指定的參數主要為ImageNet2012數據集的路徑imagenet-path和攻擊演算法attack。默認情況下會攻擊100張圖片,如果希望修改攻擊圖片的範圍,可以通過指定start和end來設置起始和結束的圖片序號。
parser=argparse.ArgumentParser()
parser.add_argument('--imagenet-path',type=str,required=True,
help='directorycontaining`val.txt`and`val/`folder')
parser.add_argument('--start',type=int,default=0)
parser.add_argument('--end',type=int,default=100)
parser.add_argument('--attack',type=str,default='pgd',help='pgd|fgsm|
none')
args=parser.parse_args()
run.py會創建TensorFlow會話並初始化InceptionV3模型。
#創建TensorFlow會話
sess=tf.Session()
#初始化模型
model=InceptionV3(sess)
robust-ml通過provider.ImageNet封裝了ImageNet2012。整個攻擊過程在robustml.evaluate.evaluate函數中調用並評估攻擊和防禦效果。其中需要特別指出的是deterministic參數表示是否隨機打亂圖片順序和定向攻擊的目標標籤,如果想提高隨機性可以設置為True,如果想讓每次運行的結果保持穩定可以設置為False。
#初始化ImageNet圖像文件的數據發生器
provider=robustml.provider.ImageNet(args.imagenet_path,(299,299,3))
success_rate=robustml.evaluate.evaluate(model,attack,provider,
start=args.start,
end=args.end,
deterministic=True,
debug=True)
print('attacksuccessrate:%.2f%%(over%ddatapoints)'%(success_
rate*100,args.end-args.start))
運行FGSM攻擊演算法,攻擊成功率為83%。
pythonrun.py--imagenet-path../data/--attackfgsm
attacksuccessrate:83.00%(over100datapoints)
運行PGD攻擊演算法,攻擊成功率為100%。
pythonrun.py--imagenet-path../data/--attackpgd
attacksuccessrate:100.00%(over100datapoints)
robust-ml運行的演算法是定向攻擊還是無定向攻擊,由模型的攻擊模式決定。在evaluate函數的實現中可以發現。
https://github.com/robust-ml/robustml/blob/master/robustml/evaluate.py
evaluate函數會讀取模型的攻擊模式的targeted屬性,默認都是無定向攻擊。
threat_model=model.threat_model
targeted=threat_model.targeted
本例中使用的攻擊模式為linf,為無定向攻擊。
self._threat_model=robustml.threat_model.Linf(epsilon=0.01)