پردازش اشیاء بصری با مدل‌های مولد

مقدمه

سامانه بینایی انسان محرک های ورودی خود را با دقت و سرعت بالایی پردازش می کند. نشان داده شده است که پیچیدگی های موجود در محرک های بصری  از جمله زاویه دید، شدت روشنایی محیط، میزان آشنایی و …  باعث افزایش زمان پردازش می شود. این زمان پردازش بیشتر ناشی از بار محاسباتی بیشتر است و فرضیه های گوناگونی برای توجیه این پدیده وجود دارد. یکی از مهمترین فرضیه ها پردازش های بازگشتی و وجود فیدبک ها است و از دیگر فرضیه‌ها میتوان به وجود مدل‌هایی برای بازسازی تصاویر اشاره کرد.

ادامه خواندن پردازش اشیاء بصری با مدل‌های مولد

مقدمه ای بر شبکه‌های مولد تخاصمی (Generative Adversarial Networks)

یادگیری بدون نظارت (Unsupervised Learning)
همان‌طور که پیش‌تر بحث شده بود، یکی از حوزه های یادگیری ماشین، یادگیری بدون نظارت است که در آن داده‌ها برچسب ندارند. در یادگیری بدون نظارت هدف اصلی، یادگیری ساختار داده‌ها می‌باشد.

 

ادامه خواندن مقدمه ای بر شبکه‌های مولد تخاصمی (Generative Adversarial Networks)

معرفی BERT، تحولی در NLP

زمانی که برای اولین بار یک شبکه کانولوشنی در مسابقه Image Net برنده شد، توجه همگان به مبحث یادگیری ماشین و در ادامه یادگیری عمیق جلب شد. دیگر همگان راه حل تمام مشکل ها را در این زمینه جست جو می‌کردند؛ ولی فراموش می‌کردند که مسابقه Image Net دیتای عظیمی در اختیار شرکت کنندگان قرار می‌دهد و برگ برنده شبکه های عمیق نیز همین دیتای زیاد است. در صورتی که برای خیلی از مشکلات این حجم از اطلاعات در دسترس نیست.

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

این جا بود که استفاده از مدل های pre-trained به کمک افرادی آمد که از دیتا و قدرت پردازشی محدودی برخوردار بودند. شبکه هایی که با دیتای مسابقه Image Netآموزش داده شده اند، در اختیار همه قرار دارد و دیگر نیازی نیست که تمام مسیر را از اول طی کنیم. کافیست که یک شبکه را بر داریم و با استفاده از دو روش feature extraction و fine-tuning برای کار خودمان اختصاصی کنیم.

ولی اگر مسأله ما به تصویر مربوط نباشد چه؟ دیتای به این عظیمی برای متن را از کجا بیاوریم؟ چگونه شبکه را آموزش دهیم؟

برای استفاده از مدل های pre-trained در مسائلی که با متن سر و کار دارند، ابتدا به سراغ word embedding ها رفتیم. به ما کمک کردند و تغییر محسوسی در دقت شبکه ها ایجاد کردند. ولی اصلا عمیق نبودند و حاوی اطلاعات کمی بودند. کمک آن ها موثر ولی محدود بود.

در سال ۲۰۱۸ این مسیر برای مسأله های متنی یا به طور دقیق‌تر NLP نیز در دسترس قرار گرفت. شبکه بزرگی با دیتای زیاد (Wikipedia + BookCorpus) توسط مهندسان گوگل آموزش داده شد و در دسترس همه قرار گرفت. حالا یک شبکه بسیار قدرتمند برای بهره گیری در مسائل متنی در اختیار داریم. این شبکه Bidirectional Encoder Representations from Transformers یا BERT نام دارد. ادامه خواندن معرفی BERT، تحولی در NLP

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

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

مقدمه

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 هاست، اپلیکیشن اندرویدی برای پیش‌بینی تصاویر توسط مدل و با اتصال به سرور تولید شد.

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

معرفی تعدادی از معماری‌های شبکه های کانولوشنالی معروف

در این قسمت می خواهیم به معرفی تعدادی از شبکه های نورونی کانولوشنالی (CNN) معروف بپردازیم. این شبکه ها از آن جهت معروفند که امروزه بسیاری از افراد در مقالات یا پروژه های خود از آن ها استفاده می کنند و هم چنین در زمان معرفی شدنشان توانستند جایزه ی ImageNet که یکی از معتبر ترین جوایز در این زمینه است را برنده شوند.

ImageNet

این مسابقه از سال 2010 هر ساله برگزار می‌شود. هدف آن دسته تشخیص و دسته بندی تصاویر در مقیاس وسیع است. شبکه های شرکت کننده، باید تصاویری با 1000 کلاس متفاوت را از هم تمیز دهند. معیار اندازه گیری دقت شبکه ها، خطای 5 کلاس برتر است. به صورتی که شبکه با دیدن تصویر، ۵ کلاس معرفی می‌کند. در صورتی که کلاس مورد نظر در میان آن ها بود، جواب شبکه پذیرفته می‌شود.

۱- LeNet-5

اولین شبکه ی کانولوشنالی که بسیار مطرح شد شبکه ی LeNet-5 بود که در مقاله ی”Gradient-based learning applied to document recognition ” نوشته شده توسط LeCun, Bottou, Bengio, Haffner و در سال 1998 ارائه شد. نام شبکه نیز از نام Yann Lecun یکی از نویسندگان این مقاله برداشته شده است. این شبکه را می توان به عنوان اولین شبکه که فیلتر های کانولوشنالی در آن استفاده شده است نام برد. هدف این شبکه، خواندن کد پستی از پشت بسته های پستی بود.

شکل بالا شبکه ی Lenet را نمایش می دهد. این شبکه در ابتدا یک ورودی 32*32 دریافت می کند و سپس از 6 فیلتر کانولوشنالی 5*5 که گام(stride) آن برابر 1 است عبور می کند. حاصل یک تنسر 6*28*28 است. سپس از فیلتر subsampling که در این جا فیلتر AveragePool 2*2 با گام 2 است عبور می کند. این فیلتر موجب می شود که طول و عرض آرایه نصف شود اما عمق آن تغییری نمی کند در نتیجه به آرایه ی 6*14*14 می رسیم. این بار از 16 فیلتر کانولوشنالی 5*5 با گام 1 عبور می دهیم که حاصل 16*10*10 است. دوباره از یک AveragePool مانند قبل عبور می دهیم که حاصل 16*5*5 میشود. و در انتها نیز از دو لایه ی Fully connected عبور داده می شوند.

۲- AlexNet

دومین شبکه ی نورونی کانولوشنالی مهمی که می توان نام برد شبکه ی AlexNet است که توسط Alex Krizhevsky و حدود چهارده سال بعد از LeNet یعنی در سال 2012 معرفی شد. این شبکه دارای 8 لایه (پنج لایه ی کانولوشنالی و سه لایه fully connected) است که موجب شده در دسته ی شبکه های کم عمق (Shallow) قرار گیرد.

شکل بالا شبکه ی AlexNet را نمایش می دهد.(دلیل این که لایه ها دوطبقه ای هستند، استفادهاز دو GPU برای پردازش آن است) درشکل ورودی شبکه یک عکس 3*224*224 است اما ورودی درست 3*227*227 است! در ابتدا 96 فیلتر کانولوشنالی 11*11 همراه با 4 گام و padding=0 اعمال می شود. خروجی آرایه ی 96*55*55 است.(تعداد پارامتر های هر لایه ی کانولوشنالی برابر است با : طول لایه * عرض لایه * عمق ورودی * تعداد فیلتر ها (به طور مثال در اینجا برابر است با 11*11*3*96))در مرحله ی بعد از لایه ی maxpool 3*3 با اندازه ی گام 2 عبور داده می شود که خروجی 96*27*27 می شود.(تعداد پارامتر های قابل یادگیری در maxpool صفراست.) در مرحله بعد از 256 فیلتر کانولوشنالی 5*5 با گام یک و padding=2 عبور می دهیم که خروجی 256*27*27 است. در مرحله ی بعد نیز دوباره از فیلتر maxpool 3*3 با گام 2 عبور می دهیم که خروجی 13*13*96 است. در سه مرحله ی بعد از فیلتر های کانولوشنالی با گام و padding یک استفاده می کنیم که تعداد آن ها به ترتیب 384 ، 384 ، 256 است که خروجی نهایتا 256*13*13 می شود. سپس از یک لایه ی maxpool 3*3 با گام یک عبور می دهیم و خروجی آن 256*6*6 می شود. در آخر نیز سه لایه ی fullyconected قرار دارد. دو لایه 4096 تایی و یک لایه 1000 تایی با اکتیویشن softmax برای تعیین کلاس های موجود در مساله. (به طور مثال اگر قصد انتخاب بین سه کلاس سگ، گربه، موش را داشته باشیم اندازه لایه ی آخر را سه در نظر می گیریم.)

ورودی

نوع فیلتر

تعداد

اندازه

گام

حاشیه

خروجی

3*227*227

Conv

96

11*11

4

0

96*55*55

96*55*55

maxpool

1

3*3

2

96*27*27

96*27*27

conv

256

5*5

1

2

256*27*27

256*27*27

Maxpool

1

3*3

2

256*13*13

256*13*13

Conv

384

3*3

1

1

384*13*13

384*13*13

Conv

384

3*3

1

1

384*13*13

384*13*13

Conv

256

3*3

1

1

256*13*13

256*13*13

Maxpool

1

3*3

2

256*6*6

9216

Fullyconected

4096

4096

Fullyconected

4096

4096

Fullyconected

1000

نکات مهم :

• تابع relu برای اولین بار معرفی و استفاده شد.
• بعد از دو لایه ی maxpool اول از نرمال ساز استفاده شده بود که دیگر مورد استفاده قرار نمی‌گیرد.
• برای اولین بار از dropout استفاده شده.
• اندازه ی batch در آن 128 است.
• میزان خطای آن در مسابقه ی imagenet برای خطای 5 کلاس برتر ، مقدار 15.4% بود که حدود سه درصد نسبت به سال گذشته بهبود داشت.

۳- ZFNet

نویسنده های این شبکه، Matthew Zeiler و Rob Fergus بودند که نام شبکه نیز از آن ها گرفته شده.این شبکه از ایده زیادی برخوردار نیست و مهم ترین ایده آن ، قسمت Visualization آن است. ابزاری که با استفاده از آن، کاربرد هر نورون در شبکه تا حدی مشخص می‌شود و به درک شبکه های کانولوشنالی کمک بزرگی کرد. در این ابزار می‌توان دید که در لایه های نخست، شبکه خطوط و لبه های ساده را تشخیص می‌دهد و در لایه های بعد نورون ها مفاهیم پیچیده تری مانند صورت انسان یا نوشته را تشخیص می‌دهند. بعضی از نورون ها برای ما قابل فهم نیستند. ولی معلوم شده حذف آن ها هم تاثیری مانند حذف دیگر نورون ها در عملکرد نهایی شبکه دارد.
این شبکه همان شبکه AlexNet است با این تفاوت که در لایه اول، به جای (11*11 stride4)، از (7*7 stride2) استفاده شده است(چون سایز فیلتر در AlexNet بزرگ گرفته شده بود و stride آن زیاد بود.) و در لایه های 3، 4 و 5 به ترتیب به جای 384 ، 384 و 256 فیلتر، از 1024، 512 و512 فیلتر استفاده شده است.

نکات مهم:

• ZFNet، در مسابقه ImageNet خطای ۵ کلاس برتر را به 14.8% کاهش داد و همین باعث شد تا برنده Challenge ImageNet سال 2013 شود.
• ارائه ابزار Visualization

۴- VGG

این شبکه، به دلیل این که تعداد HyperParameter ها را کاهش داده، پیچیدگی کمتری نسبت به AlexNet و ZFNet دارد و به دلیل همین سادگی، از محبوبیت بالایی برخوردار است.
در VGG در هر جا:
CONV به معنی فیلتر 3*3 با stride 3 و same است.
و POOL به معنی پولینگ 2*2، با stride 2 است.
سایز تصویر ورودی 3*224*224 است. سپس دو بار CONV با عمق 64 روی آن اعمال می شود.(با CONV اول، تصویر 64*224*224 می شود و با CONV دوم دوباره 64*224*224 می شود.) سپس POOL روی آن اعمال می شود وتصویر 64*112*112 می شود.(پولینگ روی عمق تاثیر نمی گذارد.) بقیه مراحل در شکل زیر قابل مشاهده هستند:

در مقاله VGG، که در سال 2015 ارائه شد، چند مدل مختلف تست شده اند و مدلی دارای 16 لایه تحت عنوان VGG-16 بیش ترین کارایی را داشته است.

نکات مهم:

• در این معماری، به ازای هر تصویر، 93MB حافظه اشغال می شود.
• 138 میلیون پارامتر قابل یادگیری دارد.
• در سال 2014، خطای ۵ کلاس برتر مسابقه ImageNet را به 7.3% بهبود بخشیده است. با این حال این شبکه برنده نشد.

۵- GoogLeNet (Inception)

این شبکه توسط Google در سال 2014 ارائه شد. نام آن ادای احترامی به Yann Lecun، سازنده LeNet، اولین شبکه کانولوشنالی، است. این شبکه با ایده عمیق تر کردن شبکه های کانولوشنالی که طبق گفته سازنده، برگرفته از دیالوگی در فیلم Inception است! برای همین به این نام نیز شناخته می‌شود.

در این شبکه با این رویکرد که هایپر پارامتر های شبکه را هم به گونه ای به پارامتر قابل یادگیری تبدیل کنند، ماژولی به نام Inception module طراحی شد.

در این ماژول، ۳ فیلتر کانولوشنالی با اندازه های متفاوت و یک فیلتر پولینگ روی لایه قبلی اجرا شده و نتایج را به صورت یک تنسر واحد کنار هم می‌گذارد. در این صورت شبکه می‌تواند در لایه بعدی تصمیم بگیرد که از نتیجه کدام فیلتر و به چه اندازه می‌خواهد استفاده کند. سایز فیلتر های کانولوشنالی به صورتی که در تصویر مشخص است، 1*1, 3*3 و 5*5 است و فیلتر پولینگ با سایز 3*3 روی آن اجرا شده.


در این شبکه با قرار دادن دو لایه ی پولینگ در ابتدای کار، پارامتر های قابل یادگیری مساله را بسیار کاهش داده اند. در ادامه از ۹ لایه یInception module استفاده شده. جزئیات بیشتر در تصویر زیر مشخص است.
در تصویر بالا بلاک های آبی نشان دهنده لایه کانولوشنالی، قرمز نشان دهنده پولینگ، زرد سافت مکس و سبز کنار هم گذاشتن خروجی های قبلی است.

نکات مهم:

• معرفی ایده جدید Inception module
• داشتن تنها ۵ میلیون پارامتر قابل یادگیری. این تعداد نسبت به شبکه های AlexNet و VGG به ترتیب ۱۲ و ۳۶ برابر کمتر است.
• این شبکه در سال2014 با کاهش میزان خطای ۵ کلاس برتر در مسابقه ImageNet به 6.7% برنده شد.

۶- Microsoft ResNet

این شبکه توسط Microsoft ارائه شد که نام آن مخفف Residual Network است. در این شبکه ارتباطاتی خارج از ساختار کانولوشنالی در کنار آن بین لایه ها در نظر گرفته شده تا ورودی های لایه قبلی را بدون واسطه به لایه بعدی منتقل کند و در مرحله back propagation یا اصلاح شبکه، ارور هر لایه را به لایه قبلی انتقال دهد تا بتوان شبکه را عمیق تر کرد و آن را سریع تر آموزش داد. به این ارتباطات skip connections و به ساختار حاصل از آن Residual block می‌گویند.

با این ترفند توانستند شبکه ای با عمق ۱۵۲ لایه را آموزش دهند که اختلاف زیادی با شبکه های قبلی داشت.

نکات مهم:

• معرفی مفهوم جدید skip connections و residual block.
• عمیق کردن قابل توجه شبکه.
• این شبکه در سال 2015 در مسابقه ImageNet میزان خطای ۵ کلاس برتر را به 3.6% کاهش داد.

خلاصه

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

برای مطالعه بیشتر

LeNet

AlexNet

ZF Net

VGG Net

GoogLeNet

Microsoft ResNet

منابع

ImageNet

CNNs Architectures: LeNet, AlexNet, VGG, GoogLeNet, ResNet and more …

We Need to Go Deeper: A Practical Guide to Tensorflow and Inception

An Overview of ResNet and its Variants

آموزش یک شبکه عصبی کانولوشنالی از ابتدا در Kears

مجموعه داده

مجموعه داده گربه در مقابل سگ برای این مثال استفاده شده است. این مجموعه داده در چالش بینایی کامپیوتر اواخر سال ۲۰۱۳ توسط سایت Kaggle.com در دسترس عموم قرار گرفت. مجموعه داده اصلی دارای ۲۵۰۰۰ تصویر (۱۲۵۰۰ از هر کلاس) است که می‌توانید آن را از اینجا دریافت کنید.

ما بعد از دانلود تصاویر، آن ها را در ساختار جدیدی مرتب کردیم. ۱۰۰۰ عکس برای آموزش، ۵۰۰ عکس برای ارزیابی و ۵۰۰ عکس برای آزمون از هر کلاس (گربه و سگ) جدا کردیم. این فرایند توسط کد زیر انجام شده و تصاویر مرتب شده از اینجا در دسترس است.

برای بررسی صحت انجام کار، تعداد تصاویر آموزشی، ارزیابی و آزمون را بررسی میکنیم.

تعریف معماری مدل (model architecture)

ما از یک مدل کانولوشنالی برای حل این مساله استفاده می‌کنیم. از قبل از سال ۲۰۱۳ استفاده از شبکه های کانولوشنالی خیلی رایج نبود ولی بعد از آن تقریبا در همه مدل های بینایی ماشین با روش یادگیری عمیق، از این شبکه ها استفاده می‌شود.شبکه ما از ۴ لایه ی کانولوشنالی و پولینگ بعد از هر کدام، یک لایه متراکم (Dense) پنهان و یک لایه متراکم برای لایه خروجی که دارای یک نورون است استفاده می‌کنیم.تابع فعال سازی لایه آخر sigmoid است. در پیاده سازی مدل برای تشخیص اعداد دست نویس دیتاست هدی، ما در لایه آخر از تابع softmax استفاده کردیم. با تابع softmax خروجی نورون های لایه آخر به صورتی می‌شود که مقدار هر کدام عددی بین ۰ و ۱ است و مجموع همه برابر یک خواهد بود. این تابع برای لایه آخر مسائل طبقه بندی به کار می‌رود.در این مسال مابه جای استفاده از دو نورون با تابع softmax از یک نورون با تابع sigmoid استفاده می‌کنیم. این تابع عددی بین ۰ و ۱ برمی‌گرداند. چون تنها دو کلاس داریم، مقدار یکی از نورون ها برابر اختلاف دیگری با عدد ۱ است. پس می‌توانیم عدد ۰ را متناظر با یکی از کلاس ها (مثلا گربه)‌ و عدد ۱ را متناظر با کلاس دیگر (سگ) قرار دهیم. در این صورت به جای دو نورون در لایه خروجی، با یک نورون همان کار را انجام می‌دهیم.

نگاهی به ابعاد و تعداد اطلاعات در هر یک از لایه های شبکه می‌اندازیم.نگاهی به ابعاد و تعداد اطلاعات در هر یک از لایه های شبکه می‌اندازیم.

چون این مساله تنها دو کلاس داریم، از تابع binary_crossentropy برای محاسبه میزان خطا استفاده می‌کنیم. با توجه به اینکه تعداد تصاویر یکسانی از سگ و گربه برداشته ایم معیار Accuracy معیارمناسبی برای ارزیابی خواهد بود.

پیش پردازش داده (Data preprocessing)

مراحل آماده سازی تصاویر برای شروع عملیات یادگیری:

  1. خواندن تصویر
  2. تبدیل فرمت jpeg به پیکسل های RGB
  3. تبدیل آن به tensor (آرایه چند بعدی) از اعداد حقیقی
  4. نرمال کردن اعداد (تبدیل بازه ۰ تا ۲۵۵ به بازه ۰ تا ۱)

به لطف ابزار های کتابخانه کراس، تمام این مراحل به راحتی انجام می‌شود. کافی است کلاس ImageDataGenerator را از keras.preprocessing.image ایمپورت کرده، آدرس فولدر ها، ابعاد تصاویر ورودی، نوع طبقه بندی و اندازه batch را مشخص کنیم و از کلاس های ایجاد شده برای یادگیری و ارزیابی مدل استفاده کنیم.

اطلاعات بیشتر در مستندات Keras :

https://keras.io/preprocessing/image/

اگر بخواهیم نگاهی به خروجی کلاس های generator بیاندازیم خواهیم دید در هر گام پیمایش، آن ها یک دسته(batch) از تصاویر رنگی ۱۵۰ در ۱۵۰ پیکسل (3, 150, 150, 20) و به تعداد تصاویر، عنوان آن ها را (۰ برای گربه و ۱ برای سگ) برمی‌گرداند. با ادامه پیمایش این روند به تعداد نامحدود تکرار می‌شود.

 

آموزش مدل (fitting model)

حالا نوبت آموزش مدل می‌شود. برای این کار به جای تابع fit از تابع fit_generator استفاده می‌کنیم که همان  کار را انجام می‌دهد ولی با generator ها کار می‌کند. این تابع برای اولی ورودی یک generator مانند آنچه  ساختیم می‌گیرد و با آن مدل را تغذیه می‌کند. چون generator ها بدون اطلاع از تعداد تصاویر، مدام  خروجی ها را برمی‌گردانند، باید به گونه ای تعداد گام های پیمایش را به ازای هر دوره(epoch) مشخص کنیم. پس علاوه بر generator باید مقدار ورودی steps_per_epoch را هم به تابع بدهیم. چون تعداد تصاویر ۲۰۰۰ تا و اندازه هر تکه ۲۰ است، ما برای هر دوره به ۱۰۰۰ گام برای پیمایش نیاز داریم.

مقدار validation_steps با توجه به نسبت تصاویر آموزشی و ارزیابی مشخص می‌شود. چون در این مساله  ما ۱۰۰۰ عکس آموزشی و ۵۰۰ عکس برای ارزیابی داریم، به ازای هر دو گام آموزش، یک بار ارزیابی مدل  صورت می‌گیرد. پس تعداد گام های ارزیابی در هر دوره، نصف گام های آموزش است. پس این مقدار را برابر  ۵۰ قرار می‌دهیم.

حالا نمودار میزان خطا و میزان دقت را در طول آموزش رسم می‌کنیم.

این تصاویر نشان دهنده وقوع overfitting است. دقت اطلاعات آموزشی ما به نزدیک ۱۰۰٪ رسیده ولی دقت  اطلاعات ارزیابی بعد از ۵ دوره به حدود ۷۰٪ رسیده و بعد از آن تغییری نکرده. چون تعداد تصاویر ما کم است  و شبکه اطلاعات را حفظ کرده و قدرت عمومیت بخشی ندارد.

شبکه با Dropout

برای جلوگیری از این اتفاق روش Dropout را امتحان می‌کنیم.

حالا دوباره نمودار های دقت و خطا را بررسی می‌کنیم.

همان طور که تصاویر مشخص است این روش تاثیر اندکی روی سیستم گذاشته و شبکه را کمی بهبود داده  ولی هنوز هم مشکل overfitting برطرف نشده. برای مقابله با این مشکل باید از روش data augmentation  استفاده کنیم که در آینده با آن آشنا خواهیم شد.

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

 

کدها برگرفته از فصل دو کتاب Deep Learning with Python و گیت هاب نویسنده کتاب و توسعه دهنده  کراس François Chollet است.

بررسی مقدماتی شبکه های کانولوشنالی


یکی از وظایف پایه در مبحث بینایی ماشین Image Classification می باشد. در ادامه با چالش های عکس در این زمینه آشنا می شوید.

Semantic gap : همان گسستگی میان پیکسل ها که حاوی این نکته است که ما فقفط بخشی از تصویر واقعی را در اختیار داریم.

viewpoint variation : یکی دیگر از چالش ها، اختلاف بین زاویه های مختلف یک شیء می باشد.

Illumination : نورپردازی های مختف کار تشخیص شیء را دچار چالش می کند.

Deformation : حالت های مختلف یک شیء و تغییر حالت آن از دیگر مشکلات این فیلد می باشد.

Occlusion : ناقص بودن یک شیء ممکن است مدل را برای تشخیص دچار مشکل کند.

Background clutter : هم شکلی با محیط کار تشخیص شیء از محیط را دشوار تر می کند.

Intraclass variation : تنوع یک دسته شیء هم از دیگر چالش های این حوزه محسوب می شود.

یکی از مشکلات تشخیص شیء عدم وجود هیچ الگوریتم مشخصی برای شناسایی شکل است، این فرآیند از همچین الگویی ثابت پیروی نمی کند.

 

محوریت ساخت مدل:

  • Collect a dataset of images and labels (جمع آوری عکس ها و لیبل ها)
  • Use Machine Learning to train an image classifier (آموزش مدل)
  • Evaluate the classifier on a withheld set of test images (ارزیابی مدل)

یک مدل ساده بر روی دیتاست هدی

طبقه بند چند لایه softmax

 

تعیین تابع هزینه و روش بهینه سازی

 

تعیین داده‌های آموزشی، سایز mini-batch و تعداد epoch

 

نکته : مدل ساخته شده بعد از مدتی (چندبار دیدن عکس ها) شروع به حفظ دیتاست و ساخت توابع پیچیده میکند که باعث ایجاد مشکلی به نام overfitting می شود.


شبکه های کانولوشنی

تا قبل از سال 2012 تصور بر این بود که تعداد لایه های درونی را نباید بیش از 2 تا نشود که میزان خطا بالاتر تر نرود این بدلیل استفاده از تابع activation ناکارآمد sigmoid بود که با معرفی و استفاده از تابع ReLu و بالاتر رفتن تعداد لایه ها میزان خطا کمتر شد.

ایده ایجاد شبکه های کانولوشنی

در ماشین لرنینگ سنتی زمانی که از فیلتر ها استفاده می کردند با این چالش روبرو بودند که از چه فیلتری و با چه مقادیری استفاده کنند (مثلا کدام فیلتر لبه یاب بهتر است) تا این که این ایده ایجاد شد که خود مدل ، این فیلتر را طراحی کند. در شبکه های کانوولوشنی مقادیر این فیلتر ها را نیز بر عهده ی خود شبکه گذاشتند تا train شود.

Padding

لبه ها به اندازه پیکسل های درونی در کانولوشن شرکت نمی کنند درنتیجه خروجی کوچک می شود ( اگر تعداد لایه های کانولوشنی زیاد باشد حجم زیادی از دیتا از بین میرود )

با اضافه کردن مقادیری در اطراف عکس ورودی سعی در شرکت بیشتر لبه ها در این عمل داریم که به آن padding می گویند.

اگر در اطراف عکس مقدار 0 گذاشته شود zero-padding انجام داده ایم.

 

انواع کانولوشن

Valid : اگر از سایز ورودی با سایز خروجی برابر نباشد در حقیقت کانولوشن valid انجام داده ایم (اگر ورودی n*n و سایز فیلتر f*f باشد خروجی (n-f+1)*( n-f+1) می شود

Same : اگر به مقداری padding بدهیم که سایز ورودی با سایز خروجی یکی شود کاولوشن same خواهد بود) اگر ورودی n*n و سایز فیلتر f*f باشد و به اندازه p واحد padding بدهیم خروجی (n+2p-f+1)*( n+2p-f+1)  یا همان n*n می شود.

* نکته: برای اینکه کانولوشن same شود باید به اندازه 2/(f-1) به عکس ورودی padding بدهیم

* نکته: سایز فیلتر باید فرد در فرد باشد

Stride : مقدار جابجایی فیلتر به صورت افقی (چندتا چندتا جلو بره)

نکته : اگر ورودی n*n و سایز فیلتر f*f باشد و به اندازه p واحد padding بدهیم و stride s داشته باشیم خروجی

[( n+2p-f)/s+1]*[( n+2p-f)/s+1]   می شود(اگر عدد رند نشد به سمت پایین گرد میکنیم)

parameter : پارامتری که در فرایند training مشخص می شود و تابع cost بر اساس آن بهینه می شود ( مانند وزن های شبکه)

Hyper parameter : پارامتری که با فرآیند training بدست نمی آید ( مانند k در k nearest neighbor، مقدار stride)

 

کانولوشن چند بعدی

در این نوع کانولوشن باید بعد هم عمق با ورودی باشد یعنی اگر ورودی 6*6*3(یک عکس RGB 6*6) باشد، فیلتر میتواند 3*3*3 باشد.

 

 

* نکته: در این مثال از یک فیلتر استفاده کردیم پس بعد سوم خروجی 1 است یعنی خروجی 1*4*4 است (بعد خروجی = تعداد فیلتر استفاده شده)

* نکته: مقادیر مرکزی کانولوشن هر بعد با هم جمع می شود و bias نیز به آن اضافه می شود

** مثال: با 10 فیلتر 3*3*3 تعداد پارامتر آن لایه چقدر می شود؟   ((3*3*3)+1)*10 = 280

 

** مثال:


در شبکه های عصبی کانولوشنالی از لایه های conv  و pool  به شکل زیر استفاده میکنیم :

همان طور که مشاهده می کنید قبل از اولین لایه Dense یا fully connected همیشه از متد flatten استفاده میشود تا نرون ها به صورت یک وکتور در بیایند.

در لایه آخر نیز اگر خروجی مدل ما باینری باشد میتوان از activation=sigmoidاستفاده کرد اما اگر خروجی مدل چند حالت مختلف باشد مثل مدل بالا که برای هدی هست و 10 تا خروجی دارد از softmax استفاده شده.

به ورودی و خروجی هر لایه نیز تنسور گفته می شود.

تصاویر مجموعه داده هدی در تابعی که قبلا نوشته ایم، load_hoda به صورت flat شده و یک وکتور در آمده اند.
در این فراخوانی طول و عرض تصاویر 28 قرار داده شده است، پس خروجی این تابع وکتورهای 784 تایی است.
دقت کنید که قبل از ورودی شبکه کانولوشنالی تصویر را به شکل اصلی خود یعنی 28×28 برگردانده ایم.
همچنین چون تصاویر سیاه و سفید است تعداد کانال تصویر را 1 قرار داده ایم.

 

با دستور ()model.summary ورودی و خروجی هر لایه را میبینیم :

همانطور که مشاهده میکنید با هر بار conv گرفتن پارامتر های جدیدی به دست می آید که میتوانند با تابع cost بهینه شوند.

لایه dropout هم هر بار تعدادی از نرون ها را میکشد برای جلوگیری از پدیده overfitting .

و با هر بار pooling همان طور که مشاهده میکنید پارامتری برای آموزش نمی دهد و تنها دو هایپر پارامتر s و f دارد و تنها ابعاد داده را کوچکتر میکند با ازبین بردن برخی جزییات از طرق ماکسیمم گیری،میانگین گیری و ….