پیاده سازی اولین شبکه عصبی برای طبقه بندی تصاویر (قسمت اول)
تو این نوشتار هدف ما طراحی و پیاده سازی یک شبکه عصبی پرسپترونی با دو لایه مخفی برای طبقه بندی تصاویره! در نظر داشته باشید تو این تمرین برای اینکه کارمون راحت باشه از لایه های دیگه که داخل شبکه های عصبی استفاده میشه مانند کانولوشن ها صرف نظر کردیم و صرفا در قالب الگوریتم شبکه عصبی پرسپترونی عمل می کنیم و با لایه های Dense سر و کار داریم ، طبیعتا استفاده از سایر متدها و لایه ها میتونه نتیجه ای که ما در این نوشتار بدست میاریم رو بهبود بده ولی در اینجا هدف صرفا آموزش هر چه ساده تر پیاده سازی اولین شبکه عصبی برای فردی هست که قصد داره کار با شبکه های عصبی رو شروع کنه!
خوب ابتدا توضیح میدم که قراره چه تصاویری رو دسته بندی کنیم ، مجموعه تصاویر مورد استفاده در اینجا مجموعه داده MNIST هست که این مجموعه داده یک مجموعه داده بسیار معروف جهت شناسایی و نمایش ارقام از 0 تا 9 است . در این مجموعه داده هر تصویر نشان دهنده یک عدد تک رقمی است که در کل در 10 دسته ( از صفر تا 9 ) طبقه بندی شده اند ، این مجموعه داده مجموعا از هفتاد هزار تصویر تشکیل شده است که 60 هزار تصویر آن در مجموعه آموزشی و 10 هزار تصویر تصویر در مجموعه تست قرار گرفته اند.
نمونه ای از تصاویر موجود در دیتاست MNIST رو مشاهده می کنید :
اگه می خواید اطلاعات بیشتری راجع به این مجموعه داده تصویری پیدا کنید می تونید به لینک زیر سر بزنید!
http://yann.lecun.com/exdb/mnist/
خوب حالا باید این مجموعه تصویر رو دانلود کنیم تا داخل کدمون ازش استفاده کنیم ، یه راه حل مراجعه به همین لینک بالا و دانلود این مجموعه هست ، اما خوب راه ساده تری هم وجود داره و می تونیم به راحتی از کتابخانه ها برای دانلود Mnist استفاده کنیم ، با استفاده از قطعه کد زیر تصاویر در دو قسمت آموزشی و تست دانلود میشن :
حالا بعد از دانلود تصاویر و قبل از پیاده سازی مدل شبکه عصبی لازم است ، داده های ما نرمال یا استاندارد بشوند، اما چرا لازمه این کار رو انجام بدیم؟
وقتی داده های ما بدون پیش پردازش به عنوان ورودی به شبکه عصبی داده بشه ، الگوریتم شبکه عصبی با توجه به پراکندگی داده ها و تفاوت مقیاس داده ها دچار حساسیت میشه و باعث بالا رفتن مقادیر وزن های شبکه عصبی میشه که در نهایت باعث تولید نتیجه نامناسب میشه
برای نرمالسازی می تونیم مقدار ماکزیمم و مینیمم هر ستون از داده ها رو محاسبه کنیم و با استفاده از روش MinMax و فرمول زیر داده ها رو نرمالسازی کنیم! دقت کنید داده ها باید در یک محدوده مشخص نرمال بشن (اینجا بین صفر و یک)!
خوب در روش نرمالسازی پراکندگی داده ها تغییر نمیکنه ولی در روش استانداردسازی مقادیر میانگین و انحراف معیار تغییر خواهند کرد ، مقدار میانگین صفرو انحراف معیار 1 خواهد شد. با تمام این تفاسیر با استفاده از فرمول زیر و محاسبه میانگین و انحراف معیار داده ها می تونیم داده ها رو استانداردسازی کنیم!
یه راه ساده تر و سریع تر از دو روش بالا هم وجود داره که به نوعی نرمالسازی صورت می گیره با توجه به اینکه پیکسل داده های این شبکه عصبی از نوع Graylevel هستند و در بازه 0 تا 255 قرار دارند ، کافی است آنها را فقط تقسیم بر 255 بکنیم. سپس آنها را Reshape می کنیم تا بتوانیم از این داده ها در ورودی مدل شبکه عصبی استفاده کنیم.
برای پیاده سازی نرمالسازی و استاندارد سازی می تونیم از کتابخانه Scikit استفاده کنیم.
نمونه کد برای نرمالسازی داده ها :
نمونه کد برای استاندارد سازی داده ها :
خوب حالا بعد نرمالسازی یا استانداردسازی داده هامون باید اونها رو به ابعادی در بیاریم که بتونیم داخل شبکه عصبی استفاده کنیم ، تصاویر مجموعه Mnist در ابعاد 28 در 28 هستن و فقط کافیه اونها رو به یک بردار 784 بعدی تبدیل کنیم! این کار رو هم برای داده های آموزشی و هم داده های تست انجام میدیم.
قطعه کد برای تغییر ابعاد :
حالا برای داده های هدف ، یعنی دسته های کلاسمون هم باید تغییر ابعاد انجام بدیم! به این صورت که شماره کلاس ها رو به روش One-hot کد گذاری کنیم یعنی مثلا به جای اینکه داده هدفمون وقتی عددمون تو دسته سوم هست 3 باشه ، بیایم از یک آرایه با ده خانه استفاده کنیم و تمام خونه های اون رو برابر صفر قرار بدیم و تنها خونه سوم رو برابر با یک قرار بدیم تا نشون بده این تصویر به دسته سوم تعلق داره!!
این کار رو برای تمام داده های هدف انجام میدیم ، برای این کار میشه به راحتی از قطعه کد زیر داخل کتابخانه استفاده کرد :
داده ها رو هم برای اینکه آموزش شبکه به درستی انجام بشه و تصاویر از دسته های مختلف برای آموزش انتخاب بشن با استفاده از قطعه کد زیر ، آنها را بُر می زنیم!
حالا لازم هست معماری شبکمون رو طراحی کنیم! همونطور که قبلا گفته شد قصد داریم یک شبکه با دو لایه مخفی طراحی کنیم ، حالا معماری کلی شبکمون رو می دونیم ولی باید تعداد نورون های مورد استفاده داخل این معماری رو بدست بیاریم!
ابتدا در مورد نورون های ورودی باید دقت کنیم تعداد نورون های لایه ورودی ما برابر با ابعاد تصویر ورودی هست! و از اونجایی که در این مسئله تمام تصاویر ما 784 بعدی هستن! پس تعداد نورون های لایه ورودی هم 784 تا میشه!
خوب حالا که تعداد نورون ورودی مشخص شد ، باید تعداد نورون های لایه خروجی رو مشخص کنیم! تعداد نورون های لایه خروجی در یک مسئله طبقه بندی برابر با تعداد طبقه های ما هست ، ما تو این مسئله ده طبقه (کلاس) داده داریم پس 10 نورون خروجی خواهیم داشت!
حالا که تکلیف نورون های ورودی و خورجی مشخص شد ، میریم سراغ نورون های لایه مخفی ! خوب نمیشه قبل از آموزش شبکه و بارها تست گرفتن تعداد نسبتا دقیقی نورون براش قرار داد! کشف تعداد نورون لازم برای لایه های میانی یا همان لایه های مخفی در این مسئله نیازمند تعداد زیادی آزمایش هست تا با بررسی دقتشون به نتیجه مشخصی برسیم !
اما میتوان یک تخمین نسبی برای تعداد نورون های لایه مخفی زد ، تعداد نورون ها نباید نسبت به ابعاد تصویر اولیه خیلی کمتر یا خیلی بیشتر باشند تا شبکه دچار Overfitting یا Underfitting نشه! فعلا تو این مسئله تعداد نورون های هر دو لایه مخفی رو برابر با 512 در نظر می گیریم و خودتون می تونید تغییر بدید!
در نهایت ما چنین معماری ای برای شبکه عصبی طبقه بندمون خواهیم داشت:
خوب حالا نوبت به پیاده سازی شبکه عصبی رسیده ! برای پیاده سازی شبکه عصبی همونطور که داخل قطعه کد زیر مشخص هست از تعدادی لایه Dense موجود در کتابخانه Keras استفاده می کنیم ، همونطور که مشخص هست اندازه تصویر ورودی 784 ، و تعداد نورون های دو لایه Dense اول برابر 512 و لایه آخر نیز برابر 10 در نظر گرفته شده است. کلیت ساختار پیاده سازی یک مدل شبکه عصبی به همین صورت هست ، حالا علاوه بر پارامتری مانند تعداد نورون ، پارامترها و توابع دیگه ای مثل تابع فعالساز ، نرخ یادگیری ، بهینه ساز و تابع هزینه هم در قطعه کد زیر مشخص هست که در قسمت دوم آموزش در مورد تاثیر و کاربرد هر کدومشون صحبت می کنیم
خوب حالا نوبت به آموزش شبکه میرسه ، از قطعه کد زیر برای این کار استفاده می کنیم:
دو آرگومان اول شامل تصاویر و داده های هدف هستن ، یک آرگومان برای تعداد Epoch داریم که تعداد دوره هایی رو مشخص میکنه که میخواهیم شبکه مورد آموزش قرار بگیره و آرگومان Validation_split نیز نمایش دهنده درصد داده هایی هست که از داده های ورودی به عنوان داده های ارزیابی ( نه برای اموزش) قرار است در هر Epoch استفاده شود. همچنین مقدار آرگومان batch size اندازه دسته ها را مشخص می کند که در قسمت دوم آموزش در مورد تاثیر آن توضیح داده می شود.
در نهایت از داده های تست نیز برای ارزیابی دقت شبکه استفاده می کنیم ، مطابق با قطعه کد زیر 10 هزار تصویر تست را به شبکه می دهیم و نتایج بدست آمده را با نتایج واقعی مقایسه می کنیم و مقدار دقت و خطا را بدست میاریم:
نتیجه بدست آمده از داده های تست :
Test - Loss: 0.06670001149177551
Test - Accuracy 0.9790999889373779
کد رسم نمودار دقت و خطا :
نمودار میزان دقت داده های آموزش و ارزیابی شبکه در 50 دوره
نمودار میزان خطا داده های آموزش و ارزیابی شبکه در 50 دوره
تا اینجا توانستیم یک شبکه برای طبقه بندی تصاویر ایجاد کنیم ، توضیحات مربوط به توابع و پارامترهای مختلف در قسمت دوم آموزش داده شده است.
مطلبی دیگر از این انتشارات
آینده تشخیص چهره در ایران
مطلبی دیگر از این انتشارات
آیا با استفاده از تحلیل کلیدواژههای جستجوشده در گوگل میتوان روندهای تقاضا را پیشبینی کرد؟
مطلبی دیگر از این انتشارات
رسم داده ها بر روی نقشه ها با پایتون