آموزش یادگیری ماشین با مثالهای کاربردی ــ بخش هشتم
در بخشهای پیشین از مجموعه مطالب «آموزش یادگیری ماشین با مثالهای کاربردی»، مبانی و مفاهیم هوش مصنوعی و یادگیری ماشین، شبکههای عصبی، یادگیری عمیق، شبکههای عصبی پیچشی، بینایی ماشین و تشخیص چهره، ترجمه ماشینی، تشخیص صوت و بازشناسی گفتار، مدلهای زایشی و الگوریتم DCGAN مورد بررسی قرار گرفت. در این بخش به ترفند جالبی برای دور زدن شبکههای عصبی پرداخته میشود.
از زمانیکه برنامهنویسها اولین نرمافزارهای کامپیوتری را نوشتند تاکنون، هکرها بهدنبال راهکارهایی برای بهرهبرداری از این برنامهها بودند. هکرهای مخرب، از کوچکترین باگهای موجود در نرمافزارها برای نفوذ به سیستمها سو استفاده کرده و به سرقت دادهها و آسیبرسانی به کامپیوترها میپرداختند.
اما، سیستمهای قدرت گرفته از الگوریتمهای یادگیری عمیق باید از هرگونه مداخله انسانی در امان باشند. در چنین شرایطی، یک هکر چگونه میتواند به دادههای آموزش که شبکه عصبی با آن آموزش دیده دست پیدا کند؟
حقیقت این است که پیشرفتهترین شبکههای عصبی عمیق نیز به راحتی گمراه میشوند. با چند ترفند ساده، میتوان این شبکهها را وادار کرد پیشبینیهای خود را مطابق میل کاربر تغییر دهند.
بنابراین، پیش از راهاندازی یک سیستم جدید که از شبکه عصبی قدرت گرفته، باید شیوه نفوذ به آن و چگونگی محافظت از شبکه در مقابل مهاجمان را آموخت.
شبکههای عصبی به عنوان گاردهای امنیتی
یک وبسایت مزایده اینترنتی مشابه Ebay مفروض است. در این وبسایت یکی از اهداف، ممانعت از خرید و فروش کالاهای ممنوع - مانند حیوانات زنده - است. اجرای چنین قوانینی در صورت وجود میلیونها کاربر بسیار دشوار خواهد بود. میتوان هزاران نفر از افراد را استخدام کرد تا کلیه مزایدهها را به صورت دستی لیست و بررسی کنند، اما این کار بسیار پیچیده و پر هزینه خواهد بود. در عوض، میتوان از «یادگیری عمیق» (Deep Learning) برای بررسی تصاویر مزایدهها بهمنظور کشف و پرچمگذاری موارد ممنوعی که ناقض قوانین هستند بهره برد.
این رویکرد، یعنی چالش پیش رو یک مساله متداول طبقهبندی است. برای ساخت مدل بیان شده، یک شبکه عصبی پیچشی عمیق برای یافتن موارد ممنوعه از میان گزینههای مجاز مورد استفاده قرار خواهد گرفت. از اینرو، کلیه تصاویر سایت به عنوان ورودی الگوریتم به آن داده خواهند شد.
در این راستا، ابتدا نیاز به مجموعهای شامل هزاران تصویر از مزایدههای پیشین است. لازم به ذکر است که این مجموعه داده باید شامل موارد ممنوع و مجاز باشد. با استفاده از این مجموعه داده، شبکه آموزش داده میشود تا این موارد را از یکدیگر تمییز دهد.
برای آموزش دادن شبکه عصبی، از «الگوریتم بازگشت به عقب استاندارد» (standard back Backpropagation algorithm) استفاده میشود. این الگوریتمی است که موارد ممنوع و مجاز را به عنوان ورودی آموزش دریافت کرده و بر اساس آن برای تصاویر دیگر در خروجی پیشبینی ارائه میدهد. در این الگوریتم، هر بار بازگشت به عقب در لایههای شبکه اتفاق میافتد که به بهبود خروجی کمک میکند.
این فرآیند را هزاران بار با هزاران تصویر تکرار کرده تا مدل به شکل قابل اعتمادی نتایج صحیح با صحت قابل قبول تولید کند. نتیجه نهایی یک شبکه عصبی است که میتواند به شکل قابل اعتمادی تصاویر را طبقهبندی کند.
تذکر: مطالعه بخش سوم از مجموعه مطالب «آموزش یادگیری ماشین با مثالهای کاربردی» به افرادی توصیه میشود که تمایل به مطالعه بیشتر درباره شبکههای پیچشی دارند.
هیچچیز آنطور که به نظر میرسد قابل اعتماد نیست
شبکههای عصبی پیچشی مدلهای قدرتمندی هستند که کل یک تصویر را هنگام طبقهبندی آن در نظر میگیرند. آنها میتوانند اشکال پیچیده و الگوها را بیتوجه به اینکه در کدام قسمت از تصویر وجود دارند تشخیص دهند. در بسیاری از وظایف تشخیص تصویر، مدل میتواند از کارایی انسان پیشی بگیرد.
در یک مدل «یادگیری ماشین» (Machine Learning)، تغییر چند پیکسل و روشنتر یا تیرهتر کردن آن در تصویر نباید تفاوت قابل توجهی در پیشبینی نهایی ایجاد کند. این امر ممکن است درستنمایی نهایی را سر انجام دستخوش تغییر کند، اما نباید تصویر را به جای «ممنوع» به اشتباه «مجاز» تشخیص دهد و بالعکس.
در مقاله بسیار معروف منتشر شده در سال ۲۰۱۳ با عنوان «ویژگیهای جالب شبکههای عصبی»، اذعان شد که این مساله همیشه هم درست نیست. اگر کاربر بداند که کدام پیکسل و به چه میزان تغییر داشته باشد، ممکن است شبکه را تعمدا وادار به ارائه خروجیهای غلط برای یک تصویر بر اساس میل و خواست خود کند.
چرا چنین است؟ یک دستهبند یادگیری ماشین با پیدا کردن خط جدا کننده برای دادههایی از گروههای (دستهها) گوناگون کار و بدین شکل دادهها را دستهبندی میکند. در ادامه، نمودار یک دستهبند دوبُعدی که آموخته تا نقاط - داده - سبز (مجاز) را از موارد قرمز رنگ (ممنوع) جدا کند آورده شده.
در حال حاضر دستهبند با صحت ۱۰۰٪ کار میکند. این دستهبند، به خوبی کلیه نقاط سبز را از قرمز جدا میسازد. اما اگر از ترفندی برای طبقهبندی غلط یکی از نقاط قرمز در دسته سبزها استفاده شود چه؟ مقدار کمینهای که میتوان یک نقطه قرمز را با حرکت دادن وارد ناحیه سبز کرد چیست؟ اگر مقدارِ اندکی به Y نقطه قرمزی که درست کنار مرز است اضافه شود، میتوان به راحتی آن را در دسته سبزها قرار داد. اگر هدف خرابکاری به صورت ناشناس باشد، ایدهآلترین حالت آن است که این مقدار تا حد امکان کوچک باشد تا به نظر یک مقدار منطقی برسد.
در طبقهبندی تصاویر با شبکههای عصبی عمیق، هر «نقطهای» که دستهبندی میشود یک تصویر کلی ساخته شده از هزاران پیکسل است. این امر هزاران مقدار ممکنی که میتوان برای پیچش به منظور بهبود تصمیمسازی استفاده کرد را فراهم میکند. اگر اطمینان حاصل شود که پیکسلها در تصویر بهگونهای پیچیده شدهاند که برای انسان مشهود نیست، میتوان با استفاده از آنها به دستهبند - بدون آنکه تصویر دستکاری شده به نظر برسد - حقه زد.
به عبارت دیگر، میتوان یک تصویر واقعی از یک شی را دریافت و پیکسلها را به شیوه بسیار ملایمی تغییر داد و با این ترفند کاری کرد که شبکه به اشتباه تصویر را متعلق به چیزی غیر از آنچه هست تشخیص دهد. این در حالیست که حتی میتوان آنچه تصویر به عنوان آن پیشبینی میشود را بهطور دقیق کنترل کرد.
چطور میتوان به یک شبکه عصبی حقه زد؟
پیش از این درباره فرآیند پایهای آموزش یک شبکه عصبی برای طبقهبندی تصاویر صحبت شد:
- خوراندن تصاویر آموزش به شبکه
- بررسی پیشبینیهای شبکه عصبی و مشاهده فاصله خروجیها با نتایج صحیح
- پیچاندن وزنهای هر لایه در شبکه عصبی با استفاده از الگوریتم بازگشت به عقب برای آنکه پیشبینیهای نهایی اندکی به پاسخ صحیح نزدیکتر شوند.
- تکرار گامهای اول تا سوم برای هزاران بار با چندین هزار تصویر آموزش متفاوت
اگر به جای پیچش وزنهای لایههای شبکه عصبی، تصاویر برای گرفتن پاسخ مورد نظر پیچش داده شوند چه اتفاق خواهد افتاد؟ برای پاسخگویی به این پرسش، شبکه عصبی از پیش آموزش دیده، مجددا آموزش داده میشود. از الگوریتم بازگشت به عقب برای تنظیم تصاویر ورودی به جای لایههای شبکه استفاده خواهد شد.
بنابراین، در ادامه یک الگوریتم جدید وجود دارد:
- خوراندن تصاویری که قصد هک کردن آنها وجود دارد
- بررسی پیشبینی شبکه عصبی و مشاهده فاصله پاسخ مورد نظر با پیشبینی برای آن تصویر
- پیچاندن تصاویر با استفاده از الگوریتم بازگشت به عقب برای آنکه پیشبینی نهایی اندکی به پاسخ مورد نظر نزدیکتر شود.
- تکرار گامهای یک تا سه برای هزاران بار با تصویر مشابه، تا هنگامی که شبکه پاسخ مورد نظر را ارائه کند.
در پایان این امر، تصویری وجود دارد که میتواند به شبکه عصبی (بدون آنکه تغییری در شبکه به وقوع بپیوندد) حقه بزند. تنها مساله موجود این است که اگر هر پیکسل بدون هیچگونه محدودیتی تغییر کند، اصلاحات تصاویر ممکن است به اندازهای شدید باشند که به سادگی توسط کاربر قابل مشاهده شوند.
برای پیشگیری از این اعوجاج شدید، میتوان محدودیتهای سادهای به الگوریتم افزود. در این راستا، به الگوریتم گفته میشود که هر پیکسل نمیتواند در تصویر هک شده، نسبت به مقدار موجود در تصویر اصلی تغییر قابل توجهی کند. میتوان گفت این مقدار چیزی حدود ۰.۰۱٪ است. این کار الگوریتم را به پیچاندن تصاویر به صورتی وا میدارد که همچنان شبکه عصبی را گول زده و در عین حال تفاوت زیادی نسبت به تصویر اصلی ایجاد نکند. در زیر، تصویر تولیدی در شرایطی که میزان تغییر پیکسلها محدود شده قابل مشاهده است.
اگرچه این تصاویر برای مخاطب مشابه بهنظر میرسند، اما میتوانند شبکه عصبی را به سادگی گول بزنند.
وقت کد زدن فرا رسیده!
برای پیادهسازی روش بیان شده با استفاده از زبان برنامهنویسی پایتون، نیاز به یک شبکه عصبی از پیش آموزش دیده است که با تصاویر اصلاح شده به آن حقه زده شود. در اینجا به جای ساخت یک شبکه عصبی آموزش دیده از پایه، از نسخه ساخته شده توسط گوگل استفاده میشود. «کِراس» (Keras)، چارچوب یادگیری عمیق معروفی است که چندین شبکه عصبی از پیش آموزش دیده را به همراه دارد.
در اینجا از یک کپی از شبکه عصبی عمیق Inception v3 گوگل که از پیش آموزش دیده استفاده شده. کد پایه Keras برای تشخیص اشیای موجود در تصویر با استفاده از شبکه عصبی در ادامه آمده است. کلیه افراد پیش از استفاده و اجرای این کد باید اطمینان حاصل کنند که پایتون ۳ و Keras روی سیستم آنها نصب شده.
1import numpy as np
2from keras.preprocessing import image
3from keras.applications import inception_v3
4
5# Load pre-trained image recognition model
6model = inception_v3.InceptionV3()
7
8# Load the image file and convert it to a numpy array
9img = image.load_img("cat.png", target_size=(299, 299))
10input_image = image.img_to_array(img)
11
12# Scale the image so all pixel intensities are between [-1, 1] as the model expects
13input_image /= 255.
14input_image -= 0.5
15input_image *= 2.
16
17# Add a 4th dimension for batch size (as Keras expects)
18input_image = np.expand_dims(input_image, axis=0)
19
20# Run the image through the neural network
21predictions = model.predict(input_image)
22
23# Convert the predictions into text and print them
24predicted_classes = inception_v3.decode_predictions(predictions, top=1)
25imagenet_id, name, confidence = predicted_classes[0][0]
26print("This is a {} with {:.4}% confidence!".format(name, confidence * 100))
هنگامی که کد بالا اجرا میشود، شبکه به درستی تصویر را گربه ایرانی (Persian cat) تشخیص میدهد.
$ python3 predict.py This is a Persian_cat with 85.7% confidence!
اکنون با پیچش تصویر به میزانی که شبکه حقه بخورد، به مدل ترفند زده میشود تا به اشتباه تصویر گربه را توستر پیشبینی کند. کد این حقه در ادامه آمده است. Keras راهکار توکاری برای آموزش دادن شبکه در مقابل تصاویر ورودی به جای آموزش شبکه عصبی ندارد، بنابراین کد این قسمت به صورت جدا زده میشود.
1import numpy as np
2from keras.preprocessing import image
3from keras.applications import inception_v3
4from keras import backend as K
5from PIL import Image
6
7# Load pre-trained image recognition model
8model = inception_v3.InceptionV3()
9
10# Grab a reference to the first and last layer of the neural net
11model_input_layer = model.layers[0].input
12model_output_layer = model.layers[-1].output
13
14# Choose an ImageNet object to fake
15# The list of classes is available here: https://gist.github.com/ageitgey/4e1342c10a71981d0b491e1b8227328b
16# Class #859 is "toaster"
17object_type_to_fake = 859
18
19# Load the image to hack
20img = image.load_img("cat.png", target_size=(299, 299))
21original_image = image.img_to_array(img)
22
23# Scale the image so all pixel intensities are between [-1, 1] as the model expects
24original_image /= 255.
25original_image -= 0.5
26original_image *= 2.
27
28# Add a 4th dimension for batch size (as Keras expects)
29original_image = np.expand_dims(original_image, axis=0)
30
31# Pre-calculate the maximum change we will allow to the image
32# We'll make sure our hacked image never goes past this so it doesn't look funny.
33# A larger number produces an image faster but risks more distortion.
34max_change_above = original_image + 0.01
35max_change_below = original_image - 0.01
36
37# Create a copy of the input image to hack on
38hacked_image = np.copy(original_image)
39
40# How much to update the hacked image in each iteration
41learning_rate = 0.1
42
43# Define the cost function.
44# Our 'cost' will be the likelihood out image is the target class according to the pre-trained model
45cost_function = model_output_layer[0, object_type_to_fake]
46
47# We'll ask Keras to calculate the gradient based on the input image and the currently predicted class
48# In this case, referring to "model_input_layer" will give us back image we are hacking.
49gradient_function = K.gradients(cost_function, model_input_layer)[0]
50
51# Create a Keras function that we can call to calculate the current cost and gradient
52grab_cost_and_gradients_from_model = K.function([model_input_layer, K.learning_phase()], [cost_function, gradient_function])
53
54cost = 0.0
55
56# In a loop, keep adjusting the hacked image slightly so that it tricks the model more and more
57# until it gets to at least 80% confidence
58while cost < 0.80:
59 # Check how close the image is to our target class and grab the gradients we
60 # can use to push it one more step in that direction.
61 # Note: It's really important to pass in '0' for the Keras learning mode here!
62 # Keras layers behave differently in prediction vs. train modes!
63 cost, gradients = grab_cost_and_gradients_from_model([hacked_image, 0])
64
65 # Move the hacked image one step further towards fooling the model
66 hacked_image += gradients * learning_rate
67
68 # Ensure that the image doesn't ever change too much to either look funny or to become an invalid image
69 hacked_image = np.clip(hacked_image, max_change_below, max_change_above)
70 hacked_image = np.clip(hacked_image, -1.0, 1.0)
71
72 print("Model's predicted likelihood that the image is a toaster: {:.8}%".format(cost * 100))
73
74# De-scale the image's pixels from [-1, 1] back to the [0, 255] range
75img = hacked_image[0]
76img /= 2.
77img += 0.5
78img *= 255.
79
80# Save the hacked image!
81im = Image.fromarray(img.astype(np.uint8))
82im.save("hacked-image.png")
با اجرای این کد، تصویری حاصل میشود که میتواند به شبکه عصبی حقه بزند.
1$ python3 generated_hacked_image.py
2Model's predicted likelihood that the image is a toaster: 0.00072%
3[ .... a few thousand lines of training .... ]
4Model's predicted likelihood that the image is a toaster: 99.4212%
تذکر: در صورت نداشتن GPU، اجرای این قطعه کد ممکن است ساعتها به طول بیانجامد. اگر GPU از پیش بهطور مناسبی با Keras و CUDA پیکربندی شود، انجام این کار بیش از چند دقیقه طول نمیکشد. اکنون، تصویر هک شده به مدل اصلی داده میشود تا خروجی آن مورد بررسی قرار بگیرد.
$ python3 predict.py This is a toaster with 98.09% confidence!
نتیجه داد! شبکه عصبی حقه خورد، بنابراین به اشتباه فکر میکند که گربه یک توستر است.
با تصویر هک شده چه کار میتوان کرد؟
به ساخت تصاویر هک شدهای مانند این، «تولید مثال رقابتی» گفته میشود. در این رویکرد، هدف ساخت دادههایی است که مدل آنها را اشتباه پیشبینی کند. این ترفند جالب، کاربردهای جهان واقعی نیز دارد.
در ادامه به برخی از این کاربردهای جالب توجه اشاره شده است.
- تصاویر هک شده میتوانند شبکه عصبی را گول بزنند حتی هنگامی که روی یک کاغذ پرینت شده باشند. بنابراین میتوان از این تصاویر هک شده نه تنها برای گول زدن سیستمهای آپلود تصویر بهطور مستقیم استفاده کرد، بلکه میتوان دوربینهای فیزیکی یا اسکنرها را به اشتباه انداخت.
- تصاویری که یک شبکه عصبی را گول زدند، گرایش به گول زدن دیگر شبکههای عصبی (دارای طراحی کاملا متفاوت) نیز در صورت آموزش دیدن با دادههای مشابه دارند.
بنابراین، کارهای زیادی است که میتوان با این تصاویر هک شده انجام داد. اما همچنان یک محدودیت بزرگ در چگونگی ساخت این تصاویر وجود دارد. حملات نیازمند دسترسی مستقیم به خود شبکه عصبی هستند. از آنجا که آموزش دادن بر علیه شبکه عصبی و برای حقه زدن به آن اتفاق میافتد، نیاز به یک کپی از شبکه وجود دارد. در جهان واقعی، هیچ شرکتی به افراد اجازه دانلود کدهای شبکههای عصبی آموزش دیده خود را نمیدهد. بنابراین آیا نمیتوان به آنها حمله کرد؟!
پژوهشگران اخیرا نشان دادهاند که فرد میتواند با آموزش دادن شبکه عصبی جایگزین و با پروب کردن شیوه دید شبکه ، شبکه عصبی دیگری را آینه کنند. سپس، میتوان از شبکه عصبی جایگزین برای تولید تصاویر هک شدهای استفاده کرد که بتوانند شبکه عصبی دیگر را گول بزنند. به این کار حمله جعبه سیاه (black-box attack) گفته میشود. کاربردهای حمله جعبه سیاه نامحدود است. در ادامه برخی مثالهای محتمل بیان شدهاند.
- حقه زدن به خودروهای خودران به منظور ندیدن چراغ سبز که میتواند منجر به وقوع تصادفات شود.
- حقه زدن به سیستمهای فیلترینگ محتوا برای دریافت اجازه نشر محتوای غیر قانونی یا توهینآمیز.
- حقه زدن به اسکنرهای بررسی ATM به منظور آنکه دستگاه مبلغ نوشته شده با دستخط روی چک را بیش از آنچه که هست در نظر بگیرد. (البته احتمال این وجود دارد که فرد پس از انجام این کار دستگیر شود!)
این روشهای حمله فقط به تصاویر محدود نشدهاند. بلکه، میتوان از رویکرد مشابهی برای گول زدن دستهبندهایی استفاده کرد که با دیگر انواع دادهها کار میکنند. برای مثال، میتوان به یک اسکنر ویروس جهت تشخیص برنامههای مخرب تحت عنوان امن حقه زد.
چگونه میتوان از خود در مقابل این حملات محافظت کرد؟
اکنون که احتمال آن وجود دارد که شبکه عصبی (و همچنین دیگر انواع مدلهای یادگیری ماشین) حقه بخورند، چگونه میتوان در مقابل این حملات دفاع کرد؟ کوتاهترین پاسخ این است که هنوز هیچ راهکار قطعی وجود ندارد. پیشگیری از چنین حملاتی همچنان یکی از موضوع مهم پژوهشی است.
برای همراه بودن با فناوریهای مربوط به این حوزه، دنبال کردن وبلاگ cleverhans توصیه میشود. این وبلاگ متعلق به «ایان گودفِلو» (Ian Goodfellow) و «نیکولاس پپرنات» (Nicolas Papernot) دو نفر از تاثیرگذارترین افراد در حوزه «یادگیری ماشین» (Machine Learning) است. نکاتی در رابطه با چگونگی پیشگیری از این حملات در ادامه ارائه شده.
- اگر تصاویر هک شده زیادی ساخته و در مجموعه داده آموزش استفاده شوند، شبکه عصبی به چنین حملاتی مقاومتر میشود. به این کار آموزش رقابتی گفته میشود و احتمالا در حال حاضر معقولانهترین دفاع قابل پذیرش است.
- یک رویکرد موثر دیگر، روشی است که «Defensive Distillation» نامیده میشود. در این روش، تلاش میشود که یک مدل دوم برای تقلید کردن از مدل اصلی ساخته شود. اما این رویکرد همچنان جدید است و به اندازه کافی کامل محسوب نمیشود. بنابراین سرمایهگذاری در این روش جز در شرایطی که نیازهای خاصی وجود داشته باشد توصیه نمیشود.
- با وجود تلاشهای مکرری که پژوهشگران برای پیشگیری از اینگونه حملات انجام دادهاند، اغلب روشهای بیان شده در پیشگیری از این حملات ناکارآمد هستند.
از آنجا که هیچ پاسخ نهایی و قطعی برای پرسش مطرح شده در بالا وجود ندارد، یک سناریو مناسب این است که در صورت استفاده از شبکه عصبی این مساله همواره در نظر گرفته شود که خطر وقوع چنین حملاتی یک مدل را تهدید میکند.
به بیان دیگر، مدلهای یادگیری ماشین (Machine Learning) موجود پتانسیل دور زده شدن را دارند. لذا باید به شرایطی که مدل تعمدا توسط اشخاصی دور زده شود و راههای غلبه بر آن اندیشید.
اگر نوشته بالا برای شما مفید بوده، آموزشهای زیر نیز به شما پیشنهاد میشود:
- مجموعه آموزشهای شبکه های عصبی مصنوعی در متلب
- بررسی شبکه عصبی کانولوشن (CNN)
- آموزش یادگیری عمیق (Deep learning)
- گنجینه آموزشهای یادگیری ماشین و دادهکاوی
^^