对抗网络学习-FGSM对抗样本生成
對抗樣本指的是一個經過微小調整就可以讓機器學習算法輸出錯誤結果的輸入樣本。在圖像識別中,可以理解為原來被一個卷積神經網絡(CNN)分類為一個類(比如“熊貓”)的圖片,經過非常細微甚至人眼無法察覺的改動后,突然被誤分成另一個類(比如“長臂猿”)。
為什么這樣輕微的擾動可以對神經網絡造成如此大的影響,業界目前的共識認為這不是過擬合的結果,而是因為輸入特征維度過高和模型的線性性質導致的。
深度模型本實確實是一個非常非線性的模型,但是模型的組成部分都是線性的,全連接網絡的矩陣乘法是線性的,卷積網絡的卷積計算也是計算點乘,同樣也是線性的,哪怕是激活函數,看似是為了造成模型的非線性,但是目前主流的relu激活函數其實在部分區域內也是線性的。
因此,盡管深度模型整體呈非線性,但是其中的線性部分卻依舊占了很大一部分,也正是如此,輕微的擾動經過網絡的積累后會形成雪崩效應,從而對最終結果造成影響。
更具體的來說,在高維空間中,每個像素值即使改變很小,這些改變會通過線性模型的參數進行點乘累計造成很明顯的變化。只要方向正確,即使數據上只是邁出了一小步,在特征空間上就是一大步,極大概率會跨越決策層。
Fast Gradient Sign Method (FGSM)
關鍵公式
x′=x+η
η =εsign(▽xJ(θ,x,y))
參數解釋:
x -輸入圖象 ,x^′-輸出圖像, η-擾動
ε-步長,即擾動大小
Sign()-符號函數,J(θ,x,y)損失函數
θ -模型參數,x-模型輸入,y-標簽
主要思想
攻擊成功的目標是使得模型分類錯誤,也即是利用加入擾動的樣本使得模型的損失增大,而我們沿著梯度方向添加擾動,可以對分類結果產生最大的影響,因為我們一般是沿著梯度下降的方向去減小損失函數。
代碼實現
from __future__ import absolute_import, division, print_function, unicode_literals import warnings warnings.filterwarnings('ignore') import tensorflow as tf import matplotlib as mpl import matplotlib.pyplot as plt mpl.rcParams['figure.figsize'] = (8, 8) mpl.rcParams['axes.grid'] = False #MobileNetV2# Let's load the pretained MobileNetV2 model and the ImageNet class names. pretrained_model = tf.keras.applications.MobileNetV2(include_top=True, weights='imagenet') pretrained_model.trainable = False# ImageNet labels decode_predictions = tf.keras.applications.mobilenet_v2.decode_predictions# Helper function to preprocess the image so that it can be inputted in MobileNetV2 # 對圖像預處理,使得圖像可以輸入MobileNetV2模型 def preprocess(image):image = tf.cast(x=image, dtype=tf.float32)image = image/255image = tf.image.resize(images=image, size=(224, 224))image = image[None, ...]return image# Helper function to extract labels from probability vector # 得到圖像真實標簽 將圖像輸入模型并得到概率最高的分類結果 def get_imagenet_label(probs):return decode_predictions(probs, top=1)[0][0]#只獲取第一個#image_path = tf.keras.utils.get_file(fname='YellowLabradorLooking_new.jpg', origin='https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg')#image_path=tf.keras.utils.get_file('turtle.jpg','https://storage.googleapis.com/download.tensorflow.org/example_images/Green_Sea_Turtle_grazing_seagrass.jpg') image_path = tf.keras.utils.get_file(fname='grace_hopper.jpg', origin='https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg') image_raw = tf.io.read_file(filename=image_path)image = tf.image.decode_image(contents=image_raw)#可以自動判定圖像格式然后 decodeimage = preprocess(image)#預處理 image_probs = pretrained_model.predict(image) #模型預測,輸入測試集,輸出預測結果---概率plt.figure() plt.imshow(image[0]) _, image_class, class_confidence = get_imagenet_label(image_probs)#probs? plt.title('{} : {:.2f}% Confidence'.format(image_class, class_confidence*100))#加入標簽 plt.show()#計算梯度 loss_object = tf.keras.losses.CategoricalCrossentropy()#損失函數--交叉熵損失函數 #交叉熵是用來評估當前訓練得到的概率分布與真實分布的差異情況。 #它刻畫的是實際輸出(概率)與期望輸出(概率)的距離,也就是交叉熵的值越小,兩個概率分布就越接近。def create_adversarial_pattern(input_image, input_label):with tf.GradientTape() as tape: #梯度帶tape.watch(tensor=input_image) #watch函數把需要計算梯度的變量input_image加進來prediction = pretrained_model(input_image)loss = loss_object(input_label, prediction)# Get the gradients of the loss w.r.t to the input image.獲取梯度gradient = tape.gradient(loss, input_image)# Get the sign of the gradients to create the perturbation.獲取符號signed_grad = tf.sign(gradient) # 符號梯度攻擊return signed_grad# Get the input label of the image. labrador_retriever_index = 208 label = tf.one_hot(labrador_retriever_index, image_probs.shape[-1]) label = tf.reshape(label, (1, image_probs.shape[-1]))perturbations = create_adversarial_pattern(image, image_probs) plt.imshow(perturbations[0]) #定義函數來顯示圖像 def display_images(image, description): # 展示被攻擊過的圖像_, label, confidence = get_imagenet_label(pretrained_model.predict(image))plt.figure()plt.imshow(image[0])plt.title('{} \n {} : {:.2f}% Confidence'.format(description,label, confidence*100))plt.show()#加入噪聲后再將圖像輸入模型進行判斷 epsilons = [0, 0.01, 0.1, 0.15, 0.20] descriptions = [('Epsilon = {:0.3f}'.format(eps) if eps else 'Input') for eps in epsilons]for i, eps in enumerate(epsilons):adv_x = image + eps*perturbations[0]adv_x = tf.clip_by_value(adv_x, 0, 1) # 將值限制在[0,1]范圍內display_images(adv_x, descriptions[i])
參考鏈接
https://blog.csdn.net/nemoyy/article/details/81052301
https://blog.csdn.net/nemoyy/article/details/81052301
https://download.csdn.net/download/qq_35225463/11646431
總結
以上是生活随笔為你收集整理的对抗网络学习-FGSM对抗样本生成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交叉小波分析matlab,[转载]Mat
- 下一篇: matlab小波分析