معاينة مختبر آمنة
Adversarial Cat_TF
هذي معاينة منقّحة للقراءة فقط؛ ما فيه أي شيء يشتغل داخل الصفحة.
قراءة فقط
معاينة الدفتر
Adversarial Cat_TF
> **ملاحظة بيئة التشغيل المدمجة:** هالمعاينة تستخدم عيّنة صغيرة وثابتة وآمنة من ناحية الحقوق عشان تكون النتايج قابلة للتكرار. النتايج بالحجم الكامل تحتاج مجموعة البيانات أو النموذج الموثّق بالدرس داخل بيئة خارجية معتمدة.
## كيف تشوف الشبكة العصبية القط؟
الشبكة العصبية المدرّبة مسبقًا على ImageNet تقدر تتعرف على 1000 فئة مختلفة من الأجسام، ومنها سلالات قطط كثيرة. وبيكون ممتع نشوف كيف يبدو **القط السيامي المثالي** من منظور شبكة عصبية.
> أكيد تقدرون تستبدلون *القط السيامي* بأي فئة ثانية في ImageNet.
بالبداية، خلونا نحمّل شبكة VGG:
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import numpy as np
from IPython.display import clear_output
from PIL import Image
import json
np.set_printoptions(precision=3,suppress=True)
model = keras.applications.VGG16(weights=None, include_top=True)
classes = [f"fixture-class-{index}" for index in range(1000)]## تحسين الصورة للنتيجة المطلوبة
عشان نتصوّر القط المثالي، بنبدأ بصورة تشويش عشوائي ونستخدم تحسين الانحدار المتدرج عشان نعدّلها لين تتعرف عليها الشبكة على إنها قط.
> **وصف الشكل:** دورة التحسين
وهذي صورة البداية:
x = tf.Variable(tf.random.normal((1,224,224,3)))
def normalize(img):
return (img-tf.reduce_min(img))/(tf.reduce_max(img)-tf.reduce_min(img))
plt.imshow(normalize(x[0]))> نستخدم دالة `normalize` عشان نخلي القيم ضمن نطاق 0-1.
إذا مرّرنا هالصورة إلى شبكة VGG، بنحصل على توزيع احتمالات شبه عشوائي:
def plot_result(x):
res = model(x)[0]
cls = tf.argmax(res)
print(f"Predicted class: {cls} ({classes[int(cls)]})")
print(f"Probability of predicted class = {res[cls]}")
fig,ax = plt.subplots(1,2,figsize=(15,2.5),gridspec_kw = { "width_ratios" : [1,5]} )
ax[0].imshow(normalize(x[0]))
ax[0].axis('off')
ax[1].bar(range(1000),res,width=3)
plt.show()
plot_result(x)> مع إن احتمال إحدى الفئات قد يبان أعلى بكثير من البقية، فهو للحين منخفض جدًا؛ شوفوا المقياس وبتلقون الاحتمال الفعلي حول 5% بس.
الحين خلونا نختار فئة مستهدفة، مثل **القط السيامي**، ونبدأ نعدّل الصورة بالانحدار المتدرج. إذا كانت $x$ صورة الإدخال وكانت $V$ شبكة VGG، بنحسب دالة الخسارة $\mathcal{L} = \mathcal{L}(c,V(x))$، بحيث $c$ هي الفئة المستهدفة، ثم نعدّل $x$ بالصيغة هذي:
$$
x^{(i+1)} = x^{(i)} - \eta{\partial \mathcal{L}\over\partial x}
$$
بنستخدم خسارة الانتروبيا المتقاطعة لأننا نقارن توزيعين احتماليين. وبما إن الفئة عندنا ممثّلة برقم، مب بمتجه ترميز one-hot، بنستخدم *خسارة الانتروبيا المتقاطعة الفئوية المتناثرة (Sparse Categorical Cross-Entropy)*.
بنكرر العملية عدة حقب، ونطبع الصورة وإحنا نتقدم.
> الأفضل تشغّلون هالكود على جهاز فيه GPU، أو تقلّلون عدد الحقب عشان ما يطول الانتظار.
target = [284] # Siamese cat
def cross_entropy_loss(target,res):
return tf.reduce_mean(keras.losses.sparse_categorical_crossentropy(tf.convert_to_tensor(target, dtype=tf.int32), res))
def optimize(x,target,epochs=10,show_every=None,loss_fn=cross_entropy_loss, eta=1.0):
if show_every is None:
show_every = epochs // 10
for i in range(epochs):
with tf.GradientTape() as t:
res = model(x)
loss = loss_fn(target,res)
grads = t.gradient(loss,x)
x.assign_sub(eta*grads)
if i%show_every == 0:
clear_output(wait=True)
print(f"Epoch: {i}, loss: {loss}")
plt.imshow(normalize(x[0]))
plt.show()
optimize(x,target)plot_result(x)الحين طلعنا بصورة تشوفها الشبكة العصبية قطًا، مع إنها للحين تبان لنا تشويشًا. لو واصلنا التحسين شوي، غالبًا بنحصل على **صورة قط مثالي مشوّشة** باحتمال قريب من 1.
## نفهم التشويش
هالتشويش ما له معنى واضح لنا، لكنه غالبًا يحتوي على أنماط كثيرة ترصدها المرشّحات منخفضة المستوى والمعتادة في صور القطط. وبما إن فيه طرق كثيرة جدًا لتحسين الإدخال والوصول للنتيجة المثالية، ما عند خوارزمية التحسين دافع تختار أنماطًا مفهومة بصريًا.
عشان تصير الصورة أقل تشويشًا، نقدر نضيف حدًا إلى دالة الخسارة اسمه **خسارة التغاير الكلي (Total Variation Loss)**. يقيس هالحد مدى تشابه وحدات البكسل المتجاورة. إذا أضفناه إلى *دالة الخسارة*، نجبر المحسّن يدور حلولًا تشويشها أقل وتفاصيلها أوضح.
> عمليًا، نحتاج نوازن بين خسارة الانتروبيا المتقاطعة وخسارة التغاير عشان نطلع بنتائج زينة. أضفنا في دالتنا معاملات رقمية؛ جرّبوا تغيّرونها وراقبوا كيف تتغيّر الصورة.
def total_loss(target,res):
return 10*tf.reduce_mean(keras.losses.sparse_categorical_crossentropy(tf.convert_to_tensor(target, dtype=tf.int32), res)) + \
0.005*tf.image.total_variation(x)
optimize(x,target,loss_fn=total_loss)هذي صورة القط المثالية لشبكتنا العصبية. نقدر نشوف فيها سمات مألوفة مثل العيون والأذنين، وهي متكررة بكثرة لدرجة تخلي الشبكة العصبية أوثق إن الصورة لقط.
plot_result(x)خلونا نشوف بعد كيف يبدو جسم ثاني لشبكة VGG:
x = tf.Variable(tf.random.normal((1,224,224,3)))
optimize(x,[340],loss_fn=total_loss) # zebra# Generated image fixture replaces the excluded third-party photograph.
yy, xx = np.mgrid[:224, :224]
img = np.stack((
(xx * 3 + 40) % 256,
(yy * 2 + 80) % 256,
((xx + yy) * 2 + 20) % 256,
), axis=-1).astype(np.uint8)
plt.imshow(img)واضح إن الشبكة تتعرف على هالصورة على إنها كلب:
plot_result(np.expand_dims(img,axis=0))الحين بنستخدم هالصورة كنقطة بداية، ونحاول نحسّنها لين تصير قطًا:
x = tf.Variable(np.expand_dims(img,axis=0).astype(np.float32)/255.0)
optimize(x,target,epochs=10)plot_result(x)يعني الصورة اللي فوق قط مثالي من وجهة نظر شبكة VGG!
## التجربة مع ResNet
الحين خلونا نشوف كيف يصنّف نموذج مختلف، مثل ResNet، الصورة نفسها:
model = keras.applications.ResNet50(weights=None, include_top=True)> بما إننا استخدمنا `model` متغيرًا عامًا، من الحين كل الدوال بتستخدم ResNet بدل VGG
plot_result(x)واضح إن النتيجة مختلفة مرة، وهذا متوقع. يوم حسّنا الصورة عشان تصير قطًا أخذنا بالحسبان طبيعة شبكة VGG ومرشّحاتها منخفضة المستوى. وبما إن مرشّحات ResNet مختلفة، فهي تعطي نتيجة مختلفة. هالشي يعطينا فكرة عن طريقة نحمي فيها أنفسنا من الهجمات الخصومية: نستخدم تجميعة من نماذج مختلفة.
خلونا نشوف كيف يبدو الحمار الوحشي المثالي لشبكة ResNet:
x = tf.Variable(tf.random.normal((1,224,224,3)))
optimize(x,target=[340],epochs=10,loss_fn=total_loss)plot_result(x)هالصورة مختلفة مرة، وهذا يدل إن بنية الشبكة العصبية غالبًا لها دور مهم في طريقة تعرّفها على الأجسام.
> **المهمة**: جرّبوا تنفّذون هجومًا خصوميًا على ResNet، وقارنوا النتائج.
## استخدام محسّنات مختلفة
استخدمنا في مثالنا أبسط تقنية تحسين، وهي الانحدار المتدرج. لكن Keras يوفّر [محسّنات](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers) مدمجة مختلفة نقدر نستخدمها بدل الانحدار المتدرج. التعديل المطلوب على الكود بسيط جدًا: نستبدل الجزء اللي يعدّل صورة الإدخال `x.assign_sub(eta*grads)` باستدعاء دالة المحسّن `apply_gradients`:
def optimize(x,target,epochs=10,show_every=None,loss_fn=cross_entropy_loss,optimizer=keras.optimizers.SGD(learning_rate=1.0)):
if show_every is None:
show_every = epochs // 10
for i in range(epochs):
with tf.GradientTape() as t:
res = model(x)
loss = loss_fn(target,res)
grads = t.gradient(loss,x)
optimizer.apply_gradients([(grads,x)])
if i%show_every == 0:
clear_output(wait=True)
print(f"Epoch: {i}, loss: {loss}")
plt.imshow(normalize(x[0]))
plt.show()
x = tf.Variable(tf.random.normal((1,224,224,3)))
optimize(x,[898],loss_fn=total_loss) # water bottle## الخلاصة
قدرنا نتصوّر صورة القط المثالية، وأي جسم ثاني، داخل شبكة عصبية التفافية (CNN) مدرّبة مسبقًا. استخدمنا تحسين الانحدار المتدرج عشان نعدّل صورة الإدخال بدل الأوزان. والحيلة الأساسية عشان تطلع الصورة مفهومة كانت إضافة خسارة التغاير إلى دالة الخسارة، لأنها تجبر الصورة تصير أنعم.
حذفنا المخرجات وعدّادات التشغيل والودجات والمحتوى النشط وقت الاستيراد. شغّل الدفاتر بس في بيئة خارجية تثق فيها.
سجّل تطبيقك
التسجيل اختياري، يفيدك تتذكر وش طبّقت، ولا يمنع إكمال الدورة.