קלט / פלט של גוגל חוזר 18-20 במאי! שמור מקום ובנה את לוח הזמנים שלך הירשם עכשיו

דוגמא לנגדית באמצעות FGSM

צפה ב- TensorFlow.org הפעל בגוגל קולאב צפה במקור ב- GitHub הורד מחברת

מדריך זה יוצר דוגמה ליריבית תוך שימוש בהתקפה מהירה (Gradient Signed Method) (FGSM) כמתואר בהסבר ורתמה של דוגמאות יריבות מאת Goodfellow et al . זו הייתה אחת ההתקפות הראשונות והפופולריות ביותר שביצו לרשת רשת עצבית.

מהי דוגמה יריבה?

דוגמאות יריבות הן תשומות מיוחדות שנוצרו במטרה לבלבל רשת עצבית, וכתוצאה מכך סיווג שגוי של קלט נתון. לא ניתן להבחין בין תשומות ידועות לשמצה בעין האנושית, אך גורמות לרשת לא לזהות את תוכן התמונה. ישנם מספר סוגים של התקפות כאלה, עם זאת, כאן ההתמקדות היא בהתקפת שיטת סימן שיפוע מהיר, שהיא התקפת קופסא לבנה שמטרתה להבטיח סיווג שגוי. מתקפת קופסאות לבנות היא המקום בו לתוקף יש גישה מלאה לדגם המותקף. אחת הדוגמאות המפורסמות ביותר לתמונה יריבה המוצגת להלן לקוחה מהמאמר הנ"ל.

דוגמה יריבה

כאן, החל בתמונה של פנדה, התוקף מוסיף הפרעות קטנות (עיוותים) לתמונה המקורית, מה שמביא לכך שהמודל מתייג תמונה כגיבון, בביטחון גבוה. תהליך הוספת הפרעות אלה מוסבר להלן.

שיטת סימן שיפוע מהיר

שיטת סימן השיפוע המהיר פועלת באמצעות שיפועי הרשת העצבית ליצירת דוגמא יריבה. עבור תמונת קלט, השיטה משתמשת בשיפועי האובדן ביחס לתמונת הקלט ליצירת תמונה חדשה שממקסמת את ההפסד. תמונה חדשה זו נקראת דימוי היריב. ניתן לסכם זאת באמצעות הביטוי הבא:

$$adv\_x = x + \epsilon*\text{sign}(\nabla_xJ(\theta, x, y))$$

איפה

  • adv_x: תמונה יריבה.
  • x: תמונת קלט מקורית.
  • y: תווית קלט מקורית.
  • $ \ epsilon $: מכפיל כדי להבטיח שההפרעות קטנות.
  • $ \ theta $: פרמטרים של דגם.
  • $ J $: הפסד.

מאפיין מסקרן כאן, הוא העובדה שהמעברים נלקחים ביחס לתמונת הקלט. זה נעשה מכיוון שהמטרה היא ליצור תמונה שממקסמת את האובדן. שיטה להשיג זאת היא למצוא כמה כל פיקסל בתמונה תורם לערך האובדן, ולהוסיף הפרעה בהתאם. זה עובד די מהר מכיוון שקל למצוא כיצד כל פיקסל קלט תורם לאובדן באמצעות כלל השרשרת ומציאת הדרגתיות הנדרשות. לפיכך, מעבירים את השיפועים ביחס לתמונה. בנוסף, מכיוון שהמודל כבר לא מאומן (לפיכך השיפוע לא נלקח ביחס למשתנים הניתנים לאימון, כלומר פרמטרי המודל), ולכן פרמטרי המודל נשארים קבועים. המטרה היחידה היא להטעות מודל שהוכשר כבר.

אז בואו ננסה להטעות דוגמנית מאומנת מראש. במדריך זה, המודל הוא מודל MobileNetV2 , מאומנים מראש ב- ImageNet .

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 המאומן מראש ואת שמות המחלקות ImageNet.

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
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet_v2/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224.h5
14540800/14536120 [==============================] - 0s 0us/step
# Helper function to preprocess the image so that it can be inputted in MobileNetV2
def preprocess(image):
  image = tf.cast(image, tf.float32)
  image = tf.image.resize(image, (224, 224))
  image = tf.keras.applications.mobilenet_v2.preprocess_input(image)
  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]

תמונה מקורית

בואו נשתמש בתמונת דוגמה של לברדור רטריבר מאת מירקו CC-BY-SA 3.0 מתוך Wikimedia Common וניצור ממנו דוגמאות יריבות. השלב הראשון הוא עיבוד מקדים שלו כך שניתן יהיה להזין אותו כקלט למודל MobileNetV2.

image_path = tf.keras.utils.get_file('YellowLabradorLooking_new.jpg', 'https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg')
image_raw = tf.io.read_file(image_path)
image = tf.image.decode_image(image_raw)

image = preprocess(image)
image_probs = pretrained_model.predict(image)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg
90112/83281 [================================] - 0s 0us/step

בואו נסתכל על התמונה.

plt.figure()
plt.imshow(image[0] * 0.5 + 0.5)  # To change [-1, 1] to [0,1]
_, image_class, class_confidence = get_imagenet_label(image_probs)
plt.title('{} : {:.2f}% Confidence'.format(image_class, class_confidence*100))
plt.show()
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/imagenet_class_index.json
40960/35363 [==================================] - 0s 0us/step

png

צור את התמונה היריבית

יישום שיטת סימני שיפוע מהירים

השלב הראשון הוא יצירת הפרעות אשר ישמשו לעיוות התמונה המקורית וכתוצאה מכך תמונה אדברסרית. כאמור, למשימה זו לוקחים את השיפועים ביחס לתמונה.

loss_object = tf.keras.losses.CategoricalCrossentropy()

def create_adversarial_pattern(input_image, input_label):
  with tf.GradientTape() as tape:
    tape.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, label)
plt.imshow(perturbations[0] * 0.5 + 0.5);  # To change [-1, 1] to [0,1]
<matplotlib.image.AxesImage at 0x7fea986d07f0>

png

בואו ננסה זאת לערכים שונים של אפסילון ונצפה בתמונה שהתקבלה. תוכלו לשים לב שככל שערך epsilon גדל, קל יותר להטעות את הרשת. עם זאת, זה בא כקיזוז שגורם לכך שההפרעות ניתנות לזיהוי יותר.

def display_images(image, description):
  _, label, confidence = get_imagenet_label(pretrained_model.predict(image))
  plt.figure()
  plt.imshow(image[0]*0.5+0.5)
  plt.title('{} \n {} : {:.2f}% Confidence'.format(description,
                                                   label, confidence*100))
  plt.show()
epsilons = [0, 0.01, 0.1, 0.15]
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
  adv_x = tf.clip_by_value(adv_x, -1, 1)
  display_images(adv_x, descriptions[i])

png

png

png

png

הצעדים הבאים

עכשיו שאתה יודע על התקפות יריבות, נסה זאת על מערכי נתונים שונים וארכיטקטורות שונות. אתה יכול גם ליצור ולהכשיר את המודל שלך, ואז לנסות להטעות אותו באותה שיטה. אתה יכול גם לנסות לראות כיצד הביטחון בתחזיות משתנה כאשר אתה משנה אפסון.

אף על פי שהמתקפה שהוצגה במדריך זה הייתה עוצמתית, הייתה רק תחילת המחקר על התקפות יריבות, ומאז היו מספר מאמרים שיצרו התקפות חזקות יותר. בנוסף להתקפות יריבות, המחקר הוביל גם ליצירת הגנות, שמטרתן ליצור מודלים חזקים של למידת מכונה. אתה יכול לסקור את מאמר הסקר הזה כדי לקבל רשימה מקיפה של התקפות והגנות יריבות.

לקבלת יישומים רבים יותר של התקפות יריבות והגנות, ייתכן שתרצה לראות את ספריית הדוגמאות היריבות CleverHans .