Xem trên TensorFlow.org | Chạy trong Google Colab | Xem nguồn trên GitHub | Tải xuống sổ ghi chép |
Hướng dẫn này tạo ra một ví dụ về đối thủ bằng cách sử dụng tấn công Phương pháp ký tên nhanh (FGSM) như được mô tả trong Giải thích và khai thác các ví dụ về đối thủ của Goodfellow et al . Đây là một trong những cuộc tấn công đầu tiên và phổ biến nhất để đánh lừa mạng nơ-ron.
Ví dụ về đối thủ là gì?
Ví dụ đối nghịch là các đầu vào chuyên biệt được tạo ra với mục đích gây nhầm lẫn cho mạng nơ-ron, dẫn đến việc phân loại sai một đầu vào nhất định. Mắt người không thể phân biệt được những đầu vào khét tiếng này, nhưng lại khiến mạng không xác định được nội dung của hình ảnh. Có một số kiểu tấn công như vậy, tuy nhiên, ở đây tập trung vào cuộc tấn công theo phương pháp dấu hiệu gradient nhanh, là một cuộc tấn công hộp trắng với mục tiêu là đảm bảo phân loại sai. Một cuộc tấn công hộp trắng là nơi kẻ tấn công có toàn quyền truy cập vào mô hình bị tấn công. Một trong những ví dụ nổi tiếng nhất về hình ảnh kẻ thù được hiển thị dưới đây được lấy từ bài báo nói trên.
Ở đây, bắt đầu với hình ảnh của một con gấu trúc, kẻ tấn công thêm những nhiễu loạn nhỏ (sự biến dạng) vào hình ảnh gốc, dẫn đến việc người mẫu gắn nhãn hình ảnh này là một con vượn với độ tin cậy cao. Quá trình thêm các nhiễu này được giải thích bên dưới.
Phương pháp ký hiệu gradient nhanh
Phương pháp dấu hiệu gradient nhanh hoạt động bằng cách sử dụng các gradient của mạng nơ-ron để tạo ra một ví dụ đối nghịch. Đối với hình ảnh đầu vào, phương pháp này sử dụng các gradient của sự mất mát đối với hình ảnh đầu vào để tạo ra một hình ảnh mới giúp giảm thiểu tối đa sự mất mát. Hình ảnh mới này được gọi là hình ảnh đối nghịch. Điều này có thể được tóm tắt bằng cách sử dụng biểu thức sau:
\[adv\_x = x + \epsilon*\text{sign}(\nabla_xJ(\theta, x, y))\]
ở đâu
- adv_x: Hình ảnh đối nghịch.
- x: Hình ảnh đầu vào gốc.
- y: Nhãn đầu vào gốc.
- \(\epsilon\) : Hệ số nhân để đảm bảo nhiễu loạn là nhỏ.
- \(\theta\) : Thông số mô hình.
- \(J\) : Mất mát.
Một thuộc tính hấp dẫn ở đây, là thực tế là các gradient được thực hiện đối với hình ảnh đầu vào. Điều này được thực hiện vì mục tiêu là tạo ra một hình ảnh tối đa hóa sự mất mát. Một phương pháp để thực hiện điều này là tìm mức độ đóng góp của mỗi pixel trong hình ảnh vào giá trị mất mát và thêm nhiễu loạn cho phù hợp. Điều này hoạt động khá nhanh vì có thể dễ dàng tìm ra cách mỗi pixel đầu vào góp phần vào sự mất mát bằng cách sử dụng quy tắc chuỗi và tìm các độ dốc cần thiết. Do đó, các gradient được thực hiện đối với hình ảnh. Ngoài ra, vì mô hình không còn được đào tạo (do đó gradient không được sử dụng đối với các biến có thể đào tạo, tức là các tham số của mô hình), và do đó, các tham số của mô hình vẫn không đổi. Mục tiêu duy nhất là đánh lừa một người mẫu đã được đào tạo.
Vì vậy, chúng ta hãy thử và đánh lừa một mô hình được đào tạo trước. Trong hướng dẫn này, mô hình là mô hình MobileNetV2 , được đào tạo trước trên 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
Hãy tải mô hình MobileNetV2 được đào tạo trước và các tên lớp 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 14548992/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]
Ảnh gốc
Hãy sử dụng hình ảnh mẫu về Labrador Retriever của Mirko CC-BY-SA 3.0 từ Wikimedia Common và tạo các ví dụ đối thủ từ nó. Bước đầu tiên là xử lý trước nó để nó có thể được cung cấp làm đầu vào cho mô hình 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 98304/83281 [===================================] - 0s 0us/step
Chúng ta hãy nhìn vào hình ảnh.
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 49152/35363 [=========================================] - 0s 0us/step
Tạo hình ảnh đối thủ
Triển khai phương pháp ký hiệu gradient nhanh
Bước đầu tiên là tạo nhiễu sẽ được sử dụng để làm sai lệch hình ảnh gốc, dẫn đến hình ảnh đối nghịch. Như đã đề cập, đối với tác vụ này, các gradient được thực hiện đối với hình ảnh.
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
Các nhiễu loạn kết quả cũng có thể được hình dung.
# 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]
Hãy thử điều này cho các giá trị khác nhau của epsilon và quan sát hình ảnh kết quả. Bạn sẽ nhận thấy rằng khi giá trị của epsilon được tăng lên, việc đánh lừa mạng trở nên dễ dàng hơn. Tuy nhiên, điều này xảy ra như một sự đánh đổi dẫn đến các nhiễu loạn trở nên dễ nhận dạng hơn.
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])
Bước tiếp theo
Bây giờ bạn đã biết về các cuộc tấn công đối thủ, hãy thử điều này trên các bộ dữ liệu khác nhau và các kiến trúc khác nhau. Bạn cũng có thể tạo và đào tạo mô hình của riêng mình, sau đó cố gắng đánh lừa nó bằng phương pháp tương tự. Bạn cũng có thể thử và xem mức độ tin cậy trong các dự đoán thay đổi như thế nào khi bạn thay đổi epsilon.
Mặc dù mạnh mẽ, cuộc tấn công được hiển thị trong hướng dẫn này chỉ là bước khởi đầu của nghiên cứu về các cuộc tấn công đối thủ và đã có nhiều bài báo tạo ra các cuộc tấn công mạnh mẽ hơn kể từ đó. Ngoài các cuộc tấn công đối thủ, nghiên cứu cũng dẫn đến việc tạo ra các hệ thống phòng thủ, nhằm mục đích tạo ra các mô hình học máy mạnh mẽ. Bạn có thể xem lại bài khảo sát này để biết danh sách đầy đủ về các cuộc tấn công và phòng thủ của đối thủ.
Để biết thêm nhiều cách triển khai tấn công và phòng thủ đối phương, bạn có thể muốn xem thư viện ví dụ về đối thủ CleverHans .