تشخیص اشیا در تصویر با YOLO object detection

Object detection یا تشخیص شی در تصویر چیست ؟

تشخیص اشیا یک فناوری کامپیوتری است که در ارتباط با کامپیوتر ویژن و پردازش تصویر است که با شناسایی نمونه هایی از اشیاء معنایی یک کلاس خاص (مانند انسان ها، ساختمان ها و اتومبیل ها) در تصاویر و فیلم های دیجیتال مورد بررسی قرار می گیرد.

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

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

وظایف اصلی بینایی ماشین را می‌توان به موارد زیر تقسیم کرد:

  • شناسایی یا دسته‌بندی شیء: در شناسایی شیء، یک تصویر خام را تحویل می‌گیرید و باید تشخیص دهید که مربوط به کدام دسته می‌شود.
  • دسته‌بندی و مکان‌شناسی: در این حالت شما یک تصویر دارید که فقط یک شیء در آن وجود دارد و باید جای آن شیء را پیدا کنید. به این کار «مساله‌ مکان‌شناسی» نیز می‌گویند.
  • پیداکردن شیء: در این حالت شما باید موقعیت شیء در تصویر را پیدا کنید. این اشیا می‌توانند از کلاس‌های متفاوت باشند.
  • تقسیم‌بندی تصویر: تقسیم‌بندی تصویر وظیفه‌ سنگین‌تری است. در این حالت باید تمام پیکسل‌ها را بر اساس دسته‌ درست آن پیدا کنید.

 

روش ها و الگوریتم های موجود :

1 – روش های اولیه و سنتی :

در این روش ها مسئله را با رویکرد های ساده تری انجام میدهند. بعنوان مثال ابتدا تصویر را به یک شبکه سگمنتیشن داده و با روش های موجود به سگمنت کردن اشیا موجود در تصویر پرداخته و پس از مشخص شدن محدوده اشیا در تصویر هر کدام را جداگانه به یک شبکه دسته بند میدهیم تا کلاس آن نیز مشخص شود.
این روش ها زمان بر بوده و عملا برای تشخیص اشیا به صورت real time کارآمد نیستند. برای مثال روش selective search

بعد از مدت ها و برای بهبود عملکرد این روش ها ایده هایی برای نحوه سگمنت کردن و در نهایت تشخیص اشیا مطرح شد که از جمله آنها میتوان روش roi pooling را نامبرد. که برای سگمت کردن تصویر ورودی از لایه ای کانولوشنالی شبکه های عمیق بهره میبردند. زیرا روش های قبلی با استفاده از محاسبه میزان تفاوت بین پیکسل های تصویر و تمایز قائل شدن بین آنها انجام میشد که دیگر منسوخ شدند.

2 – روش های مدرن و پیشرفته :

در این الگوریتم ها ایده هایی برای این مسئله مطرح شد که سعی بر این داشتند تا ماشین تصویر ورودی را فقط یک بار دیده و با استفاده از ترکیب شبکه های عمیق کانولوشنالی و تمام متصل به صورت موازی فیچر های لازم از تصویر استخراج شده و درنهایت به دسته بندی پرداخته شود تا از لحاظ دقت و سرعت پیشرفت بسیاری داشته باشد.

از جمله این روش ها و الگوریتم ها میتوان روش YOLO و SSD را نامبرد.

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

 

YOLO : You Only Look Once

کامل‌ترین سیستم‌ بلادرنگ (Real time) در یادگیری عمیق و حل مسائل تشخیص تصویر است. همان‌طور که در تصویر زیر مشاهده می‌کنید، این الگوریتم ابتدا تصویر را به بخش‌های مختلف تقسیم می‌کند و هر بخش را علامت‌گذاری می‌کند، سپس الگوریتم شناسایی را به صورت موازی برای تمامی این بخش‌ها اجرا می‌کند تا ببیند هر بخش به کدام دسته‌بندی تعلق می‌گیرد. بعد از شناسایی کامل اشیا، آن‌ها را به هم متصل می‌کند تا دو هر شیء اصلی یک جعبه باشد.

همه‌ این کارها به صورت موازی انجام می‌شوند؛ در نتیجه به صورت بلادرنگ است و می‌تواند تا 40 تصویر را در یک ثانیه پردازش کند. با اینکه این مدل کمی نسبت به RCNN عملکرد ضعیف‌تری دارد، ولی به دلیل بلادرنگ بودن آن، می‌توان از آن برای حل مشکلات روزانه استفاده کرد. در زیر تصویری از معماری YOLO را مشاهده می‌کنید.

نحوه تشخیص شی در تصویر توسط الگوریتم yolo :

در شبکه ی YOLO تصاویر به صورت فرضی به N در N ناحیه تقسیم می شوند. به ازای هر کدام از این نواحی فرض می شود که K شی امکان حضور دارند. شبکه به صورتی طراحی شده است که در نهایت به ازای تمامی نواحی امکان وجود اشیا در آن ناحیه ها – دسته ی آن شی و همچنین مختصات کادر دور شی را پیش بینی می کند.

با توجه به اینکه کادر دور هر شی ۴ مختصات دارد و همچنین دسته ی مورد نظر شی یک بردار C تایی هست و همین طور یک عدد برای احتمال وجود شی داریم پس به ازای هر شی یک تنزور (4 + 1 + C) تایی مورد نیاز است.

با توجه به اینکه فرض شد در هر تصویر N در N ناحیه وجود دارد و هر ناحیه احتمال حضور K شی به صورت بیشینه وجود دارد و هر شی نیز تزوری (4 + 1 + C) نیاز دارد پس در انتهای شبکه تنزوری KNN(C+1+4) وجود دارد که به پیشبینی کادر اشیا و احتمال آنها و دسته آنها می پردازد.

در نسخه نخست این شبکه پس از لایه های کانولوشن ویژگی ها خطی شده و به لایه های تمام متصل تحویل داده شده و در نهایت پیشبینی ها انجام می شوند در حالی که در نسخه های بعدی به جای ایجاد تنزوری به این ابعاد حجیم یک کرنل کانولوشن با ابعاد K(C+1+4) به نحوی بر روی ویژگی های آخرین لایه ی کانولوشن کانوالو می شود که ناحیه های ادراکی آن (Receptive Field) بر روی هر یک از N*N ناحیه از تصور ورودی قرار بگیرند و عملیات پیشبینی انجام شود.

 

تفاوت عمده این شبکه با شبکه ی RCNN این است که این شبکه به صورت سراسری (End-to-End) کار می کند و بحث تشخیص مکان اشیا را بدون نیاز به الگوریتم های بیرونی (Selective Search در RCNN) حل می کند و سرعت بسیار بالایی دارد و تماما با استفاده از شبکه های عصبی پیاده سازی شده و در نتیجه قابلیت موازی سازی بسیار مناسبی بر روی پردازنده هایی مثل GPU ها و FPGAها را داراست.

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

Cost function :

نتایج نهایی تشخیص اشیا روی تصویر توسط YOLO :

طبقه بند K نزدیکترین همسایه در scikit-learn

مسائل machine learning  به سه دسته تقسم می شوند:

1.supervised

2.unsupervised

3.enforcement learning

اکنون به دسته ی اول یعنی supervised learning میپردازیم.

The k-Nearest Neighbor Classifier

این الگوریتم از دسته الگوریتم های supervised learning  است. که آن را با چند مثال بررسی خواهیم کرد.

مثال اول:  در اینجا تعدادی feature برای تعدادی از گل ها مشخص کرده ا یم. اندازه ی گلبرگ ها و روشنایی گلبرگ ها.با توجه به مقادیری از feature ها که هر گل دارد، و label  های آن، مکان آن در نمودار مشخص می شود.

اگر بخواهیم بگوییم عکس جدیدی که    label آن را نداشته ایم در کدام دسته از گل ها قرار میگیرد(یعنی در واقع بخواهیم کلاس آن را تعیین کنیم.)، طبق الگوریتم nearest neighbor به صورت زیر میکنیم:

فاصله عکس جدید را با تمام training dataset ها محاسبه میکنیم تا ببنیم به کدام یک نزدیک تر است. و label عکس جدید همان label  نزدیک ترین data خواهد بود.

مثال دوم: در اینجا سه کلاس مختلف و دو feature داریم. و برای تعیین کلاس داده جدید مانند مثال قبل عمل خواهیم کرد.

1-nearest neighbor

در این الگوریتم label داده جدید، همان label نزدیک ترین داده به آن خواهد شد و در آن کلاس قرار خواهد گرفت. مشکل این الگوریتم این است که اگر در داده ها noise داشته باشیم، الگوریتم به درستی عمل نمیکند کرد.و داده ها را در کلاس اشتباه قرار میدهد.

k-nearest neighbor

برای رفع مشکل ذکر شده از این الگوریتم استفاده می شود. که در آن به جای یک همسایه، چند همسایه در نظر گرفته می شوند. K تعداد همسایه ها را مشخص می کند و hyper parameter است. که در فرایند training مشخص نمی شود.

انتخاب مقدار k به مسئله بستگی دارد. و باید مقادیر مختلف آن را برای test data بررسی کرد. اما اگر مقدار آن را بر اساس test data تعیین کنیم، مشکلی که به وجود می آید این است که ممکن است این مقدار فقط روی داده هایی که داریم عملکرد خوبی داشته باشد. و روی داده های جدید به خوبی عمل نکند.

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

از مشکلات این الگوریتم این است که اگر تعدادdata ها زیاد باشد، تعداد مقایسه ها بالا رفته و الگوریتم زمان بر می شود.

روشی که برای بهبود این مشکل وجود دارد استفاده ازVoronoi diagram است. که برای هر کلاس ناحیه ای مشخص شده است. و هنگام مشاهده داده جدید، با توجه به ناحیه ای که در آن قرار دارد، کلاس آن مشخص می شود.

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

1.scipy : برای لود کردن فایل مطلب استفاده می شود.

2.matplotlib : برای کشیدن نمودار استفاده می شود.

3.scikit-learn: کتابخانه ای برای machine learning است و بیشتر در machine learning  سنتی و کلاسیک کاربرد دارد.

میتوانید به جای pip از کلمه ی conda استفاده کنید. (اگر از آناکوندا استفاده میکنید.)

ابتدا package  ها و function های مورد نیاز را import  میکنیم.

 

Load_hoda : تابعی است که قبلا نوشته بودیم. که یک tuple شامل 1000 عدد training data و 200 عدد test data  بر می گرداند.

ایجاد طبقه بند k-nn

در کتابخانه scikit-learn طبقه بند به این شکل ایجاد می شود.

عدد 3 در اینجا همان k است.

و از تابع fit برای ذخیره دیتا های  train استفاده شده است.

پیش بینی داده های آموزشی

متغیر: sample را برای مشخص کردن اولین خانه تعریف می کنیم.

طبق کد X یک لیست شامل یک خانه است که آن خانه لیستی شامل 25 خانه (یک عکس از 200 دیتای  test) است.

 : Predicted_classهمان کلاس تشخیص داده شده برای داده است.

Actual_class : کلاسی است که واقعا داده به آن تعلق دارد. که از روی y_test  که همان label ها هستند تشخیص داده می شود.

در اینجا به تابع predict یک vector 25 تایی دادیم، و در قسمت fit 1000 تا vector 25 تایی. یکvector اول با 1000 vector دوم مقایسه شده و فاصله ها محاسبه می شود. با داشتن label  هر 1000 vector آن ها را sort می کند. و نزدیک ترین ها را پیدا می کند. و با بررسی سه  تا از نزدیک ترین ها، label داده را پیدا می کند.

Predict probability

تابع predict_proba درصد احتمال تعلق x تعریف شده به هرکدام از کلاس ها را بر می گرداند. که در اینجا با k=3 سه حالت اتفاق می افتد. (1، 0.6، 0.3)

پیش بینی چندین داده آزمون

Pred_classes: همه ی 200 داده مربوط به test data است.

True_classes: همه ی کلاس های واقعی را شامل می شود.

ارزیابی

با استفاده از تابع آماده score می توانیم میزان performance را محاسبه کنیم. همانطور که مشاهده می شود performance  برابر با 96 درصد است. یعنی از 200 داده، 8 تای آن اشتباه تشخیص داده شده است.