آیا تا بحال از خود پرسیدهاید عملیات تشخیص چهره در شبکههای اجتماعی چگونه کار میکند؟ یا فرآیند تشخیص یک شی (Object) در ماشینهای خودران (self driving car) چگونه است؟ یا شاید هم برای شما جای سوال باشد که چگونه از طریق تصاویر یک بیماری را تشخیص میدهند؟ پاسخ همه این سوالات در شبکه عصبی پیچشی (convolutional neural networks) نهفته است. در این مقاله با این شبکه عصبی آشنا خواهیم شد و لایههای مختلف آن را بررسی میکنیم.
ویدئو آموزش شبکه عصبی پیچشی
عملیات کانولوشن (convolution)
همانطور که از نام شبکه عصبی پیچشی (convolutional neural networks) مشخص است برای ایجاد این شبکه نیاز است با عملیات convolution آشنا باشیم. کانولوشن یک عملیات خطی است که بر روی تصاویر اعمال میشود. روش انجام این عملیات بدین صورت است که ما یک Kernel داریم و میخواهیم عملیات convolution انجام دهیم. عدد وسط ماتریس Kernel را بر روی پیکسلهای تصویر قرار داده و بر روی پیکسلها حرکت میکنیم(دقت کنید در پایان سایز تصویر خروجی کوچکتر میگردد).

تصویر بالا عملیات کانولوشن در یک مرحله انجام گردیده است. تصویر مرحله بعد را مشاهده کنید:

حال تصویر مرحله سوم:

در حقیقت ما ضرب ماتریسها را بر روی پیکسل تصویر و ماتریس kernel اعمال میکنیم و در خروجی یک ماتریس کوچکتر تحویل میگیریم.
لایههای شبکه عصبی پیچشی
عملیات کانولوشن یکی از عملیاتهای مهم شبکه عصبی پیچشی است که در قسمت قبل خلاصهای از آن را توضیح دادیم. اما این شبکهها از چه لایههایی استفاده میکنند؟ CNN شامل لایههای زیر میباشد:
- Convolution یا همان کانولوشن
- Activation
- Pooling
- Fully connected
- Batch normalization
- Dropout
تمامی لایههای گفته شده ساختار یک شبکه عصبی پیچشی میباشد. Activation و Dropout معمولاً به صورت یک لایه جداگانه شناخته نمیشوند اما در نمایش ساختار برخی CNNها، آنها را نیز به عنوان یک لایه جدا نمایش میدهند. Convolutional و Fully connected و Batch normalization دارای پارامترهایی هستند که در هنگام train، یادگیری (Learning) آنها انجام میشود.
لایه Convolution یا همان کانولوشن
با عملیات کانولوشن در بخشهای قبل آشنا شدیم. ما از این عملیات در لایه کانولوشن استفاده میکنیم. این لایه شامل k عدد kernel میباشد. تعداد kernelها توسط ما مشخص میگردد اما مقدار درون kernelها ابتدا به صورت random (تصادفی) انتخاب میشود و در ادامه مقدار آن با توجه به شبکه عصبی (در backpropagation) تغییر میکند. چند نکته در لایه کانولوشن باید به یاد داشته باشید:
- به kernelها فیلتر نیز گفته میشود. این فیلترها بر روی تمامی پیکسلهای تصویر با هر تعداد عمق اعمال میشود.
- عمق تصویر به معنی تعداد کانالهای تصویر است. به عنوان مثال عمق تصویر RGB عدد 3 است یعنی شامل 3 کانال میباشد.
- در لایه کانولوشن عمق به معنای تعداد kernel میباشد. اما همانطور که گفتیم در تصویر ورودی به تعداد کانالهای تصویر عمق گفته میشود.
- به ماتریس ایجاد شده بعد از عملیات کانولوشن، feature map یا activation map میگویند.
عمق
با توجه به اینکه عمق در تصاویر و در لایه کانولوشن معنای متفاوتی دارد در این قسمت توضیح تکمیلی عمق در هر دو بخش را با یکدیگر بررسی خواهیم کرد. همانطور که گفتیم در تصویر عمق به معنای تعداد کانال تصویر است. ابتدا یک تصویر grayscale را با هم ببینیم:

همانطور که در تصویر مشاهده میکنید ما با یک ماتریس 6*6 میتوانیم تصویر grayscale را نمایش دهیم. تعداد کانال در تصویر grayscale یک عدد است. حال تصویر RGB را مشاهده میکنیم:


در تصاویر RGB برای نمایش هر پیکسل نیاز به سه مقدار داریم. عمق را در تصاویر RGB نیز همان تعداد کانالها یا مقادیر در نظر میگیرند که برابر با 3 میباشد.
عمق در لایه کانولوشن اما کمی متفاوت است. تصویر زیر را ببینید:

در تصویر بالا خروجی کانولوشن همان feature map میباشد. این feture mapها در کنار یکدیگر به صورت زیر میباشند:

در تصویر بالا ابعاد feature map را با with و height نمایش داده و تعداد آنها را با depth نشان دادهایم. این تعریف depth در لایه کانولوشن میباشد.
Stride
در عملیات کانولوشن kernel نقشی اساسی در خروجی دارد. ما kernel را در ابتدای تصویر قرار داده از چپ به راست در تصویر حرکت میکنیم. یک نکتهای که قابل تامل است حرکت kernel در تصویر است. بعد از اتمام یک مرحله تعداد یک پیکسل به جلو رفته و مجدداً عملیات کانولوشن را انجام میدهیم. تعداد حرکت رو به جلو ما یک پیکسل است. این مقدار را stride میگویند. اما چرا مقدار یک؟ معمولاً به صورت default مقدار stride برابر با یک قرار میدهند. اما این مقدار میتواند بیشتر شود و با توجه به مسئله و تصویر ورودی میتوان آن را تنظیم نمود.

در تصویر بالا یک فیلتر با سایز 3*3 در نظر گرفته شده است. قسمت بالای تصویر stride برابر با عدد یک است و در قسمت پایین تصویر Stride برابر با 2 میباشد. خروجی را مشاهده میکنید که feature map در قسمت پایین کوچکتر شده است. پس هر چه میزان stride بزرگتر باشد ماتریس feature map کوچکتر خواهد شد.
padding
Feature map حاصل عملیات کانولوشن میباشد. همانطور که مشخص است ماتریس Feature map ابعادی کوچکتر از سایز تصویر ورودی خواهد داشت. اگر بخواهیم سایز خروجی با تصویر ورودی یکسان باشد به تصویر padding اضافه میکنند. این تکنیک گاهاً zero padding نیز نامیده میشود. در این روش ما برای اینکه سایز خروجی با تصویر ورودی یکسان باشد به حاشیه تصویر ورودی، پیکسلهایی با مقدار صفر اضافه میکنیم.

در تصویر بالا ما یک لایه zero padding به تصویر ورودی اضافه کردیم. بعد از اعمال فیلتر 3*3 خروجی این عملیات را با هم ببینیم:

در تصویر بالا ماتریس خروجی هم اندازه با تصویر ورودی گردیده است. این کار با padding امکان پذیر شد.
فرمول جمعبندی پارامترها
اگر ابعاد تصویر ورودی n*n و فیلترها f*f باشد و مقدار p برابر با padding و s برابر با stride اعمال شده در نظر گرفته شود. از فرمول زیر برای محاسبه سایز feature map استفاده میگردد. دقت کنید سایز feature map باید عددی صحیح (یا integer) باشد.
M=((n − f + 2p) / s) + 1
سایز feature map برابر با M*M خواهد بود. به عنوان مثال در مثال بخش قبل تصویر ورودی ابعاد 6*6 داشت. فیلتر اعمالی ابعاد 3*3 و padding و stride برابر با یک بود. فرمول بالا را اعمال کنیم:
M=((6 − 3 + 2*1) / 1) + 1 = 6
ابعاد feature map برابر با 6*6 خواهد بود که در تصویر بالا همین سایز را نشان میدهد.
Activation Layers
پس از اینکه همه فیلترها اعمال و feature mapها ساخته شدند. از تابع activation استفاده میکنند. در این لایه یک تابع غیر خطی را در خروجی اعمال میکنند. تابع RELU در شبکه عصبی پیچشی یا CNN بسیار معروف است. این تابع اگر عدد ورودی منفی باشد در خروجی صفر برمیگرداند در غیر این صورت همان عدد بازگردانی میشود. از این تابع در CNN بسیار استفاده میشود:

نمودار تابع RELU به صورت زیر است:

pooling
لایه pooling برای کاهش ابعاد میباشد البته این لایه برای جلوگیری از overfitting نیز به شبکه عصبی کمک میکند. دو روش pooling معروف وجود دارد یکی max pooling و دیگری average pooling است. در pooling نیز فیلتری در نظر گرفته میشود که معمولاً سایز آن 2*2 میباشد. البته ابعاد بزرگتر نیز مانند 3*3 یا … در بعضی از شبکههای عمیق استفاده گردیده است. اما به طور معمول سایز فیلتر همان 2*2 میباشد. این فیلتر با فیلتری که در عملیات کانولوشن استفاده میشود کمی متفاوت است. روش max pooling با فیلتر 2*2 به صورت زیر میباشد:

عدد وسط ماتریس فیلتر را بر روی پیکسلهای تصویر قرار داده و بر روی پیکسلها حرکت میکنیم. اما برای عملیات max pooling، ماکزیمم پیکسلی که در محدوده فیلتر قرار دارد را در خروجی قرار میدهیم. سپس یک گام به اندازه stride رو به جلو حرکت میکنیم. برای average pooling اما بجای ماکزیمم، میانگین پیکسلها در محدوده فیلتر را محاسبه و در خروجی قرار میدهیم:

برای محاسبه ابعاد خروجی pooling از فرمول زیر استفاده میشود:
Woutput = ((Winput −F) / S) +1
Houtput = ((Hinput −F) / S) +1
W عرض و H ارتفاع خروجی بوده و همچنین F سایز فیلتر و S مقدار stride میباشد.
Fully connected Layers
نورونهای لایه Fully connected به همه نورونهای لایه قبل متصل میباشند دقیقاً مانند یک شبکه عصبی استاندارد. لایه Fully connected در انتهای ساختار یک CNN قرار دارد و از آن در ابتدای شبکه استفاده نمیشود. به طور معمول حداقل یک یا دو لایه Fully connected در انتهای CNN استفاده میکنند. در پایان معرفی لایههای CNN، اولویتبندی لایهها و ترتیب آنها را نیز با یکدیگر بررسی خواهیم کرد.
Batch Normalization
همانطور که از نام این لایه مشخص است برای نرمال کردن اطلاعات استفاده میشود. قبل از ارسال اطلاعات به لایه بعدی، ابتدا دادهها را نرمالسازی میکند سپس به لایه بعدی ارسال میشوند. این کاری است که Batch Normalization انجام میدهد.

متغیرهای Z در تصویر بالا عملیات نرمالسازی را انجام میدهند. برای آشنایی بیشتر در زمینه فرمول ریاضی این لایه میتوانید به لینک مراجعه نمایید. این نکته را به یاد داشته باشید که معمولا Batch Normalization بعد از لایه activation قرار میگیرد.
Dropout
کاری که Dropout انجام میدهد بسیار ساده است. ابتدا تصویر این لایه را ببینید:

بعضی از اتصالات در شبکه عصبی توسط dropout حذف میشود (در نظر گرفته نمیشود). این کار برای جلوگیری از overfitting میباشد. عملیات حذف اتصالات بین لایههای شبکه عصبی کاملاً تصادفی (random) میباشد. به طور معمول نیمی از اتصالات را حذف میکنند به همین دلیل p = 0.5 را به dropout میدهند. بدین معنی که 50% اتصالات میبایست حذف شود.
الگوی لایهها
نحوه چینش شبکه CNN بسیار مهم است. به طور معمول ساختار این شبکه از یک یا چند لایه کانولوشن (به همراه RELU) آغاز میشود. در ادامه لایه pooling اضافه میشود. دو مرحله قبل را آنقدر تکرار میکنیم تا ابعاد تصویر به اندازه کافی کوچک شود و بتوان آن را در شبکه عصبی قرار داد. در این نقطه یک یا چند لایه Fully connected قرار میگیرد. ساختار CNN در ایجا به پایان میرسد. گرچه تا زمانی که پیاده سازی واقعی انجام نشده است کمی لایهها گیجکننده بنظر میرسند اما ساختار آنها به طور معمول به این صورت است. فرموله کردن لایهها را با هم ببینیم:
INPUT => [[CONV => RELU]*N => POOL?]*M => [FC => RELU]*K => FC
- INPUT تصویر ورودی
- CONV لایه کانولوشن
- RELU تابع activation
- POOL لایه pooling
- FC یا لایه Fully connected
- K و M مقدار ثابت بوده که توسط ما انتخاب میشود.