دعونا نتعرف على إحدى الهجمات على الشبكة العصبية ، مما يؤدي إلى أخطاء التصنيف بأقل قدر من التأثيرات الخارجية. تخيل للحظة أن الشبكة العصبية هي أنت. وفي الوقت الحالي ، أثناء شرب فنجان من القهوة العطرية ، يمكنك تصنيف صور القطط بدقة تزيد عن 90 بالمائة دون حتى الشك في أن "هجوم البكسل الواحد" حول "قططك" إلى شاحنات.والآن سنتوقف مؤقتًا ، وننقل القهوة جانبًا ، ونستورد جميع المكتبات التي نحتاجها ونرى كيف تعمل هجمات البكسل هذه.الغرض من هذا الهجوم هو جعل الخوارزمية (الشبكة العصبية) تعطي إجابة غير صحيحة. أدناه سنرى هذا مع العديد من النماذج المختلفة للشبكات العصبية التلافيفية. باستخدام إحدى طرق التحسين الرياضي متعدد الأبعاد - التطور التفاضلي ، نجد بكسلًا خاصًا يمكنه تغيير الصورة بحيث تبدأ الشبكة العصبية في تصنيف هذه الصورة بشكل غير صحيح (على الرغم من حقيقة أن الخوارزمية في وقت سابق "تعرفت" على نفس الصورة بشكل صحيح وبدقة عالية).إستيراد المكتبات:
%matplotlib inline
import pickle
import numpy as np
import pandas as pd
import matplotlib
from keras.datasets import cifar10
from keras import backend as K
from networks.lenet import LeNet
from networks.pure_cnn import PureCnn
from networks.network_in_network import NetworkInNetwork
from networks.resnet import ResNet
from networks.densenet import DenseNet
from networks.wide_resnet import WideResNet
from networks.capsnet import CapsNet
from differential_evolution import differential_evolution
import helper
matplotlib.style.use('ggplot')
لتجربتنا ، سنقوم بتحميل مجموعة بيانات CIFAR-10 التي تحتوي على صور من العالم الحقيقي مقسمة إلى 10 فئات.(x_train, y_train), (x_test, y_test) = cifar10.load_data()
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
دعونا نلقي نظرة على أي صورة من خلال فهرسها. على سبيل المثال ، هنا على هذا الحصان.image_id = 99
helper.plot_image(x_test[image_id])
سيتعين علينا البحث عن البكسل القوي جدًا الذي يمكنه تغيير استجابة الشبكة العصبية ، مما يعني أن الوقت قد حان لكتابة وظيفة لتغيير بكسل واحد أو أكثر من الصورة.def perturb_image(xs, img):
if xs.ndim < 2:
xs = np.array([xs])
tile = [len(xs)] + [1]*(xs.ndim+1)
imgs = np.tile(img, tile)
xs = xs.astype(int)
for x,img in zip(xs, imgs):
pixels = np.split(x, len(x) // 5)
for pixel in pixels:
x_pos, y_pos, *rgb = pixel
img[x_pos, y_pos] = rgb
return imgs
تحقق من ذلك ؟! قم بتغيير بكسل واحد من حصاننا بإحداثيات (16 ، 16) إلى اللون الأصفر.image_id = 99
pixel = np.array([16, 16, 255, 255, 0])
image_perturbed = perturb_image(pixel, x_test[image_id])[0]
helper.plot_image(image_perturbed)
لإثبات الهجوم ، تحتاج إلى تنزيل نماذج مدربة مسبقًا من الشبكات العصبية على مجموعة بيانات CIFAR-10. سنستخدم نموذجين lenet و resnet ، ولكن يمكنك استخدام نماذج أخرى لتجاربك من خلال إلغاء تعليق الأسطر المقابلة من التعليمات البرمجية.lenet = LeNet()
resnet = ResNet()
models = [lenet, resnet]
بعد تحميل النماذج ، من الضروري تقييم صور الاختبار لكل نموذج للتأكد من أننا نهاجم فقط الصور المصنفة بشكل صحيح. يعرض الرمز أدناه دقة وعدد المعلمات لكل نموذج.network_stats, correct_imgs = helper.evaluate_models(models, x_test, y_test)
correct_imgs = pd.DataFrame(correct_imgs, columns=['name', 'img', 'label', 'confidence', 'pred'])
network_stats = pd.DataFrame(network_stats, columns=['name', 'accuracy', 'param_count'])
network_stats
Evaluating lenet
Evaluating resnet
Out[11]:
name accuracy param_count
0 lenet 0.748 62006
1 resnet 0.9231 470218
يمكن تقسيم جميع هذه الهجمات إلى فئتين: WhiteBox و BlackBox. الفرق بينهما هو أنه في الحالة الأولى ، نعرف جميعًا بشكل موثوق به عن الخوارزمية ، النموذج الذي نتعامل معه. في حالة BlackBox ، كل ما نحتاجه هو الإدخال (الصورة) والإخراج (احتمالات التعيين في إحدى الفئات). يشير هجوم بكسل واحد إلى BlackBox.في هذه المقالة ، نعتبر خيارين لمهاجمة بكسل واحد: غير مستهدف وموجه. في الحالة الأولى ، لن يهم على الإطلاق أي فئة ستنتمي الشبكة العصبية لقطتنا ، والأهم من ذلك ، ليس لفئة القطط. الهجوم المستهدف قابل للتطبيق عندما نريد أن تصبح قطتنا شاحنة وفقط شاحنة.ولكن كيف يمكن العثور على وحدات البكسل نفسها التي سيؤدي تغييرها إلى تغيير في فئة الصورة؟ كيفية العثور على بكسل عن طريق تغيير هجوم بكسل واحد ممكن ونجاح؟ دعونا نحاول صياغة هذه المشكلة كمشكلة تحسين ، ولكن فقط بكلمات بسيطة للغاية: من خلال هجوم غير مستهدف ، يجب علينا تقليل الثقة في الفئة المطلوبة ، ومع الهدف ، زيادة الثقة في الفئة المستهدفة.عند تنفيذ مثل هذه الهجمات ، من الصعب تحسين الوظيفة باستخدام التدرج. يجب استخدام خوارزمية تحسين لا تعتمد على سلاسة الوظيفة.تذكر أنه في تجربتنا نستخدم مجموعة بيانات CIFAR-10 ، التي تحتوي على صور من العالم الحقيقي ، بحجم 32 × 32 بكسل ، مقسمة إلى 10 فئات. وهذا يعني أن لدينا قيمًا صحيحة منفصلة من 0 إلى 31 وكثافات لونية من 0 إلى 255 ، ولا يُتوقع أن تكون الوظيفة سلسة ، بل متعرجة ، كما هو موضح أدناه:
لهذا السبب نستخدم خوارزمية التطور التفاضلي.ولكن بالعودة إلى الكود وكتابة دالة ترجع احتمالية موثوقية النموذج. إذا كانت الفئة المستهدفة صحيحة ، فنحن نريد تقليل هذه الوظيفة حتى يكون النموذج متأكدًا من فئة أخرى (وهذا غير صحيح).def predict_classes(xs, img, target_class, model, minimize=True):
imgs_perturbed = perturb_image(xs, img)
predictions = model.predict(imgs_perturbed)[:,target_class]
return predictions if minimize else 1 - predictions
image_id = 384
pixel = np.array([16, 13, 25, 48, 156])
model = resnet
true_class = y_test[image_id, 0]
prior_confidence = model.predict_one(x_test[image_id])[true_class]
confidence = predict_classes(pixel, x_test[image_id], true_class, model)[0]
print('Confidence in true class', class_names[true_class], 'is', confidence)
print('Prior confidence was', prior_confidence)
helper.plot_image(perturb_image(pixel, x_test[image_id])[0])
Confidence in true class bird is 0.00018887444
Prior confidence was 0.70661753
سنحتاج إلى الوظيفة التالية لتأكيد معيار نجاح الهجوم ، وسوف يعود صحيحًا عندما يكون التغيير كافيًا لخداع النموذج.def attack_success(x, img, target_class, model, targeted_attack=False, verbose=False):
attack_image = perturb_image(x, img)
confidence = model.predict(attack_image)[0]
predicted_class = np.argmax(confidence)
if verbose:
print('Confidence:', confidence[target_class])
if ((targeted_attack and predicted_class == target_class) or
(not targeted_attack and predicted_class != target_class)):
return True
دعونا نلقي نظرة على عمل دالة معيار النجاح. من أجل التظاهر ، نفترض هجومًا غير مستهدف.image_id = 541
pixel = np.array([17, 18, 185, 36, 215])
model = resnet
true_class = y_test[image_id, 0]
prior_confidence = model.predict_one(x_test[image_id])[true_class]
success = attack_success(pixel, x_test[image_id], true_class, model, verbose=True)
print('Prior confidence', prior_confidence)
print('Attack success:', success == True)
helper.plot_image(perturb_image(pixel, x_test[image_id])[0])
Confidence: 0.07460087
Prior confidence 0.50054216
Attack success: True
حان الوقت لجمع جميع الألغاز في صورة واحدة. سنستخدم تعديل صغير لتنفيذ التطور التفاضلي في Scipy.def attack(img_id, model, target=None, pixel_count=1,
maxiter=75, popsize=400, verbose=False):
targeted_attack = target is not None
target_class = target if targeted_attack else y_test[img_id, 0]
bounds = [(0,32), (0,32), (0,256), (0,256), (0,256)] * pixel_count
popmul = max(1, popsize // len(bounds))
def predict_fn(xs):
return predict_classes(xs, x_test[img_id], target_class,
model, target is None)
def callback_fn(x, convergence):
return attack_success(x, x_test[img_id], target_class,
model, targeted_attack, verbose)
attack_result = differential_evolution(
predict_fn, bounds, maxiter=maxiter, popsize=popmul,
recombination=1, atol=-1, callback=callback_fn, polish=False)
attack_image = perturb_image(attack_result.x, x_test[img_id])[0]
prior_probs = model.predict_one(x_test[img_id])
predicted_probs = model.predict_one(attack_image)
predicted_class = np.argmax(predicted_probs)
actual_class = y_test[img_id, 0]
success = predicted_class != actual_class
cdiff = prior_probs[actual_class] - predicted_probs[actual_class]
helper.plot_image(attack_image, actual_class, class_names, predicted_class)
return [model.name, pixel_count, img_id, actual_class, predicted_class, success, cdiff, prior_probs, predicted_probs, attack_result.x]
حان الوقت لمشاركة نتائج الدراسة (الهجوم) ومعرفة كيف سيؤدي تغيير بكسل واحد فقط إلى تحويل الضفدع إلى كلب ، والقط إلى ضفدع ، وسيارة إلى طائرة. ولكن كلما سمح بتغيير المزيد من نقاط الصورة ، زاد احتمال حدوث هجوم ناجح على أي صورة.

شرح هجوم ناجح على صورة ضفدع باستخدام نموذج resnet. يجب أن نرى الثقة في التراجع الحقيقي في الفصل بعد عدة تكرارات.image_id = 102
pixels = 1
model = resnet
_ = attack(image_id, model, pixel_count=pixels, verbose=True)
Confidence: 0.9938618
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.77454716
Confidence: 0.53226393
Confidence: 0.53226393
Confidence: 0.53226393
Confidence: 0.53226393
Confidence: 0.4211318
كانت هذه أمثلة على هجوم غير مستهدف ، والآن سنقوم بهجوم مستهدف ونختار إلى أي فئة نود أن يقوم النموذج بتصنيف الصورة. المهمة أكثر تعقيدًا بكثير من المهمة السابقة ، لأننا سنجعل الشبكة العصبية تصنف صورة السفينة كسيارة ، والحصان كقط.
أدناه سنحاول الحصول على lenet لتصنيف صورة السفينة كسيارة.image_id = 108
target_class = 1
pixels = 3
model = lenet
print('Attacking with target', class_names[target_class])
_ = attack(image_id, model, target_class, pixel_count=pixels, verbose=True)
Attacking with target automobile
Confidence: 0.044409167
Confidence: 0.044409167
Confidence: 0.044409167
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.054611664
Confidence: 0.081972085
Confidence: 0.081972085
Confidence: 0.081972085
Confidence: 0.081972085
Confidence: 0.1537778
Confidence: 0.1537778
Confidence: 0.1537778
Confidence: 0.22246778
Confidence: 0.23916133
Confidence: 0.25238588
Confidence: 0.25238588
Confidence: 0.25238588
Confidence: 0.44560355
Confidence: 0.44560355
Confidence: 0.44560355
Confidence: 0.5711696
بعد التعامل مع حالات فردية من الهجمات ، سنقوم بجمع الإحصاءات باستخدام بنية الشبكات العصبية التلافيفية ResNet ، من خلال كل نموذج ، وتغيير 1 أو 3 أو 5 بكسل لكل صورة. في هذه المقالة ، نعرض الاستنتاجات النهائية دون إزعاج القارئ للتعرف على كل تكرار ، حيث يستغرق الأمر الكثير من الوقت والموارد الحاسوبية.def attack_all(models, samples=500, pixels=(1,3,5), targeted=False,
maxiter=75, popsize=400, verbose=False):
results = []
for model in models:
model_results = []
valid_imgs = correct_imgs[correct_imgs.name == model.name].img
img_samples = np.random.choice(valid_imgs, samples, replace=False)
for pixel_count in pixels:
for i, img_id in enumerate(img_samples):
print('\n', model.name, '- image', img_id, '-', i+1, '/', len(img_samples))
targets = [None] if not targeted else range(10)
for target in targets:
if targeted:
print('Attacking with target', class_names[target])
if target == y_test[img, 0]:
continue
result = attack(img_id, model, target, pixel_count,
maxiter=maxiter, popsize=popsize,
verbose=verbose)
model_results.append(result)
results += model_results
helper.checkpoint(results, targeted)
return results
untargeted = attack_all(models, samples=100, targeted=False)
targeted = attack_all(models, samples=10, targeted=False)
لاختبار إمكانية تشويه سمعة الشبكة ، تم تطوير خوارزمية وتم قياس تأثيرها على الجودة المتوقعة لحل التعرف على الأنماط.دعنا نرى النتائج النهائية.untargeted, targeted = helper.load_results()
columns = ['model', 'pixels', 'image', 'true', 'predicted', 'success', 'cdiff', 'prior_probs', 'predicted_probs', 'perturbation']
untargeted_results = pd.DataFrame(untargeted, columns=columns)
targeted_results = pd.DataFrame(targeted, columns=columns)
يوضح الجدول أدناه أنه باستخدام الشبكة العصبية ResNet بدقة 0.9231 ، وتغيير عدة بكسل من الصورة ، حصلنا على نسبة جيدة جدًا من الصور التي تمت مهاجمتها بنجاح (attack_success_rate).helper.attack_stats(targeted_results, models, network_stats)
Out[26]:
model accuracy pixels attack_success_rate
0 resnet 0.9231 1 0.144444
1 resnet 0.9231 3 0.211111
2 resnet 0.9231 5 0.222222
helper.attack_stats(untargeted_results, models, network_stats)
Out[27]:
model accuracy pixels attack_success_rate
0 resnet 0.9231 1 0.34
1 resnet 0.9231 3 0.79
2 resnet 0.9231 5 0.79
في تجاربك ، أنت حر في استخدام بنى أخرى للشبكات العصبية الاصطناعية ، حيث يوجد حاليًا العديد منها.
لقد غطت الشبكات العصبية العالم الحديث بخيوط غير مرئية. لفترة طويلة ، تم اختراع الخدمات حيث ، باستخدام الذكاء الاصطناعي (AI) ، يتلقى المستخدمون صورًا تمت معالجتها تشبه أسلوبًا فنيًا لعمل الفنانين العظماء ، واليوم يمكن للخوارزميات نفسها رسم الصور وإنشاء روائع موسيقية وكتابة الكتب وحتى النصوص للأفلام.مجالات مثل رؤية الكمبيوتر ، والتعرف على الوجه ، والمركبات غير المأهولة ، وتشخيص الأمراض - اتخاذ قرارات مهمة ولا يحق لها ارتكاب الأخطاء ، والتدخل في تشغيل الخوارزميات سيؤدي إلى عواقب وخيمة.هجوم بكسل واحد هو طريقة واحدة لتزييف الهجمات. لاختبار إمكانية تشويه سمعة الشبكة ، تم تطوير خوارزمية وتم قياس تأثيرها على الجودة المتوقعة لحل التعرف على الأنماط. أظهرت النتائج أن بنيات الشبكات العصبية التلافيفية المستخدمة معرضة لخوارزمية هجوم بكسل واحد مدربة خصيصًا ، والتي تحل محل بكسل واحد ، لتشويه سمعة خوارزمية التعرف.وقد أعدته المادة الكسندر Andronic و Adrey شيرني-تكاتش كجزء من التدريب في Data4 .