در قسمت ششم دوره آموزشی PyTorch برای مبتدیان ، قصد داریم به فرآیند تشخیص اشیا Faster R-CNN با PyTorch بپردازیم. پس با ما همراه باشید.
فهرست مطالب
۱- کلاسه بندی تصویر در مقابل تشخیص اشیا
کلاسه بندی تصویر ، مسئله ای است که در آن یک برچسب کلاس را به یک تصویر ورودی اختصاص می دهیم. به عنوان مثال ، با توجه به یک تصویر ورودی از یک گربه ، الگوریتم کلاسه بندی تصویر ، برچسب ” گربه ” را به عنوان خروجی نمایش می دهد.
در تشخیص اشیا ( Object Detection ) ، ما فقط به دنبال شناسایی اجسام موجود در تصویر ورودی نیستیم، بلکه قصد داریم موقعیت آن ها در تصویر ورودی را هم بدانیم. به همین جهت ، تشخیص اشیا کاری فراتر از کلاسه بندی تصویر است.
شکل زیر تفاوت بین کلاسه بندی تصویر و تشخیص اشیا را نشان می دهد.

۱-۱ کلاسه بندی تصویر یا تشخیص اشیا : از کدام یک باید استفاده کرد؟
کلاسه بندی تصویر ، برای کاربرد هایی که فقط یک شی در تصویر وجود دارد مناسب است. می تواند چندین کلاس وجود داشته باشد (به عنوان مثال گربه ها ، سگ ها و غیره) اما معمولاً فقط یک نمونه از آن کلاس در تصویر وجود دارد.
در بیشتر کاربرد هایی که چندین شی در تصویر ورودی وجود دارد ، باید موقعیت اشیا را پیدا کنیم و سپس آن ها را کلاسه بندی کنیم. در چنین مواردی از الگوریتم تشخیص اشیا استفاده می کنیم.
تشخیص اشیا می تواند نسبت به کلاسه بندی تصویر، بسیار کندتر عمل کند. به همین خاطر، در کاربرد هایی که موقعیت اشیا در تصویر مهم نیست، از کلاسه بندی تصویر استفاده می کنیم.
۲- تشخیص اشیا
به زبان ساده ، تشخیص اشیا یک فرآیند دو مرحله ای است :
- پیدا کردن کادر هایی در اطراف اشیا ، به طوری که هر کادر فقط نشانگر یک شی باشد
- کلاسه بندی تصویر داخل هر کادر و اختصاص یک برچسب به آن
در بخش های بعدی ، مراحلی را که منجر به توسعه معماری تشخیص اشیا Faster R-CNN می شود را مورد بحث قرار می دهیم.
۱-۲ رویکرد پنجره لغزان
اکثر تکنیک های تشخیص اشیا مبتنی بر بینایی رایانه ای کلاسیک مانند HAAR cascade و HOG + SVM از روش پنجره لغزان برای تشخیص اشیا استفاده می کنند. در این روش ، یک پنجره را بر روی تصویر می لغزانند و تمام پیکسل های داخل آن پنجره را برش داده و به یک کلاسه بند تصویر می دهند. اگر کلاسه بند تصویر یک شی مشخص را شناسایی کند ، کادر و برچسب کلاس مربوط به آن ذخیره می شوند. در غیر این صورت، به سراغ پنجره بعدی می رود. رویکرد پنجره لغزان ، محاسبات زیادی نیاز دارد. برای شناسایی اشیا در یک تصویر ورودی ، باید پنجره های لغزان در مقیاس ها و نسبت های مختلف روی هر پیکسل از تصویر مورد ارزیابی قرار گیرند.
با توجه به هزینه های محاسباتی ، پنجره های لغزان فقط زمانی بکار گرفته می شوند که ما یک کلاس شی را با یک نسبت ثابت شناسایی کنیم. به عنوان مثال ، تشخیص چهره مبتنی بر HOG + SVM یا HAAR در OpenCV از رویکرد پنجره لغزان استفاده می کنند. جالب است بدانید که در تشخیص چهره معروف Viola Jones از پنجره های لغزان استفاده شده است. در تشخیص چهره ، پیچیدگی مسئله قابل کنترل است، زیرا فقط کادر ها را در مقیاس های مختلف ارزیابی می کنیم.
۲-۲ تشخیص اشیا R-CNN
پس از موفقیت یک روش مبتنی بر CNN در چالش ImageNet (ILSVRC) در سال ۲۰۱۲ ، کلاسه بند های تصویر مبتنی بر شبکه عصبی کانولوشنی (CNN) محبوبیت زیادی پیدا کردند. از آنجا که هر تشخیص دهنده اشیا ، درون خود یک کلاسه بند تصویر دارد ، لذا ساخت تشخیص دهنده اشیا مبتنی بر CNN اجتناب ناپذیر شده است. دو چالش وجود دارد که باید برطرف شود :
- کلاسه بند های تصویر مبتنی بر CNN در مقایسه با روش های سنتی مانند HOG + SVM یاHAAR cascade از نظر محاسباتی بسیار هزینه بر بودند.
- جامعه بینایی رایانه ای دست از بلند پروازی برنمی دارد. برخی مهندسین می خواستند یک تشخیص دهنده اشیا چند کلاسه بسازند که علاوه بر مقیاس های مختلف ، بتواند نسبت های مختلف را هم کنترل کند.
بنابراین ، رویکرد مبتنی بر پنجره لغزان برای تشخیص اشیا به دلیل هزینه بر بودن منتفی شد.
محققان کار خود را بر روی ایده جدیدی برای آموزش مدل یادگیری ماشین شروع کردند که بتواند موقعیت کادر هایی حاوی اشیا هستند را ارائه دهد. به این کادر ها، پیشنهادهای ناحیه ( Region Proposals ) یا پیشنهادهای اشیا ( Object Proposals ) گفته می شد.
پیشنهادهای ناحیه صرفاً لیستی از کادرهای با احتمال وجود شی پایین هستند. در واقع مهم نیست کدام شی در کادر وجود دارد. یک الگوریتم پیشنهاد ناحیه ، لیستی از چند صد کادر در موقعیت ها ، مقیاس ها و نسبت های مختلف تولید می کند. در اکثر این کادر ها هیچ شیئی وجود ندارد.
با این حال آیا روش پیشنهادهای ناحیه هنوز هم می تواند مفید باشد؟
ارزیابی کلاسه بندی تصویر در چند صد کادر ارائه شده توسط الگوریتم پیشنهاد ناحیه ، بسیار ارزان تر از ارزیابی آن در صدها هزار یا حتی میلیون ها کادر با رویکرد پنجره لغزان است. به همین خاطر، الگوریتم پیشنهاد ناحیه هنوز هم گاهی مفید و قابل استفاده است.
یکی از اولین رویکردهایی که از پیشنهادات ناحیه استفاده می کرد R-CNN ( Regions with features CNN ) بود. ( توسط Ross Girshick و همکاران)

منبع تصویر : مقاله R-CNN توسط Ross Girshick و همکاران
آن ها با استفاده از الگوریتمی به نام Selective Search به شناسایی ۲۰۰۰ پیشنهاد ناحیه پرداختند و یک کلاسه بندی تصویر مبتنی بر CNN + SVM را روی این ۲۰۰۰ کادر اعمال کردند.
R-CNN در آن زمان بسیار دقیق عمل می کرد ، اما هنوز سرعت پایینی داشت ( ۱۸ تا ۲۰ ثانیه برای هر تصویر در GPU )
۳-۲ تشخیص اشیا Fast R-CNN
در R-CNN هر کادر به طور جداگانه توسط کلاسه بند تصویر طبقه بندی می شد. ۲۰۰۰ پیشنهاد ناحیه وجود دارد و کلاسه بند تصویر برای هر پیشنهاد ناحیه یک نقشه ویژگی ( feature map ) محاسبه می کرد، که این روند هزینه بر بود.
در همین راستا Ross Girshick ، روشی را پیشنهاد کرد به نام Fast R-CNN که سرعت تشخیص اشیا را به طور قابل توجهی افزایش می دهد.
ایده این بود که به جای ۲۰۰۰ نقشه ویژگی برای ۲۰۰۰ پیشنهاد ناحیه ، یک نقشه ویژگی واحد برای کل تصویر محاسبه شود. برای هر پیشنهاد ناحیه ، یک ناحیه مطلوب (RoI) لایه تجمعی (pooling)، یک بردار ویژگی با طول ثابت را از نقشه ویژگی استخراج می کند. سپس از هر بردار ویژگی برای دو هدف استفاده می شود :
- کلاسه بندی ناحیه در یکی از کلاس ها (به عنوان مثال سگ ، گربه ، پس زمینه).
- افزایش دقت کادر اصلی، با استفاده از رگرسیون کادر

۴-۲ تشخیص اشیا Faster R-CNN
در Fast R-CNN ، حتی اگر فرآیند محاسباتی کلاسه بندی ۲۰۰۰ پیشنهاد ناحیه به اشتراک گذاشته شده باشد ، الگوریتم تولیدکننده پیشنهادهای ناحیه ، هیچ فرآیندی را با بخش کلاسه بندی تصویر ، به اشتراک نمی گذارد.
در Faster R-CNN ، ایده اصلی این بود که هر دو قسمت ( محاسبه پیشنهادات ناحیه و کلاسه بندی تصویر ) می توانند از یک نقشه ویژگی یکسان استفاده کنند و بنابراین بار محاسباتی را تقسیم می کنند.
از یک شبکه عصبی کانولوشنی برای تهیه یک نقشه ویژگی از تصویر استفاده شده است که به طور همزمان برای آموزش شبکه پیشنهاد ناحیه و کلاسه بند تصویر استفاده می شود. به دلیل این فرآیند مشترک ، سرعت تشخیص اشیا بطور قابل توجهی افزایش یافته است.

۳- کد نویسی تشخیص اشیا با PyTorch
در این بخش نحوه کد نویسی یک تشخیص دهنده اشیا Faster R-CNN با PyTorch را می آموزیم. ما از مدل از قبل آموزش دیده با torchvision استفاده خواهیم کرد. جزئیات تمام مدل های از پیش آموزش دیده در PyTorch را می توان در torchvision.models مشاهده کرد.
۱-۳ ورودی و خروجی
در مدل از قبل آموزش دیده Faster R-CNN ResNet-50 که می خواهیم از آن استفاده کنیم، تنسور تصویر ورودی باید به شکل [n, c, h, w] و دارای حداقل اندازه 800px باشد ، که :
- n : تعداد تصاویر
- c : تعداد کانال ها ( برای تصاویر RGB تعداد کانال ۳ است )
- h : طول تصویر
- w : عرض تصویر
و مدل موارد زیر را برمی گردد
- کادر های به مختصات [x0, y0, x1, y1] برای تمام کلاس های پیش بینی شده یه شکل (N,4) که N تعداد کلاس های پیش بینی شده موجود در تصویر توسط مدل است
- برچسب تمام کلاس های پیش بینی شده
- امتیازات هر یک از برچسب های پیش بینی شده
۲-۳ مدل از پیش آموزش داده شده
با استفاده از کد زیر، مدل از قبل آموزش دیده را از torchvision دانلود کنید :
import torchvision model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True) model.eval()
خط ۲ یک مدل از قبل آموزش دیده Resnet50 Faster R-CNN با وزن های آموزش دیده را دانلود می کند.
نام کلاس های ارائه شده را توسط فایل های معتبر PyTorch تعریف کنید
COCO_INSTANCE_CATEGORY_NAMES = [ '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table', 'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush' ]
تعدادی N / A ها را در لیست مشاهده می کنید ، زیرا چند کلاس در مقالات بعدی حذف شدند. ما با لیست ارائه شده توسط PyTorch پیش می رویم.
۳-۳ پیش بینی مدل
بیایید برای گرفتن مسیر تصویر و پیش بینی تصویر توسط مدل ، یک تابع تعریف کنیم.
def get_prediction(img_path, threshold): img = Image.open(img_path) # Load the image transform = T.Compose([T.ToTensor()]) # Defing PyTorch Transform img = transform(img) # Apply the transform to the image pred = model([img]) # Pass the image to the model pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in list(pred[0]['labels'].numpy())] # Get the Prediction Score pred_boxes = [[(i[0], i[1]), (i[2], i[3])] for i in list(pred[0]['boxes'].detach().numpy())] # Bounding boxes pred_score = list(pred[0]['scores'].detach().numpy()) pred_t = [pred_score.index(x) for x in pred_score if x > threshold][-1] # Get list of index with score greater than threshold. pred_boxes = pred_boxes[:pred_t+1] pred_class = pred_class[:pred_t+1] return pred_boxes, pred_class
- تصویر از مسیر داده شده بدست می آید
- تصویر با استفاده از تبدیلات PyTorch به تنسور تصویر تبدیل می شود
- تصویر برای بدست آوردن پیش بینی ها وارد مدل ما می شود
- کلاس و مختصات کادر بدست می آید، اما فقط امتیاز پیش بینی های بزرگ تر از آستانه انتخاب می شود.
۴-۳ خط لوله برای تشخیص اشیا
در مرحله بعد خط لوله ای برای گرفتن مسیر تصویر و بدست آوردن تصویر خروجی تعریف خواهیم کرد.
def object_detection_api(img_path, threshold=0.5, rect_th=3, text_size=3, text_th=3): boxes, pred_cls = get_prediction(img_path, threshold) # Get predictions img = cv2.imread(img_path) # Read image with cv2 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Convert to RGB for i in range(len(boxes)): cv2.rectangle(img, boxes[i][0], boxes[i][1],color=(0, 255, 0), thickness=rect_th) # Draw Rectangle with the coordinates cv2.putText(img,pred_cls[i], boxes[i][0], cv2.FONT_HERSHEY_SIMPLEX, text_size, (0,255,0),thickness=text_th) # Write the prediction class plt.figure(figsize=(20,30)) # display the output image plt.imshow(img) plt.xticks([]) plt.yticks([]) plt.show()
- پیش بینی از روش get_prediction بدست می آید
- برای هر پیش بینی ، کادر ترسیم شده و متن با opencv نوشته می شود
- تصویر نهایی نمایش داده می شود
۵-۳ استنباط
اکنون قصد داریم از خط لوله API که برای شناسایی اشیا در برخی تصاویر ساختیم استفاده کنیم. مدل از قبل آموزش دیده حدود ۸ ثانیه برای استنباط در CPU و ۰٫۱۵ ثانیه در NVIDIA GTX 1080 Ti GPU زمان می برد.
مثال ۳-۵-۱
یک تصویر را برای استنباط دانلود کنید
wget https://www.wsha.org/wp-content/uploads/banner-diverse-group-of-people-2.jpg -O people.jpg
برای نمایش خروجی از تصویر با تابع api استفاده کنید.
object_detection_api('./people.jpg', threshold=0.8)

مثال ۳-۵-۲
بیایید مثال های بیشتری را امتحان کنیم
!wget https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/10best-cars-group-cropped-1542126037.jpg -O car.jpg object_detection_api('./car.jpg', rect_th=6, text_th=5, text_size=5)

مثال ۳-۵-۳
!wget https://cdn.pixabay.com/photo/2013/07/05/01/08/traffic-143391_960_720.jpg -O traffic.jpg object_detection_api('./traffic.jpg', rect_th=2, text_th=1, text_size=1)

مثال ۳-۵-۴
!wget https://images.unsplash.com/photo-1458169495136-854e4c39548a -O girl_cars.jpg object_detection_api('./girl_cars.jpg', rect_th=15, text_th=7, text_size=5, threshold=0.8)

۴- مقایسه زمان استنباط مدل در CPU و GPU
ما قصد داریم زمان استنباط هر یک از مدل ها را در CPU و GPU بدانیم. ما زمان پیش بینی شده توسط مدل را برای پیش بینی خروجی برای یک تصویر ورودی اندازه گیری می کنیم. به عنوان مثال : prediction = model(image)
GPU | CPU | مدل |
۰٫۱۵۳۵۶ s | 8.45859 s | Faster R-CNN ResNet-50 FPN |
خب در این مقاله نگاهی داشتیم بر فرآیند تشخیص اشیا Faster R-CNN با PyTorch و بررسی چند مثال. اگر از این مقاله خوشتان آمده می توانید برای دریافت یک راهنمای مرجع بینایی رایانه ای رایگان اینجا کلیک کنید.
import های لازم رو نذاشتید ممنون میشم اگه اون ها رو هم قرار بدید
کودوم موارد منظورتونه؟