مقاله پیش رو یک مرور کلی بر یادگیری عمیق و نحوه کار شبکههای عصبی مصنوعی ارائه خواهد داد. آنچه مطالعه خواهید کرد مفاهیم کلیدی مانند ساختار نورونهای مصنوعی، جریان اطلاعات در لایههای شبکه عصبی، توابع فعال سازی مختلف، انتشار رو به جلو و رو به عقب، و روشهای بهینه سازی مانند گرادیان نزولی را پوشش خواهد داد.
اما یادگیری عمیق چیست؟
یادگیری عمیق، در واقع یادگیری از طریق مثالهاست. و این خلاصه تمام ماجراست.
در سطح بسیار پایه، یادگیری عمیق یک تکنیک یادگیری ماشین «Machine Learning» است. این تکنیک به کامپیوتر میآموزد که ورودیها را با استفاده از لایهها فیلتر کند تا چگونگی پیشبینی و طبقهبندی اطلاعات را یاد بگیرد. مشاهدات میتوانند به شکل تصویر، متن یا صدا وجود داشته باشند.
الهامبخش یادگیری عمیق، نحوه فیلتر کردن اطلاعات توسط مغز انسان است. هدف، تقلید از عملکرد مغز انسان برای ایجاد نتایج شگفتانگیز است. به طور دقیقتر، یادگیری عمیق یک شبکه عصبی مصنوعی «Artificial Neural Network» است.
به بیان ساده تر مغز انسان به عنوان الهامبخش و الگویی برای طراحی شبکههای عصبی مصنوعی در یادگیری عمیق استفاده میشود. مقصد این است که با تقلید از نحوه پردازش اطلاعات توسط مغز انسان، بتوان به نتایج قابل توجهی در زمینههای مختلف دست یافت. در واقع، شبکههای عصبی مصنوعی ساختار و عملکرد مغز انسان را شبیهسازی میکنند تا بتوانند وظایف پیچیده را انجام دهند.
در مغز انسان، حدود ۱۰۰ میلیارد نورون وجود دارد. هر نورون با حدود ۱۰۰٬۰۰۰ همسایه خود ارتباط برقرار میکند. محققین در حال بازآفرینی این ساختار هستند، اما به شیوه و سطحی که برای ماشینها کاربردی باشد. در مغز ما، یک نورون دارای یک جسم سلولی، دندریتها و یک آکسون است. سیگنال از یک نورون از طریق آکسون حرکت کرده و به دندریتهای نورون بعدی منتقل میشود. این اتصال که سیگنال از آن عبور میکند، سیناپس «Synapse» نامیده میشود.
نورونها به تنهایی تقریباً بیفایدهاند. اما وقتی تعداد زیادی از آنها را داشته باشیم، اقدامات مشترک آنها شگفتی خلق میکند. شما با استفاده از مشاهدات، ورودی دریافت میکنید و آن را وارد یک لایه میکنید. آن لایه یک خروجی ایجاد میکند که به نوبه خود به ورودی برای لایه بعدی تبدیل میشود، و همینطور ادامه مییابد. این فرآیند بارها و بارها تکرار میشود تا به سیگنال خروجی نهایی برسید!
نورون (گره) «Node» یک یا چند سیگنال (مقادیر ورودی) دریافت میکند که از نورون عبور میکنند. آن نورون سیگنال خروجی را تحویل میدهد. به طور ساده تر در شبکههای عصبی مصنوعی، هر گره دارای چندین ورودی است که سیگنالهای ورودی را دریافت میکند. این سیگنالها با وزنهایی ضرب میشوند و سپس با یکدیگر جمع میشوند تا یک مقدار ورودی واحد را تشکیل دهند. این مقدار ورودی واحد به یک تابع فعالسازی «activation function» داده میشود که خروجی نهایی را تولید کند.
این مکانیزم پردازش ورودیها و تولید خروجی توسط هر گره، الهامگرفته از عملکرد نورونهای مغز انسان است و پایه و اساس یادگیری عمیق را تشکیل میدهد.
لایه ورودی را مانند حواس خود در نظر بگیرید: مثلا مانند چیزهایی که میبینید، میبویید و احساس میکنید. اینها متغیرهای مستقل برای یک مشاهده واحد هستند. این اطلاعات به اعداد و بیتهای داده باینری که یک کامپیوتر میتواند استفاده کند، تجزیه میشوند. شما باید این متغیرها را یا استاندارد کنید یا نرمالسازی کنید تا در یک محدوده یکسان قرار بگیرند. این شبکهها از لایههای متعدد واحدهای پردازشی غیرخطی تشکیل شدهاند که به صورت سلسلهمراتبی و تدریجی ویژگیهای مفهومی پیچیدهتری را از دادههای ورودی استخراج میکنند. هر لایه، خروجی لایه قبلی را به عنوان ورودی دریافت کرده و آن را به یک نمایش انتزاعیتر تبدیل میکند. این فرآیند یادگیری سلسلهمراتبی، منجر به ایجاد یک تفسیر هرمی از مفاهیم و ویژگیهای پایه تا مفاهیم انتزاعیتر میشود.
این بدان معناست که به عنوان مثال در یک تصویر، ورودی ممکن است یک ماتریس از پیکسلها باشد. لایه اول ممکن است لبهها را کدگذاری کند و پیکسلها را ترکیب کند. لایه بعدی ممکن است آرایشی از لبهها را ترکیب کند. لایه بعدی ممکن است بینی و چشمها را کدگذاری کند. لایه بعدی ممکن است تشخیص دهد که تصویر حاوی یک صورت است، و به همین ترتیب ادامه مییابد.
چه اتفاقی درون یک نورون رخ میدهد؟
گره ورودی «Input Node» اطلاعات را به شکل عددی دریافت میکند. اطلاعات به صورت یک مقدار فعالسازی «Activation Value» ارائه میشود که به هر گره یک عدد داده میشود. هر چه این عدد بزرگتر باشد، میزان فعالسازی بیشتر است.
بر اساس قدرت اتصال (وزنها) «Weights» و تابع انتقال «Transfer Function»، مقدار فعالسازی به گره بعدی منتقل میشود. هر یک از گرهها مجموع مقادیر فعالسازی که دریافت میکند را جمع میکند واین مجموع را بر اساس تابع انتقال خود تغییر میدهد. سپس، یک تابع فعالسازی «Activation Function» را اعمال میکند. تابع فعالسازی، تابعی است که به این نورون خاص اعمال میشود. از این طریق، نورون متوجه میشود که آیا نیاز به انتقال سیگنال دارد یا خیر.
هر یک از سیناپسها وزنهایی دارند که برای شبکههای عصبی مصنوعی «Artificial Neural Networks – ANNs» بسیار حیاتی هستند. وزنها چگونگی یادگیری شبکههای عصبی مصنوعی را تعیین میکنند. با تنظیم وزنها، ANN تصمیم میگیرد که تا چه میزان سیگنالها باید منتقل شوند.
فرآیند بازانتشار «backpropagation» در شبکههای عصبی به این صورت است:
- «Activation» یا فعالسازی از طریق شبکه عبور میکند تا به گرههای خروجی «output nodes» برسد.
- گرههای خروجی، خروجی را به شکلی ارائه میدهند که ما بتوانیم درک کنیم.
- شبکه از یک تابع هزینه «cost function» برای مقایسه خروجی واقعی و خروجی پیشبینیشده استفاده میکند.
- عملکرد مدل «model performance» توسط این تابع هزینه ارزیابی میشود.
- تابع هزینه به صورت اختلاف بین مقدار واقعی و مقدار پیشبینیشده «difference between actual value and predicted value» بیان میشود.
- هدف، به حداقل رساندن تابع زیان «minimize loss function» است که هر چه کمتر باشد، به خروجی مورد نظر نزدیکتر خواهد بود.
- اطلاعات به عقب باز میگردند و شبکه عصبی با هدف به حداقل رساندن تابع هزینه، شروع به یادگیری با تنظیم وزنها «tweaking the weights» میکند.
- این فرآیند «بازانتشار» «backpropagation» نامیده میشود.
در انتشار رو به جلو «Forward Propagation»، اطلاعات وارد لایه ورودی میشود و برای دریافت مقادیر خروجی از طریق شبکه به جلو منتشر میشود. مقادیر با نتایج مورد انتظار مقایسه میشود. سپس، خطاها محاسبه میشوند و اطلاعات به عقب منتشر میشوند. این امر اجازه میدهد تا شبکه آموزش ببیند و وزنها را بهروزرسانی کند. در واقع انتشار معکوس اجازه میدهد تا همه وزنها همزمان تنظیم شوند. که البته این موضوع باعث میشود تا ببینیم که هر یک از وزنهای ما در شبکه عصبی مسئول کدام بخش از خطاها هستند.
هنگامی که وزنها به مقدار بهینه تنظیم شد، آماده ورود به مرحله آزمایش «Testing Phase» میشود!
یک شبکه عصبی مصنوعی چگونه یاد میگیرد؟
برای اینکه یک برنامه آنچه را که میخواهیم انجام دهد، دو رویکرد متفاوت وجود دارد. اول، رویکرد راهنمایی شده و برنامهریزی شده به صورت خاص است. در این رویکرد، شما به برنامه دقیقاً میگویید که چه کاری را باید انجام دهد. اما نوع دوم، رویکرد شبکههای عصبی است. در شبکههای عصبی، شما به شبکه خود ورودیها و خروجیهای مورد نظر را میگویید و سپس به آن اجازه میدهید تا خودش یاد بگیرد.
با اجازه دادن به شبکه برای یادگیری به صورت خودکار، میتوان از ضرورت وارد کردن همه قوانین اجتناب کرد. میتوان معماری را ایجاد کرد و سپس آن را برای یادگیری آزاد گذاشت. پس از آموزش، میتوان یک تصویر جدید به آنچه ساخته شده ارائه داد و آن هم خواهد توانست خروجی را تشخیص دهد.
شبکههای پیشخور و بازخورد
یک شبکه پیشخور «Feedforward Network»
شبکهای است که شامل ورودیها، خروجیها و لایههای پنهان است. سیگنالها در آن فقط میتوانند در یک جهت (رو به جلو) حرکت کنند. دادههای ورودی وارد لایهای میشوند که در آن محاسبات انجام میشود. هر عنصر پردازشی بر اساس مجموع وزندار ورودیهای خود محاسبه میکند. مقادیر تازه تبدیل به مقادیر ورودی جدیدی میشوند که لایه بعدی را تغذیه میکنند (پیشخور). این در تمام لایهها ادامه مییابد و خروجی را تعیین میکند. شبکههای پیشخور اغلب در دادهکاوی استفاده میشوند.
شبکههای بازخوردی «Feedback Network»
(به عنوان مثال، شبکههای عصبی بازگشتی) مسیرهای بازخورد دارند. به این معنی که میتوان سیگنالها را در هر دو جهت با استفاده از حلقهها جابجا کرد. در این حالت تمام ارتباطات ممکن بین نورونها مجاز هستند. از آنجا که حلقهها در این نوع شبکه وجود دارند، به یک سیستم دینامیکی غیرخطی تبدیل میشود که تا زمان رسیدن به حالت تعادل به طور مداوم تغییر میکند. شبکههای بازخوردی اغلب در مسائل بهینه سازی مورد استفاده قرار میگیرند، جایی که شبکه به دنبال بهترین چینش عوامل درهم تنیده است.
مجموع وزندار «Weighted Sum» چیست؟
ورودیهای یک نورون یا میتواند از ویژگیهای مجموعه آموزشی باشد یا خروجیهای نورونهای لایه قبلی. هر اتصال بین دو نورون دارای یک سیناپس منحصر به فرد با یک وزن منحصر به فرد است. اگر بخواهید از یک نورون به نورون بعدی برسید، باید امتیاز (وزن) سیناپس را بپردازید. سپس نورون، تابع فعال سازی را بر روی مجموع ورودیهای وزن دار از هر سیناپس ورودی اعمال میکند و نتیجه را به همه نورونهای لایه بعدی منتقل میکند. ضمنا وقتی از به روزرسانی وزنها در یک شبکه صحبت میکنیم، منظور تنظیم مقادیر این وزنهای سیناپسی است.
ورودی یک نورون مجموع خروجیهای وزندار از تمام نورونها در لایه قبلی آن است. هر ورودی در وزن مرتبط با سیناپسی که ورودی را به نورون فعلی متصل میکند، ضرب میشود. اگر ۳ ورودی یا نورون در لایه قبلی وجود داشته باشد، هر نورون در لایه فعلی ۳ وزن متمایز خواهد داشت یعنی یکی برای هر سیناپس.
تابع فعالسازی «Activation function» چیست؟
به طور خلاصه، تابع فعالسازی یک گره «node»، خروجی آن گره را تعریف میکند.
تابع فعالسازی (یا تابع انتقال «transfer function») سیگنالهای ورودی را به سیگنالهای خروجی ترجمه میکند.
تابع انتقال «Transfer Function» یک نقش کلیدی در نحوه عملکرد نورونهای مصنوعی در شبکههای عصبی دارد:
- ترجمه سیگنالهای ورودی به سیگنالهای خروجی: تابع فعال سازی ورودیها را گرفته و آن را به یک خروجی مناسب ترجمه میکند.
- نگاشت خروجیها در محدودهای مشخص: معمولاً این محدوده بین ۰ تا ۱ یا -۱ تا ۱ است. این محدوده سازی به شبکه اجازه میدهد تا خروجیها را به شکل معنادار تفسیر کند.
- نمایش احتمال فعال شدن نورون: تابع فعال سازی میزان احتمال فعال شدن یک نورون را نشان می دهد. در مواردی ساده، این به صورت دوتایی (فعال شدن یا فعال نشدن) است.
- کاربرد در تشخیص الگو: به عنوان مثال، اگر از تابعی استفاده شود که محدوده ۰ تا ۱ را به احتمال تشخیص گربه در تصویر نگاشت کند، خروجی ۰٫۹ نشان دهنده ۹۰٪ احتمال وجود گربه در تصویر است.
- بنابراین در مجموع، تابع فعال سازی نقش بسیار مهمی در چگونگی پردازش اطلاعات در شبکه های عصبی مصنوعی دارد.
توابع فعالسازی زیادی وجود دارند، اما این چهار مورد بسیار رایج هستند:
- تابع آستانه (Threshold Function):
این یک تابع پلهای است که خروجی آن فقط ۰ یا ۱ است.
ورودی باید از یک آستانه مشخص فراتر رود تا خروجی ۱ شود، در غیر این صورت خروجی ۰ خواهد بود.
این تابع بسیار ساده و صریح است و در برخی موارد مفید میباشد.
- تابع سیگموئید (Sigmoid Function):
این تابع در رگرسیون لجستیک کاربرد دارد.
به جای پلهای بودن، تغییرات آن نسبت به ورودی به صورت نرم و تدریجی است.
خروجی آن بین ۰ و ۱ قرار دارد و میتواند به عنوان احتمال تفسیر شود.
در لایه خروجی شبکههای عصبی کاربرد دارد.
- تابع مماس هیپربولیک (Hyperbolic Tangent Function):
شبیه تابع سیگموئید است، اما خروجی آن بین -۱ و ۱ قرار دارد.
این تابع گاهی در آموزش شبکههای عصبی بهتر از سیگموئید عمل میکند و مانع از گیر کردن در نقاط بحرانی میشود.
- تابع محدب (Rectifier Function):
یکی از پرکاربردترین توابع فعالسازی در شبکههای عصبی است.
این تابع ساده و بیولوژیکی معقولتر است.
خروجی آن صفر یا مقداری مثبت است.
این تابع نیاز به نرمالسازی یا محاسبات پیچیده ندارد.
حال به عنوان مثال فرض کنید مقدار مورد نظر شما باینری «binary» است. شما به دنبال یک «بله» یا «خیر» هستید. کدام تابع فعالسازی را استفاده میکنید؟
از مثالهای بالا، میتوانید از تابع آستانه «threshold function» استفاده کنید یا میتوانید از تابع فعالسازی سیگموید «sigmoid activation function» استفاده کنید. تابع آستانه به شما یک «بله» یا «خیر» (۱ یا ۰) میدهد. تابع سیگموید میتواند احتمال یک بله را به شما بدهد.
اگر، به عنوان مثال، از یک تابع سیگموید برای تعیین احتمال اینکه آیا در تصویر یک گربه است استفاده میکردید، یک خروجی ۰٫۹ نشان دهنده ۹۰٪ احتمال این است که تصویر شما در واقع یک گربه باشد.
نحوه تنظیم وزن ها
میتوان از یک رویکرد نیروی بیرحمانه «brute force approach» برای تنظیم وزنها استفاده کرد و هزاران ترکیب مختلف را مورد آزمایش قرار داد. اما حتی با سادهترین شبکه عصبی «neural network» که فقط پنج مقدار ورودی و یک لایه پنهان «hidden layer» دارد، با ۱۰ به توان ۷۵، ترکیب ممکن مواجه خواهیم شد.
اجرای این کار روی سریعترین ابررایانه جهان بیشتر از عمر جهان تاکنون طول خواهد کشید.
ورود گرادیان نزولی «gradient descent»
اما اگر از گرادیان نزولی استفاده شود، میتوان زاویه شیب وزنها را بررسی کرد و فهمید که آیا حاصل مثبت است یا منفی. تا بتوان به سراشیبی ادامه داد و بهترین وزنها را در تلاش خود برای رسیدن به حداقل جهانی «global minimum» پیدا کرد.
گرادیان نزولی یک الگوریتم برای یافتن حداقل یک تابع است. فرایندی که بارها و بارها اتفاق میافتد، به عنوان مثال فردی را تصور کنید که در بالای یک کوه گیر افتاده و سعی میکند پایین بیاید. ضمنا مه غلیظی هم وجود دارد که دیدن مسیر را غیرممکن میکند، بنابراین بهتراست او از گرادیان نزولی استفاده کند تا به پایین کوه برسد. او به تندی تپه در جایی که هست نگاه میکند و در جهت تندترین نزول پیش میرود. البته باید فرض شود که تندی بلافاصله مشخص نیست. اما خوشبختانه، او ابزاری دارد که میتواند تندی شیب را اندازهگیری کند!
متأسفانه، استفاده از این ابزار زمان زیادی میبرد. کوهنورد میخواهد تا حد امکان کمتر از آن استفاده کند تا قبل از تاریکی به پایین کوه برسد. مشکل واقعی انتخاب این است که چقدر میخواهد از ابزارش استفاده کند تا از مسیر خارج نشود.
در این مثال، شخص الگوریتم است. تندی تپه، شیب سطح خطا «error surface» در آن نقطه است. جهتی که او میرود، گرادیان سطح خطا در آن نقطه است. ابزاری که او استفاده میکند مشتقگیری «differentiation» است (شیب سطح خطا را میتوان با گرفتن مشتق تابع خطای مربعی «squared error function» در آن نقطه محاسبه کرد). سرعتی که او قبل از اندازهگیری دیگر طی میکند، نرخ یادگیری «learning rate» الگوریتم است.
این یک مقایسه کامل نیست، اما درک خوبی از ماهیت گرادیان نزولی به ارائه میدهد.
گرادیان نزولی نیاز دارد که تابع هزینه «cost function» محدب «convex» باشد، اما اگر نباشد چه؟
گرادیان نزولی معمولی ممکن است در یک حداقل محلی گیر کند، منظور این است که:
در الگوریتم گرادیان نزولی معمولی «Batch Gradient Descent»، وزنهای شبکه عصبی را بر اساس کل دادههای آموزشی «یک دسته یا batch» به روز میکنیم. این روش ممکن است باعث شود الگوریتم در یک حداقل محلی «Local Minimum» گیر کند، به جای رسیدن به حداقل جهانی «Global Minimum» که بهینهترین جواب است.
در مقابل، در الگوریتم گرادیان نزولی تصادفی «Stochastic Gradient Descent»، وزنها را بر اساس هر نمونه داده به طور جداگانه به روز میکنیم. این روش به الگوریتم اجازه میدهد از حداقلهای محلی خارج شود و به سمت حداقل جهانی حرکت کند. بنابراین، گرادیان نزولی تصادفی معمولاً نتیجه بهتری نسبت به گرادیان نزولی معمولی به دست میدهد.
خلاصه اینکه گرادیان نزولی تصادفی توانایی بیشتری در یافتن حداقل جهانی (نه حداقل محلی) دارد.
گرادیان نزولی تصادفی نوسانات بسیار بالاتری دارد که به ما این امکان را میدهد تا حداقل جهانی را پیدا کنیم. به آن «تصادفی» میگویند زیرا نمونهها به صورت تصادفی مرتب میشوند، نه به عنوان یک گروه واحد یا به ترتیبی که در مجموعه آموزشی «training set» ظاهر میشوند. به نظر میرسد که ممکن است کندتر باشد، اما در واقع سریعتر است زیرا نیازی به بارگذاری همه دادهها در حافظه و انتظار برای اجرای همه دادهها با هم نیست. مزیت اصلی گرادیان نزولی دستهای این است که یک الگوریتم قطعی «deterministic algorithm» است. این بدان معناست که اگر وزنهای شروع یکسانی داشته باشید، هر بار که شبکه را اجرا میکنید، همان نتایج را خواهید گرفت. گرادیان نزولی تصادفی همیشه به صورت تصادفی کار میکند. (شما همچنین میتوانید گرادیان نزولی مینی-بچ «mini-batch gradient descent» را اجرا کنید که در آن تعدادی سطر را تعیین میکنید، آن تعداد سطر را هر بار اجرا میکنید و سپس وزنهای خود را بهروز میکنید.)
بسیاری از بهبودها در الگوریتم پایه گرادیان نزولی تصادفی پیشنهاد و استفاده شدهاند، از جمله بهروزرسانیهای ضمنی
«implicit updates»، روش مومنتوم «momentum method»، گرادیان نزولی تصادفی میانگینگیری شده «averaged stochastic gradient descent»، الگوریتم گرادیان تطبیقی «adaptive gradient algorithm – AdaGrad»، انتشار میانگین مربعی ریشه «root mean square propagation – RMSProp»، تخمین مومنت تطبیقی «adaptive «moment estimation – Adam و موارد دیگر.
مرور سریع
در اینجا یک مرور سریع بر آموزش یک شبکه عصبی مصنوعی با استفاده از گرادیان نزولی تصادفی را خواهیم خواند:
وزنها به صورت تصادفی با اعداد کوچک نزدیک به ۰ مقداردهی میشوند.
اولین مشاهده از مجموعه دادههای به لایه ورودی وارد میشوند، به طوری که هر ویژگی در یک گره ورودی قرار گیرد.
انتشار رو به جلو «Forward propagation» – از چپ به راست، نورونها به گونهای فعال میشوند که فعالسازی هر نورون توسط وزنها محدود میشود. فعالسازیها را منتشر میشود تا به نتیجه پیشبینی شده برسیم.
نتیجه پیشبینی شده با نتیجه واقعی مقایسه میشود و خطای تولید شده را اندازهگیری میشود.
انتشار معکوس «Backpropagation» – از راست به چپ، خطا به عقب منتشر میشود. وزنها بر اساس میزان مسئولیتشان در خطا بهروزرسانی میشوند. (نرخ یادگیری تعیین میکند که چقدر وزنها را بهروزرسانی شوند.)
یادگیری تقویتی (مراحل ۱ تا ۵ را تکرار میشوند و وزنها را پس از هر مشاهده بهروزرسانی خواهند شد) یا یادگیری دستهای (مراحل ۱ تا ۵ را تکرار میشوند، اما وزنها فقط پس از یک دسته از مشاهدات بهروزرسانی میشوند).
وقتی کل مجموعه آموزشی از شبکه عصبی مصنوعی عبور کرد، این یک دوره «epoch» است.این فرایند قابل تکرار بیشتر است.
ضمن تشکر از همراهی و مطالعه شما اگرچه تصور بر این است که نمیتوان تمامی دانش مربوط به یک سرفصل را به طور فشرده و در قالب چند صفحه ارائه نمود اما همه چیز از مطالعه و شناخت حداقلی آغاز شده و سپس میتواند شما را با اقیانوسی وسیع از تواناییها و امیال آشنا سازد.