آموزش PyTorch برای مبتدیان – ناحیه بندی نمونه با Mask R-CNN

در آخرین پست از مجموعه PyTorch برای مبتدیان ، ما در مورد تئوری Mask R-CNN و نحوه استفاده از یک مدل Mask R-CNN از قبل آموزش دیده در PyTorch بحث خواهیم کرد.

۱- ناحیه بندی معنایی ، تشخیص اشیا و ناحیه بندی نمونه

ما تاکنون در قسمت های پیشین این مجموعه آموزشی ، به موارد زیر پرداختیم :

  1. ناحیه بندی معنایی : در ناحیه بندی معنایی ، به هر پیکسل تصویر یک برچسب کلاس اختصاص می دهیم ( به عنوان مثال سگ ، گربه ، شخص ، پس زمینه و …).
  2. تشخیص اشیا : در تشخیص شی ، ما یک برچسب کلاس را به کادرهای محصورکننده ای که حاوی اشیا هستند اختصاص می دهیم.

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

به الگوریتم هایی که ماسک فوق را تولید می کنند ، الگوریتم های ناحیه بندی نمونه ( Instance Segmentation ) گفته می شود و Mask R-CNN یکی از این الگوریتم هاست.

ناحیه بندی نمونه و ناحیه بندی معنایی از دو جهت متفاوت هستند :

  1. در ناحیه بندی معنایی ، به هر پیکسل یک برچسب کلاس اختصاص داده می شود ، در حالی که ناحیه بندی نمونه چنین نیست.
  2. ما نمونه های یک کلاس را در ناحیه بندی معنایی جدا از هم درنظر نمی گیریم. به عنوان مثال ، به تمام پیکسل های مربوط به کلاس “شخص” در ناحیه بندی معنایی ، مقدار روشنایی یا رنگ یکسان در ماسک اختصاص می یابد. در ناحیه بندی نمونه ، مقادیر مختلفی به آن ها اختصاص داده شده است و ما می توانیم بگوییم کدام پیکسل ها مربوط به کدام شخص هستند. 

 

۱-۱ معماری Mask R-CNN

معماری Mask R-CNN یک مدل تعمیم یافته از Faster R-CNN است که ما در پست قبلی به آن اشاره کردیم. جهت یادآوری معماری Faster R-CNN به شرح زیر بود :

  1. لایه های کانولوشنی : تصویر ورودی از چندین لایه کانولوشن عبور داده می شود تا یک نقشه ویژگی استخراج شود. اگر مبتدی هستید می توانید فعلا لایه های کانولوشنی را به عنوان یک جعبه سیاه تصور کنید که یک تصویر ورودی ۳ کاناله دریافت می کند و یک ” تصویر ” با ابعاد مکانی بسیار کوچکتر (۷×۷) ، اما تعداد کانال های بیشتر (۵۱۲) تولید می کند.
  2. شبکه پیشنهاد ناحیه (RPN) : از خروجی لایه های کانولوشنی برای آموزش شبکه ای استفاده می شود که نواحی اشیا محصور را پیشنهاد می کند.
  3. کلاسه بند : از همان نقشه ویژگی برای آموزش کلاسه بندی که یک برچسب را به شی درون کادر اختصاص می دهد نیز استفاده می شود.

همچنین ، به خاطر داشته باشید که Faster R-CNN سریعتر از Fast R-CNN بود ، زیرا نقشه ویژگی یک بار محاسبه می شد و توسط RPN و کلاسه بندی مجدداً مورد استفاده قرار می گرفت.

Mask R-CNN این ایده را یک گام فراتر می برد. علاوه بر ارسال نقشه ویژگی به RPN و کلاسه بند ، از آن برای پیش بینی یک ماسک باینری برای شی درون کادر محصور کننده نیز استفاده می کند.

یکی از راه های مشاهده قسمت پیش بینی ماسک Mask R-CNN ، یک شبکه تمام کانولوشنی (FCN) است که برای ناحیه بندی معنایی مورد استفاده قرار گیرد. تنها تفاوت این است که FCN روی کادر های محصور کننده اعمال می شود، و لایه کانولوشنی هم در RPN و هم در کلاسه بند بکار گرفته می شود.

شکل زیر یک معماری سطح بالا را نشان می دهد.

معماری شبکه Mask RCNN
معماری شبکه Mask RCNN

۲- کد نویسی Mask R-CNN با PyTorch

در این بخش ، خواهیم دید که چگونه از مدل آموزش دیده Mask R-CNN در PyTorch استفاده کنیم.

۱-۲ ورودی و خروجی

این مدل لیستی از تصاویر تنسور به شکل(n , c, h, w)  با مقادیر در محدوده ۰-۱ را  به عنوان ورودی می گیرد و لزومی ندارد که اندازه تصویر ثابت باشد.

  • n : تعداد تصاویر
  • c : تعداد کانال ها ( برای تصاویر RGB برابر ۳ است )
  • h : طول تصویر
  • w : عرض تصویر

خروجی مدل به شرح زیر است :

  • مختصات کادر های محصور کننده
  • برچسب کلاس هایی که مدل در تصویر ورودی پیش بینی می کند، امتیاز برچسب ها
  • ماسک های مربوط به هر کلاس موجود در برچسب ها

۲-۲ مدل از قبل آموزش دیده

model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)
model.eval()

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

۳-۲ پیش بینی مدل

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'
]

def get_prediction(img_path, threshold):
  img = Image.open(img_path)
  transform = T.Compose([T.ToTensor()])
  img = transform(img)
  pred = model([img])
  pred_score = list(pred[0]['scores'].detach().numpy())
  pred_t = [pred_score.index(x) for x in pred_score if x>threshold][-1]
  masks = (pred[0]['masks']>0.5).squeeze().detach().cpu().numpy()
  pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in list(pred[0]['labels'].numpy())]
  pred_boxes = [[(i[0], i[1]), (i[2], i[3])] for i in list(pred[0]['boxes'].detach().numpy())]
  masks = masks[:pred_t+1]
  pred_boxes = pred_boxes[:pred_t+1]
  pred_class = pred_class[:pred_t+1]
  return masks, pred_boxes, pred_class
  • تصویر از مسیر داده شده بدست می آید
  • تصویر با استفاده از تبدیلات PyTorch به تنسور تصویر تبدیل می شود
  • تصویر برای بدست آوردن پیش بینی ها وارد مدل ما می شود
  • ماسک ها ، کلاس های پیش بینی و مختصات کادر محصورکننده از مدل بدست می آیند و ماسک های باینری ساخته می شوند (۰ یا ۱). مثال : ناحیه گربه ۱ و بقیه تصویر ۰ هستند.

به ماسک هر شی پیش بینی شده ، از بین ۱۱ رنگ تعیین شده ، یک رنگ تصادفی اختصاص داده می شود.

def random_colour_masks(image):
  colours = [[0, 255, 0],[0, 0, 255],[255, 0, 0],[0, 255, 255],[255, 255, 0],[255, 0, 255],[80, 70, 180],[250, 80, 190],[245, 145, 50],[70, 150, 250],[50, 190, 190]]
  r = np.zeros_like(image).astype(np.uint8)
  g = np.zeros_like(image).astype(np.uint8)
  b = np.zeros_like(image).astype(np.uint8)
  r[image == 1], g[image == 1], b[image == 1] = colours[random.randrange(0,10)]
  coloured_mask = np.stack([r, g, b], axis=2)
  return coloured_mask

۴-۲ خط لوله برای ناحیه بندی معنایی

def instance_segmentation_api(img_path, threshold=0.5, rect_th=3, text_size=3, text_th=3):
  masks, boxes, pred_cls = get_prediction(img_path, threshold)
  img = cv2.imread(img_path)
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  for i in range(len(masks)):
    rgb_mask = random_colour_masks(masks[i])
    img = cv2.addWeighted(img, 1, rgb_mask, 0.5, 0)
    cv2.rectangle(img, boxes[i][0], boxes[i][1],color=(0, 255, 0), thickness=rect_th)
    cv2.putText(img,pred_cls[i], boxes[i][0], cv2.FONT_HERSHEY_SIMPLEX, text_size, (0,255,0),thickness=text_th)
  plt.figure(figsize=(20,30))
  plt.imshow(img)
  plt.xticks([])
  plt.yticks([])
  plt.show()
  • ماسک ها ، کلاس پیش بینی و کادر محصورکننده با get_prediction بدست می آیند.
  • به هر ماسک یک رنگ تصادفی از بین ۱۱ رنگ اختصاص داده می شود.
  • هر ماسک در نسبت ۱:۰٫۵ با OpenCV به تصویر اضافه می شود
  • یک کادر محصورکننده با rektangle با نام کلاس که به صورت حاشیه نویسی متنی روی آن رسم شده است.
  • خروجی نهایی نمایش داده می شود

۵-۲ استنباط

مدل از قبل آموزش دیده برای استنباط در CPU حدود ۱۰ ثانیه و در GPU NVIDIA GTX 1080 Ti حدود ۰٫۲۱ ثانیه زمان لازم دارد.

ناحیه بندی افراد در تصویر با mask rcnn
ناحیه بندی خودرو ها با الگوریتم Mask RCNN
ناحیه بندی فیل ها در تصویر با Mask RCNN
ناحیه بندی اشیا مختلف با mask Rcnn

۳- عملکرد Faster R-CNN در مقابل Mask R-CNN

می دانیم که Mask R-CNN از نظر محاسباتی پرهزینه تر از Faster R-CNN است، زیرا Mask R-CNN مبتنی بر Faster R-CNN است و کارهای اضافی مورد نیاز برای تولید ماسک را انجام می دهد. اما اجازه دهید ببینیم این مدل چقدر پرهزینه تر است؟

۱-۳ مقایسه زمان استنباط مدل در CPU و GPU

ما زمان موردنیاز مدل را برای پیش بینی خروجی از یک تصویر ورودی در یک CPU و یک GPU اندازه گیری کردیم. در CPU سرعت مدل ها به طرز شگفت انگیزی نزدیک بهم است ، اما در GPU ، Mask R-CNN حدود ۴۷ میلی ثانیه بیشتر طول می کشد.

مدل هاCPUGPU
Faster R-CNN ResNet-50 FPN8.45859 s0.15356 s
Mask R-CNN ResNet-50 FPN9.82342 s0.21595 s

۲-۳ الزامات حافظه مدل ها

ما همچنین حافظه مورد نیاز مدل ها را هم اندازه گیری کردیم.

مدل هاحافظه (گیگابایت)
Faster R-CNN ResNet-50 FPN5.2
Mask R-CNN ResNet-50 FPN5.4

خب، در این قسمت به تئوری و نحوه استفاده از مدل Mask R-CNN از قبل آموزش دیده در PyTorch پرداختیم. امیدواریم این مجموعه برای شما مفید بوده باشد.

بیشتر بخوانید :

درباره‌ی امیر اقتدائی

همچنین ببینید

آیا می خواهید در زمینه یادگیری ماشین استخدام شوید؟

آیا می خواهید در زمینه یادگیری ماشین استخدام شوید؟

مسیر های شغلی زیادی در حوزه یادگیری ماشین وجود دارد، اما از کجا بفهمیم که …

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *