چگونه یک مدل برای شناسایی مکان‌ها آموزش دادیم؟

نویسندگان ‌: محیا مهدیان و محمد حسن ستاریان

مقدمه

deeplearning

در هر مسئله دسته‌بندی (Classification)، پیاده‌سازی یک مدل مناسب -از جهت صحت پیش‌بینی- به مولفه‌های متفاوتی وابسته است؛ داشتن ورودی‌های -با ویژگی‌های- گوناگون و به تعداد زیاد یکی از مولفه‌های مهم برای آموزش مدلی که دقیق (Accurate) بوده و قادر به عمومیت بخشی (Generalization) به دانش خود و راستی آزمایی آن در محیط واقعی است می‌باشد. با این حال جمع آوری داده زیاد کاری سخت و نیازمند زمان و هزینه زیاد، بسته به شرایط و نوع داده مورد نیاز خواهد بود. در این شرایط و با توجه به اینکه کار‌های پیشین زیادی انجام شده اند، استفاده از روش‌های یادگیری انتقال (Transfer learning)، درواقع استفاده از یک مدل از پیش آموزش دیده و استفاده از آن به عنوان استخراج کننده ویژگی (Feature Extractor) یا به عنوان شبکه Fine Tuning کمک بسیار زیادی در ساخت مدلی دقیق و مناسب خواهد داشت. همچنین استفاده از روش‌های افزایش داده (Data augmentation) باعث افزایش چشم‌گیر داده شده و در آموزش بهتر مدل موثر خواهد بود؛ با این‌حال در استفاده از این روش باید توجه داشت از روش‌هایی برای تغییر عکس استفاده کرد که عکس خروجی خارج از فضای حالت مسئله نبوده و در شرایط واقعی مسئله وجود داشته باشد. به علاوه در جمع‌آوری داده باید داده‌های جمع آوری شده بررسی و در صورت نیاز پاکسازی‌هایی نیز انجام شود، تا داده‌های نامناسب، نامربوط و بی‌تاثیر حذف شوند اما از عمومیت داده‌ها کم نشده و داده‌های مختلفی در شرایط مختلف آزمون مسئله وجود داشته باشد؛ چرا که هرچه داده‌ها متفاوت‌تر باشند مدل قابلیت عمومیت بخشی بیشتری خواهد داشت. استفاده از پارامترهای (Hyperparameter)‌ مناسب در آموزش مدل، انتخاب دقیق و بسته به شرایط -و داده‌- پارامترها نیز از اهمیت زیادی برخوردار است و شاید نیاز باشد تغییر دقت مدل با تغییر این پارامترها بررسی شود که در این‌صورت نیاز است مدل چندین دفعه آموزش داده شود.

مراحل پیاده‌سازی مدل

هدف ما آموزش مدلی بود تا بتواند مکان‌های دانشگاه را تشخیص بدهد؛ برای پیاده‌سازی مدل خود از فریم‌ورک کراس (Keras) و زبان پایتون استفاده کردیم. از آنجایی که تعداد کلاس‌ها کم بوده و امکان جمع‌آوری داده زیادی که بتواند مدل را خوب آموزش بدهد نبود، مدلی برای استفاده به عنوان مدل پایه (Base Model)‌ برای Fine Tuning انتخاب شد. سپس داده‌های مورد نیاز جمع‌آوری شده، تمیز شده و آماده آموزش شدند. مدل روی گوگل کولب (Google Colab) به همراه استفاده از روش‌های افزایش داده آموزش داده شده و ذخیره شد. برای استفاده از مدل برنامه‌ای برای اجرای آن روی سرور و گرفتن خروجی با میکروفریم‌ورک فلسک نوشته شده و اپلیکیشن اندرویدی نیز برای گرفتن عکس و پیش‌بینی آن در لحظه ساخته شد. هر مرحله به تفضیل توضیح داده خواهد شد:

کد تمامی مراحل در ریپوزتوری «SRU-Place-Recognizer» قابل دسترسی است.

پیدا کردن مدل پایه

VGG16 + places365

همانطور که گفته شد از آنجایی که تعداد کلاس‌ها کم بوده و امکان جمع‌آوری داده زیادی که بتواند مدل را خوب آموزش بدهد نبود، از روش یادگیری انتقال (Transfer learning) استفاده کرده و مدل VGG16 Places365  برای استفاده به عنوان مدل پایه (Base Model)‌ برای Fine Tuning انتخاب شد. این مدل یک شبکه VGG16 است که از پیش با داده‌های دیتاست Places365 که شامل بیش از ۱۰ میلیون عکس در بیش از ۴۰۰ موضوع است آموزش داده شده است؛ پس نه تنها ویژگی‌های اولیه مورد نیاز مسئله در لایه‌های ابتدایی شناسایی شده‌اند بلکه در لایه‌های جلوتر نیز ویژگی‌های بصری عمیقی شناسایی شده اند و مدلی بسیار مناسب برای این مسئله خواهد بود. بنابراین ما از این مدل به عنوان مدل پایه آموزش خود استفاده کردیم به صورتی که تنها لایه‌های کانولوشنی استفاده شده و از میان‌ آن‌ها ۵ لایه آخر را نیز از حالت فریز (freeze) خارج کردیم. در قسمت ساخت مدل بیشتر بخوانید.

جمع‌آوری داده

برای مسئله شش کلاس -شش مکان برای آموزش مدل- در نظر گرفته شد: دانشکده کامپیوتر، دانشکده معماری، سلف، بوفه، ساختمان امور فرهنگی و زمین ورزشی؛ برای جمع‌آوری داده از این مکان‌ها عکس و فیلم از تمامی زوایای ساختمان‌ها گرفته شد. همچنین سعی شد در زمان‌های متفاوتی عکس‌برداری انجام شود تا تصاویر از تنوع قابل قبولی در نور محیط برخوردار باشند. فریم‌های فیلم‌ها بعدا با استفاده از اسکریپت پایتونی زیر جدا شد تا نهایتا در هر کلاس (از هر مکان) ۸۰۰ عکس شامل ۵۰۰ عکس برای آموزش و ۳۰۰ عکس برای تست و مجموعا ۴۸۰۰ عکس تولید شود.

از این اسکریپت به صورت زیر استفاده می‌کنیم (با این فرض که کدهای بالا را در فایلی با نام frameExtractor.py ذخیره کرده اید)؛ پارامتر اول آدرس فایل ویدئو و پارامتر دوم عددی برای شروع نام‌گذاری تصاویر اسکریپت است برای مواقعی که فریم‌های چندین فایل ویدئو را می‌خواهیم جدا کنیم:

آماده‌سازی داده‌ها

از آنجایی که روش جمع‌آوری داده ما، جدا کردن فریم‌ از فیلم‌های گرفته شده بود، تصاویر نامربوط، برای نمونه از محیط اطراف ساختمان و یا تصاویر تار شده نیز در میان عکس‌ها وجود داشت. همچنین تصاویر با کیفیت ۲۱۶۰*۳۸۴۰ گرفته شده بودند و هر کدام تقریبا حجمی بیش از ۳ مگابایت داشتند که برای آموزش شبکه بسیار سنگین بوده و ویژگی‌های (features) بسیار زیادی تولید می‌کردند که برای برنامه خود تا این حد نیاز به جزئیات نداشتیم؛ همچنین عکس‌ها به صورت landscape جدا شده بودند و نیاز به چرخواندن (rotate) داشتند. برای همین، با استفاده از برنامه ImageMagick تصاویر را ۹۰ درجه چرخوانده و سپس همگی را به سایز ۱۹۲*۱۰۸ تبدیل کردیم تا مدل در حین سبک شدن از ویژگی‌های کافی برای آموزش برخوردار باشد.

برای آشنایی با Image Magick و نحوه انجام کار پست «کار با تصاویر توسط ImageMagick» را بخوانید.

در نهایت تصاویر در فولدرهای مربوطه Train و تست و زیرفولدرهایی با اسامی کلاس‌ها قرار داده شدند. این اسم فولدرها بعدا در آموزش مدل و استفاده از دیتا جنریتور (Data Generator) به عنوان اسامی کلاس‌های مدل تعریف می‌شوند. ساختار فولدربندی داده‌ها به صورت زیر شد:

 

ساخت مدل

همانطور که قبلا اشاره شد برای مسئله از Fine Tuning استفاده شد. مدل نهایی تشکیل شده است از لایه‌های کانولوشنی شبکه VGG16 Places365 که به عنوان مدل پایه استفاده شده است و ۵ لایه آخر آن از حالت حالت فریز (freeze) خارج شده و به دو لایه تماما متصل (Fully connected) با ۲۵۶ نود و ۲ نود که به ترتیب از Activation function های Relu (برای شناسایی nonlinearities) و Softmax (برای کد کردن نتیجه در ۶ کلاس) استفاده می‌کنند متصل شدند.

آموزش مدل

google colab

برای آموزش سریعتر مدل و استفاده از GPU که امکان استفاده آن در سیستم خودمان فعلا وجود نداشت، از سرویس گوگل کولب (Google Colab)‌ استفاده کردیم. برای همین منظور فایل‌های لازم برای آموزش مدل به گوگل درایو منتقل شدند -فایل‌ها آپلود شده و از طریق سرویس SavetoDrive به گوگل درایو منتقل شدند- سپس فایل‌ها را در نوت‌بوکی که در گوگل کولب ساخته بودیم وارد کردیم تا مدل را آموزش دهیم.

آموزش نحوه انتقال فایل از گوگل کولب به گوگل درایو را در پست «اتصال مستقیم سرویس کولب (Google Colab) به درایو (Google Drive) از طریق فایل سیستم FUSE» بخوانید.

برای آموزش مدل پس از تعریف ساختار مدل (که در قسمت ساخت مدل توضیح داده شد)، چون که تعداد داده‌ها زیاد بود از دیتا جنریتور (Data Generator) هایی برای خواندن تصاویر از فولدر‌های مربوطه استفاده شده و برای داده‌های آموزش (Train) از روش‌های افزایش داده (Data augmentation) استفاده شد. تصاویر در گروه‌های ۲۰ تایی به شبکه تغذیه (Feed) شده ( batch_size = 20 )، مقادیر steps_per_epoch  و validation_steps  با توجه به تعداد داده‌های Train و Test و تعداد عکس‌های هر گروه ( batch_size) محاسبه شده و با ۱۰ بار تکرار ( epochs = 10 ) شبکه آموزش دید.

بررسی مدل

برای بررسی مدل نمودارهای روند تغییر accuracy و loss در هر epoch چاپ شد تا از نبود over-fitting مطمئن شویم.

accuracy and loss Plots

به علاوه دقت مدل با پیش‌بینی تصاویری از مکان‌های آموزش دیده که مدل قبلا آن عکس‌ها را در دیتاست آموزش یا تست خود نداشته بررسی شد.

تصویر با استفاده از تابع load_img در سایز مورد استفاده مدل خوانده شده و سپس به آرایه تبدیل شده، آرایه تبدیل به آرایه تک بعدی شده و پیش پردازشی رو آن توسط تابع  preprocess_input انجام شده است. این تابع در فایل  places_utils که مدل پایه (VGG16 Places365در اختیار گذاشته موجود است.

ذخیره مدل

در نهایت برای استفاده‌های آتی، مدل را ذخیره کردیم.

 

کد آموزش مدل و نوت‌بوک استفاده شده برای آموزش مدل در گوگل کولب در ریپازیتوری در دسترس اند.

استفاده از مدل در عمل

اسکریپت پیش‌بینی

برای اینکه از مدل استفاده کنیم، برنامه‌ای لازم داشتیم تا تصویر را دریافت کرده و نتیجه پیش‌بینی را برگرداند. برای این منظور اسکریپت زیر نوشته شد:

اسکریپت در ریپازیتوری در دسترس است.

سرور پیش‌بینی

از آنجایی که برنامه بالا باید حتما به همراه عکسی که قرار است پیش‌بینی شود در یک سیستم باشند و درواقع به صورت لوکال اجرا می‌شود، محدود بوده و نیازهای استفاده عملی از مدل را فراهم نمی‌کند. برای همین با استفاده از میکروفریک ورک فلسک برنامه سرور زیر نوشته شد تا بتوان با آپلود عکس، نتیجه پیش‌بینی را دریافت کرد.

برای آشنایی با فلسک و نحوه ایجاد یک برنامه سرور پست «آموزش مقدماتی فلسک (Flask)»‌ را بخوانید.

سه endpoint برای کار با مدل تعریف شدند؛  upload/  برای آپلود عکس (عکس را به صورت base64 دریافت کرده و آن را ذخیره می‌کند)، imagetopredict/  دریافت آخرین عکسی که برای پیش‌بینی فرستاده شده و  predictagain/  برای پیش‌بینی دوباره آخرین عکس آپلود شده. سپس، این برنامه روی سرور دپلوی شده و مدل آماده استفاده عملی شد.

کد برنامه سرور در ریپازیتوری در دسترس است.

برای آشنایی با نحوه دپلوی مدل پست «دپلوی کردن و استفاده از مدل در عمل (Model deployment)» را بخوانید (ما از روش سوم استفاده کردیم).

اپلیکیشن اندروید

حال که سروری داشتیم که با فرستادن عکس می‌توانستیم نتیجه پیش‌بینی را دریافت کنیم، میخواستیم از هر جایی امکان فرستادن عکس را داشته باشیم؛ برای این منظور با استفاده از فریم‌ورک Nativescript-Vue که ترکیب فریم‌ورک‌های Nativescript که برای ساخت اپلیکیشن‌های اندروید و ios با استفاده از زبان جاوااسکریپت (javascript) است و Vue که یک فریم‌ورک جاوااسکریپتی برای ساخت Progressive Web App هاست، اپلیکیشن اندرویدی برای پیش‌بینی تصاویر توسط مدل و با اتصال به سرور تولید شد.

کد اپلیکیشن در ریپازیتوری در دسترس است.

فوتر سایت

اسلایدر سایدبار

درباره ما

درباره ما

ما گروهی از دانشجویان رشته کامپیوتر دانشگاه شهید رجایی هستیم که به راهنمایی و تدریس استاد علی‌رضا اخوان‌پور به دنیای یادگیری عمیق پا گذاشتیم و دوست داریم چیزهایی که در این مسیر یادمی‌گیریم رو به اشتراک بذاریم.

شبکه های اجتماعی