تا اینجای کار، درباره ی الگوریتم linear regression صحبت کردیم، بعد اومدیم و خیلی ساده ای الگوریتم رو با numpy پیاده سازی کردیم. بعدش رفتیم سراغ vectorization و با این ایده آشنا شدیم، در نهایت هم یک مقدار درباره ی الگوریتم logistic regression صحبت کردیم.
تو این پست میخوایم بریم سراغ شبکه های عصبی :) چرا شبکه های عصبی؟ چون تو سال های اخیر خیلی از پیشرفته های ماشین لرنینگ و هوش مصنوعی با استفاده از شبکه های عصبی (و یا دقیق ترش شبکه های عصبی همین) به دست اومده.
قبلا شبکه های عصبی مشکلات زیادی داشتن، مثل اینکه نوشتن کدی که بتونه شبکه عصبی train کنه سخت بود، train کردن اونها خیییلی زمان بر بود، داده ی زیادی نیاز داشتن و خیلی مشکلات دیگه. اما الان با توجه به وجود کتابخونه هایی مثل tensorflow و pytorch، وجود دیتاست های بزرگ، داشتن GPU های قوی، سرویس های cloud که GPU دارن و داشتن روش هایی که با اونها میشه شبکه های خیلی عمیق رو train کرد، استفاده از این الگوریتم خیلی زیاد شده و روز به روز داره بیشتر و بیشتر از این الگوریتم استفاده میشه.
خب دیگه مقدمه چینی بسه، وقتشه که بریم سراغ خود شبکه های عصبی.
دلیل اصلی ای که پست های ماشین لرنینگ رو با linear regression و logistic regression شروع کردم این بود که شبکه های عصبی (البته در ساده ترین حالت ممکن)، در واقع یک سری logistic regression هستند که به هم چسبین. یعنی فرض کنید به جای اینکه مستقیما بیایم و ورودی رو بدیم به یک logistic regression، بیایم و اول اون رو بدیم به 4 تا logistic regression، بعد خروجی اون 4 تا رو بدیم به یک logistic regression دیگه. این میشه یه شبکه عصبی!
اگر یادتون باشه تو پست linear regression گفته بودم که میشه یه این صورت نشونشن داد:
میشه به همین صورت logistic regression رو هم نشون داد:
تنها تفاوتی که اینجا ایجاد شده اینه که اومدیم و خروجی رو دادیم به یک تابع sigmoid.
حالا اگر بخوایم بر اساس همون چیزی که گفتم (بیایم و ورودی رو اول بدیم به 4 تا logistic regression و بعد خروجی اونا رو بدیم به یک logistic regression دیگه) یک شبکه عصبی بسازیم، این شکلی میشه:
البته تو این شکل دیگه bias ها رو نشون ندادم (همون تتا 0) و برای sigmoid هم دایره ی جدا نکشیدم.
به هر کدوم از دایره هایی که توی این شکل هستند، میگیم نرون. و به هر تعداد نرون که توی این شکل زیر هم هستند میگیم یک لایه. به اولین لایه (همون 3 تا نقطه) میگیم لایه ی ورودی (input layer)، یه آخرین لایه هم میگم لایه ی خروجی (output layer). لایه های بین ورودی و خروجی هم لایه های مخفی (hidden layers) هستند.
تو شکلی که داریم، یک شبکه ی دو لایه داریم (لایه ورودی رو حساب نمیکنیم). برای ادامه ی کار نرون های هر لایه رو از بالا به پایین شماره گذاری میکنیم. نرون اول لایه ی اول رو در نظر بگیرید، 3 تا ورودی به این نرون میرسه، پس باید سه تا پارامتر داشته باشه. بقیه ی نرون های این لایه هم همین جوری هستند.
به نرون لایه ی آخر 4 تا ورودی میرسه پس باید 4 تا پارامتر داشته باشه.
نرون اول لایه ی اول رو در نظر بگیرید، به این نرون باید 3 تا ورودی برسه. چون قراره روی اونها logistic regression انجام بشه پس خروجی اون به این صورت محاسبه میشه: (ورودی های اون به ترتیب x1، x2 و x3 هستند)
برای اینکه مشخص کنیم که این پارامتر ها و خروجی مربوط به نرون اول هستند، برای پارامتر ها توان 1 میذاریم. (اون عدد رو با توان ریاضیاتی قاطی نکنید). پس معادله به این صورت درمیاد:
به این ترتیب خروجی نرون های این لایه اینجوری میشه:
میتونیم این معادله رو اینجوری بنویسیم:
و خود این معادله رو میتونیم اینجوری بنویسیم:
اگر به ماتریسی که توی اون تتا ها رو گذاشتیم بگیم تتا 1، میتونیم معادله ی این لایه رو به این صورت بنویسیم:
البته، باید بردار bias رو هم با این معادله جمع کنیم و بعد اون از خروجی اون sigmoid بگیریم. (برای استاندارد تر بودن، از این به بعد به برای وزن لایه ها به جای تتا از W و به جای output از A استفاده میکنیم) پس در نهایت، معادلات این لایه به این صورت میشه:
به همین ترتیب معادله ی لایه ی دوم هم به این صورت میشه:
پس معادلات شبکه عصبی ای که ساختیم این شکلی میشه:
اگر بیایم همین معادلات رو تو کد بنویسم، در واقع این شبکه عصبی رو با کد پیاده سازی کردیم. اما سوال اصلی اینه که چه جوری مقدار ماتریس های W1، W2 و بردار های b1 و b2 رو حساب کنیم؟
اینجا هم مثل قبل باید بیایم و از یک الگوریتمی مثل gradient descent استفاده کنیم. مشکلی که اینجا به وجود میاد اینه که باید هر لایه رو بر اساس مشتق لابع J نسبت به اون لایه حساب کنیم. برای محاسبه ی این مشتقات از یک الگوریتم به نام backpropagation استفاده میشه و بعد با استفاده از gradient descent وزن ها آپدیت میشن.
به این ترتیب ما میتونیم یک شبکه ی عصبی رو train کنیم!
تو پست بعدی میریم سراغ کد نویسی یک شبکه عصبی ساده.