Artificial Neural Network - قسمت اول

سلام. من امیر داعی هستم و با قسمت پنجم از مجموعه هوش مصنوعی برای همه در خدمتتونم.از این قسمت کم کم وارد بحث اصلیمون میشیم. شبکه های عصبی مصنوعی یا به اختصار ANN، در کلاسیک ترین مفهوم یکی از متد های supervised learning هستن؛ البته در کاربرد های پیشرفته تر برای مدلسازی و حل مسائل پیشرفته تری (مثل یادگیری تقویتی و مدل های generative) هم استفاده میشن که در آینده بهشون میپردازیم.همونجور که در قسمت های قبلی گفتم، مسائل supervised learning مسائلی هستن که ما برای هر data point یک label یا target value هم داریم و با دادن این data point ها به مدل و مقایسه خطای خروجی با مقداری که توقع داریم، مدل رو بهینه سازی میکنیم تا با کمترین خطا بتونه خروجی مدنظر ما رو بده. در حال حاضر قوی ترین متد supervised learning مخصوصا برای مسائلی با حجم زیاد دیتا و پیچیده با روابط غیرخطی میان متغیر ها ANN است که در بازدهی و قابلیت generalization با قاطعیت بقیه متد ها رو شکست داده.همچنین یه سری معماری خاص ANN هم طراحی شده که به طور ویژه برای داده هایی که محلیت مختصاتی (positional locality) مثل عکس یا محلیت زمانی مثل سری های زمانی دارن استفاده میشن و بازدهی خارق العاده ای روی این نوع مسائل دارن. همچین انعطاف پذیریی در متد های کلاسیک ML بسیار کم بوده و بازدهی کمی داشتند.البته متاسفانه هیچ چیز تو دنیا ایده آل مطلق نیست و ANN هم مشکلاتی داره:

  • سختی آموزش دادن شبکه های عصبی: آموزش دادن شبکه های عصبی و بهینه سازی اون ها کار نسبتا سختی هست. مخصوصا متد های آموزش معمولی که برای این کار استفاده میشن با معضلی با عنوان vanishing gradient روبرو هستن که پروسه یادگیری رو خیلی زمان بر و کم بازده میکنه (مخصوصا با افزایش ظرفیت ANN). البته با متد های جدیدی که معرفی شده اند (هم تو معماری ANN و هم تو پروسه بهینه سازی) تا حد خوبی این مشکل قابل رفع است.
  • ذات black-box: اینکه یه شبکه عصبی چجوری به یه نتیجه خاص میرسه یا یه ورودی رو در یک طبقه خاص قرار میده و ... فهمیدنش خیلی ممکن نیست. در واقع نمیتونیم بفهمیم چجوری کار میکنه، فقط میفهمیم کار میکنه و این میتونه تو بعضی شرایط معضل بزرگی باشه. البته تو بعضی از کاربرد های خاص، متد هایی ابداع شدن که تا حدی نشون میدن ANN بر اساس کدوم بخش از اطلاعات ورودی به نتیجه خاصی رسیده ولی هنوز غالبا مجبوریم به صورت black-box باهاشون برخورد کنیم.


حالا شبکه های عصبی چجوری کار میکنن و چجوری اینقد خوبن؟

شبکه عصبی از لایه هایی از نورون تشکیل شده که هر نورون توی لایه، بوسیله سیناپس به نورون های لایه بعد وصل میشه. در شکل زیر هر دایره یک نورون و هر خط یک سیناپس است:

نمونه ای از شبکه های عصبی مصنوعی
نمونه ای از شبکه های عصبی مصنوعی

لایه های ANN به سه بخش hidden ,input و output تقسیم میشن. در نورون های لایه input ،مقادیر کمی feature های data-point ورودی قرار میگیره. برای مثال در مسئله ای فرضی مانند طبقه بندی گل بر اساس طول و عرض گلبرگ و تعداد گلبرگ، برای گرفتن خروجی از هر ورودی، در نورون اول لایه ورودی مقدار عددی طول و در نورون دوم مقدار عددی عرض گلبرگ و در نورون سوم تعداد گلبرگ ها قرار میگیره. پس تعداد نورون های لایه input برابر تعداد feature های data-point ها است. مقدار هر نورون به وسیله سیناپس به نورون های لایه بعد که لایه hidden است میرن و به هر سیناپس مقدار ثابتی به عنوان وزن اختصاص داده شده. مقدار هر نورون لایه ورودی در این وزن ضرب شده و به عنوان مقدار سیناپس به نورون لایه بعد منتقل میشه. مثل در تصویر بالا بین لایه input و لایه hidden اول، ۱۲ سیناپس وجود داره که هر سیناپس وزن مختص خودش رو داره.

لایه های hidden، جایی هست که پردازش اصلی روی دیتا ورودی صورت میگیره و ورودی های مدل با یک تابع غیرخطی پیچیده از فضای ورودی به فضای خروجی میرن ( y=f(x)) و در اصطلاح کلاسیک (مخصوصا در مدل های قدیمی SVM) به اون kernel میگن. این لایه ها به هر تعداد میتونن باشن و وقتی بیشتر از تقریبا ۳ لایه باشن به این مدل، مدل یادگیری عمیق (Deep Learning) یا شبکه عصبی عمیق (Deep Neural Network) میگن. همچنین تعداد نورون های هر لایه هم دلخواهه ولی طبق تجربه من اکثرا (نه همیشه) بیشتر از ۱.۵ برابر تعداد نورون های input هستن. با افزایش تعداد لایه ها یا تعداد نورون های هر لایه hidden، ظرفیت مدل ما بیشتر میشه و میتونه مسائل پیچیده تری رو مدل کنه ولی ممکنه موجب بیشتر شدن ریسک over-fit بشه. فهمیدن اینکه چه تعداد لایه و نورون برای یه مسئله مناسبه روش معین و مشخصی نداره و بیشتر به وسیله آزمایش و خطا برای هر مسئله به دست میاد. در نورون های لایه hidden،‌ مقادیر سیناپس های ورودی به هر نورون با هم جمع میشن و به عنوان ورودی وارد یک تابع غیرخطی (تابع فعالسازی یا activation function) از پیش تعیین شده میشن و مقدار خروجی این تابع رو به عنوان مقدار فعالیت نورون در نظر میگیریم. لیستی از توابع معمول و کاربرد هاشونو در شکل زیر میبینید:

امروزه در لایه hidden اکثرا از ReLU یا زیرمجموعه های اون به عنوان activation function استفاده میشه (دلیلشو بعدا بیشتر توضیح میدم ولی به صورت خلاصه آموزش شبکه عصبی رو آسون تر میکنن). حالا مقدار فعالیت هر نورون دوباره به وسیله سیناپس های وزن دار در یک مقدار ثابت که همون وزن است ضرب میشه و به لایه بعد منتقل میشه و این پروسه تا لایه output ادامه داره.

در لایه output هم مقدار فعالیت نورون مثل لایه های hidden محاسبه میشه و مقدار فعالیت هر نورون لایه output در حقیقت میشه خروجی ما. در بخش قبل به دو نوع اصلی از مسائل supervised learning اشاره کردیم:

  • مسائل regression: در این نوع مسائل توقع یک مقدار عددی به عنوان خروجی داریم و در لایه output صرفا یک نورون داریم و تابع فعال سازی اون رو هم Linear قرار میدیم.
  • مسائل classification: ابعاد فضای خروجی مسائل classification برابر تعداد کلاس های اون مسئله اس و مجموع مقادیر اون هم همیشه ۱ است. مقدار هر بعد خروجی احتمال قرار گرفتن ورودی در اون دسته رو نسبت به بقیه دسته ها نشون میده. مثلا یک سیستم که میتونه تصاویر اسب و گربه و شتر رو دسته بندی کنه در خروجی ۳ نورون (بعد) داره که مجموع مقدار فعالیت اون ها به ۱ میرسه و به ازای هر ورودی، بعدی که بیشترین مقدار رو داره، class پیشبینی شده توسط سیستم است. برای مثال ممکنه خروجی این سیستم برای ابعاد اسب و گربه و شتر به ترتیب ۰.۲ - ۰.۷ - ۰.۱ باشه. در اینصورت سیستم تصویر ورودی رو به عنوان گربه تشخیص داده اون هم به احتمال ۷۰درصد. در مسائل classification تعداد نورون های لایه output برابر تعداد کلاس های اون مسئله و تابع فعالسازی sigmoid یا softmax هستند (تفاوت کاربردشونو بعدا میگم)

حالا با همچین پروسه ای چجوری واقعا میشه مسائل خیلی پیچیده مدل بشن؟ این برمیگرده به قضیه ای به عنوان universal approximation theorem که باز کردنش کاملا از حوصله این بحث و البته حوصله خودم و شما خارجه و کسی که علاقه داره میتونه تو وب درموردش بیشتر سرچ کنه. به راه دیگه اش هم اینه یه کاغذ خودکار بردارید و یه شبکه عصبی خیلی کوچیک مثلا با ۴ نورون input و دولایه hidden با ۶ نورون رسم کنید و خروجی اون رو برای متغیر های پارامتری a-d به عنوان مقادیر نورون های ورودی با وزن ۱ برای تمام سیناپس ها حساب کنید و ببینید به چه تابع عجیب غریبی در خروجی میرسید یا به عبارتی این شبکه عصبی کوچیک چه تابع پیچیده ای رو میتونه مدلسازی کنه?? (کسی این کار رو کرد برای من بفرسته تا با اسم خودش برای بقیه هم منتشر کنم).

در توضیحات بالا همه چیز معلوم هستن به جز ... wait for it ... وزن های سیناپس ها ✨?✨. در واقع انتخاب مقادیر صحیح برای وزن هر سیناپس همون پروسه آموزش دادنه و البته کار سختیه، مثلا تو عکس اول توی همین مقاله یک شبکه عصبی خیلی کوچیک میبینید ولی حدود ۳۲ سیناپس داره و باید ۳۲ عدد رو که شدیدا به هم وابسته هستن رو جوری تنظیم کنیم که مدل ما برای تعداد زیادی data-point کمترین مقدار خطا رو در خروجی بده یا به عبارت دیگه مسئله بهینه سازی با ۳۲ متغیر رو حل کنیم. به متدی که در اکثر قریب به اتفاق موارد برای این بهینه استفاده میشه، Stochastic Gradient Descent یا به اختصار SGD گفته میشه. جزییات پروسه آموزش و SGD بمونه برای هفته آینده...

برای نوشتن بخش بعدی نیاز دارم بدونم این مطلب چقدر برای مخاطبان قابل فهم بوده و چه جاهایی گنگ بوده. خوشحال میشم به من فیدبک بدید (اعم از خوب و بد). آی دی تلگرام: @amir_daaee

منتظر مطالب بعدی من باشید...


قسمت پیشین: Supervised Learning - قسمت دوم

قسمت بعدی: Artificial Neural Network - قسمت دوم