Skip to content

About

Mask R-CNN implementation built 100% from scratch using TensorFlow/Keras. Complete object detection and instance segmentation pipeline with ResNet50/101 backbone, FPN, RPN, ROI Align, and detection heads. No imported pre-trained models - every layer is defined from the ground up for complete control and understanding.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎯 Mask R-CNN: Complete Implementation Guide

From-Scratch Implementation for Object Detection & Instance Segmentation


πŸ“‹ Table of Contents

  1. Project Overview
  2. Why From Scratch?
  3. Complete Architecture
  4. Component Breakdown
  5. Training vs Inference Flow
  6. Data Flow Pipeline
  7. Key Features
  8. Technical Stack
  9. Quick Start
  10. Project Structure
  11. Learning Outcomes
  12. License & Acknowledgments

🎯 Project Overview

Mask R-CNN From Scratch is a complete, production-ready implementation of the state-of-the-art Mask R-CNN architecture built entirely from the ground up using TensorFlow/Keras. Unlike other implementations that import pre-built ResNet or pre-trained models, every single layer is defined and built from scratch, giving you complete control and understanding of the entire architecture.

Aspect Details
Type Object Detection + Instance Segmentation
Implementation 100% From Scratch (No imported models)
Framework TensorFlow 2.14+ / Keras
Backbone ResNet50/101 (Built from layers)
Architecture ResNet + FPN + RPN + ROI Align + Heads

πŸ€” Why From Scratch?

Reason Benefit
Complete Control Modify any layer without framework limitations
Full Transparency Understand every operation in the pipeline
Educational Value Learn Mask R-CNN internals by building them
Flexibility Add custom layers, losses, or modifications easily
No Black Boxes Everything is visible and debuggable

πŸ—οΈ Complete Architecture

High-Level Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MASK R-CNN COMPLETE ARCHITECTURE β”‚ β”‚ (Built 100% From Scratch) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ INPUT IMAGE [batch, H, W, 3] β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ STEP 1: RESNET BACKBONE (resnet_graph) β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ Stage 1: Conv7x7 + MaxPool β†’ C1 [256x256x64] β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Stage 2: Conv + 2x Identity β†’ C2 [256x256x256] ← Fine details β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Stage 3: Conv + 3x Identity β†’ C3 [128x128x512] ← Object parts β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Stage 4: Conv + 5/22x Identity β†’ C4 [64x64x1024] ← Whole objects β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Stage 5: Conv + 2x Identity β†’ C5 [32x32x2048] ← Semantic context β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ STEP 2: FPN CONSTRUCTION (build() method) β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ C5 β†’ Conv1x1 β†’ P5 [32x32x256] ← Largest objects β”‚ β”‚β”‚ β”‚ β”‚ β”‚ C4 β†’ Conv1x1 + Upsample(P5) β†’ P4 [64x64x256] ← Large objects β”‚ β”‚β”‚ β”‚ β”‚ β”‚ C3 β†’ Conv1x1 + Upsample(P4) β†’ P3 [128x128x256] ← Medium objects β”‚ β”‚β”‚ β”‚ β”‚ β”‚ C2 β†’ Conv1x1 + Upsample(P3) β†’ P2 [256x256x256] ← Small objects β”‚ β”‚β”‚ β”‚ β”‚ β”‚ P5 β†’ MaxPool β†’ P6 [16x16x256] ← Extra large (RPN only) β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ STEP 3: RPN (rpn_graph) β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ For each P2-P6: β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Shared Conv3x3(512) β†’ Branch β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Classification Head: Conv1x1(2A) β†’ rpn_class_logits [batch, total_anchors, 2] β”‚ β”‚β”‚ β”‚ β”‚ β”‚ └── BBox Head: Conv1x1(4A) β†’ rpn_bbox [batch, total_anchors, 4] β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ STEP 4: PROPOSAL LAYER (ProposalLayer) β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ 1. Select top 6000 anchors by FG score β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 2. apply_box_deltas_graph() β†’ Refine boxes β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 3. clip_boxes_graph() β†’ Clip to [0,1] β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 4. NMS β†’ Keep top 2000 (training) or 1000 (inference) β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Output: rpn_rois [batch, 2000/1000, 4] β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ TRAINING PATH β”‚ β”‚ INFERENCE PATH β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ DetectionTargetLayer β”‚β”‚ β”‚ β”‚ Heads (Direct from rpn_rois) β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Inputs: rpn_rois + GT β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β”‚ β”‚ 1. IoU Computation β”‚β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 2. Classify proposals β”‚β”‚ β”‚ β–Ό β”‚β”‚ β”‚ β”‚ β”‚ 3. Subsample to 200 β”‚β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ 4. Generate targets β”‚β”‚ β”‚ β”‚ DetectionLayer β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Outputs: β”‚β”‚ β”‚ β”‚ 1. Get best class (argmax) β”‚ β”‚β”‚ β”‚ β”‚ β”‚ - rois [200,4] β”‚β”‚ β”‚ β”‚ 2. Class-specific deltas β”‚ β”‚β”‚ β”‚ β”‚ β”‚ - target_class_ids [200] β”‚β”‚ β”‚ β”‚ 3. Refine boxes β”‚ β”‚β”‚ β”‚ β”‚ β”‚ - target_bbox [200,4] β”‚β”‚ β”‚ β”‚ 4. Filter background + confidence β”‚ β”‚β”‚ β”‚ β”‚ β”‚ - target_mask [200,28,28]β”‚β”‚ β”‚ β”‚ 5. Class-wise NMS β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ Output: detections [max, 6] β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β–Ό β”‚β”‚ β”‚ β”‚ β”‚ PyramidROIAlign (7x7/14x14)β”‚β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ 1. Assign to FPN level β”‚β”‚ β”‚ β”‚ build_fpn_mask_graph() β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 2. Crop features β”‚β”‚ β”‚ β”‚ detection_boxes + P2-P5 β†’ masks β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 3. Resize to fixed size β”‚β”‚ β”‚ β”‚ Output: mrcnn_mask [max, 28, 28, C] β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β–Ό β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ fpn_classifier_graph() β”‚β”‚ β”‚ β”‚ FINAL OUTPUT β”‚ β”‚β”‚ β”‚ β”‚ β”‚ ROI features (7x7) β†’ β”‚β”‚ β”‚ β”‚ detections + mrcnn_mask β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 2x FC Layers β†’ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Classifier Head (C) β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ └── BBox Head (C,4) β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ build_fpn_mask_graph() β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ ROI features (14x14) β†’ β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 4x Conv3x3 β†’ β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Deconv(28x28) β†’ β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Conv1x1 + Sigmoid β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Output: mrcnn_mask [C] β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ LOSS FUNCTIONS β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 1. rpn_class_loss β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 2. rpn_bbox_loss β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 3. mrcnn_class_loss β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 4. mrcnn_bbox_loss β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ 5. mrcnn_mask_loss β”‚β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


🧩 Component Breakdown

1. ResNet Backbone (resnet_graph)

Stage Blocks Output Shape Purpose
Stage 1 Conv7x7 + MaxPool 256Γ—256Γ—64 Initial feature extraction
Stage 2 Conv + 2x Identity 256Γ—256Γ—256 Fine details, edges
Stage 3 Conv + 3x Identity 128Γ—128Γ—512 Object parts, textures
Stage 4 Conv + 5/22x Identity 64Γ—64Γ—1024 Whole objects, structures
Stage 5 Conv + 2x Identity 32Γ—32Γ—2048 Semantic concepts, context

Key Components:

  • identity_block: Skip connection, no shape change
  • conv_block: Skip connection with Conv1x1, changes shape
  • Both blocks have the SAME main path, only shortcut differs

2. Feature Pyramid Network (FPN)

Level Resolution Used For
P2 256Γ—256 Small objects (fine details)
P3 128Γ—128 Medium objects
P4 64Γ—64 Large objects
P5 32Γ—32 Very large objects (semantic)
P6 16Γ—16 RPN only (extra large)

Process:

  1. Lateral Connections: Conv1x1 on C2-C5 β†’ 256 channels
  2. Top-Down Pathway: Upsample + Add β†’ Combine features
  3. Smoothing: Conv3x3 on each P layer

3. Region Proposal Network (RPN)

Component Purpose Output Shape
Shared Conv Feature extraction [batch, H, W, 512]
Classification Head FG vs BG scores [batch, total_anchors, 2]
BBox Head Anchor refinements [batch, total_anchors, 4]
  • Input: P2-P6 feature maps
  • Output: rpn_class_logits, rpn_probs, rpn_bbox
  • Anchors: ~785,000 (5 scales Γ— 3 ratios per pixel)

4. Proposal Layer

Step Operation Output
1 Select top 6000 by FG score 6000 anchors
2 Apply deltas (apply_box_deltas_graph) 6000 refined boxes
3 Clip to image (clip_boxes_graph) 6000 clipped boxes
4 NMS (IoU > 0.7) 2000/1000 proposals

Output: rpn_rois [batch, proposal_count, 4]


5. DetectionTargetLayer (Training Only)

Step Operation Purpose
1 Remove padding Clean data
2 Handle COCO crowds Exclude crowds
3 Compute IoU Match proposals to GT
4 Classify proposals Positive (IoUβ‰₯0.5) / Negative (IoU<0.5)
5 Subsample to 200 33% positive, 67% negative
6 Generate targets Class IDs, bbox deltas, masks

Output: rois [200,4], target_class_ids [200], target_bbox [200,4], target_mask [200,28,28]


6. PyramidROIAlign

Step Operation Purpose
1 Calculate area Determine proposal size
2 Assign to FPN level P2 (small), P3 (medium), P4 (large), P5 (very large)
3 Crop features Extract from correct level
4 Resize to fixed size 7Γ—7 (classifier) or 14Γ—14 (mask)
5 Bilinear interpolation No quantization error

Output: [batch, num_rois, 7/14, 7/14, 256]


7. Classifier + BBox Head (fpn_classifier_graph)

Layer Input Output Purpose
ROI Align (7Γ—7) rois [200,4] [200,7,7,256] Extract features
FC Layer 1 [200,7,7,256] [200,1,1,1024] Feature transformation
FC Layer 2 [200,1,1,1024] [200,1,1,1024] Feature transformation
Squeeze [200,1,1,1024] [200,1024] Flatten
Classifier Head [200,1024] [200,C] Predict class
BBox Head [200,1024] [200,C,4] Predict deltas per class

Outputs: mrcnn_class_logits, mrcnn_probs, mrcnn_bbox


8. Mask Head (build_fpn_mask_graph)

Layer Input Output Purpose
ROI Align (14Γ—14) rois [200,4] [200,14,14,256] Extract detailed features
Conv1-4 [200,14,14,256] [200,14,14,256] Feature learning
Deconv [200,14,14,256] [200,28,28,256] Upsample to 28Γ—28
Conv1Γ—1 + Sigmoid [200,28,28,256] [200,28,28,C] Predict per-class masks

Output: mrcnn_mask [batch, 200, 28, 28, C]


9. DetectionLayer (Inference Only)

Step Operation Purpose
1 Get best class (argmax) Choose class per proposal
2 Get class-specific deltas Refine box for that class
3 Apply deltas Refine boxes
4 Filter background Remove class=0
5 Filter low confidence Remove low scores
6 Class-wise NMS Remove duplicates per class
7 Pad to fixed size Consistent output shape

Output: detections [batch, max_instances, 6]


10. Loss Functions

Loss Type Purpose
RPN Class Cross Entropy Learn which anchors have objects
RPN BBox Smooth L1 Refine anchor boxes
MRCNN Class Sparse Cross Entropy Predict correct class
MRCNN BBox Smooth L1 Refine boxes per class
MRCNN Mask Binary Cross Entropy Predict accurate masks

πŸ”„ Training vs Inference Flow

Training Mode

Image + GT β†’ ResNet β†’ FPN β†’ RPN β†’ Proposals (2000) β”‚ β–Ό DetectionTargetLayer β†’ rois (200) + targets β”‚ β–Ό ROI Align β†’ ROI features (7x7, 14x14) β”‚ β–Ό Heads β†’ Predictions (class, bbox, mask) β”‚ β–Ό Loss Functions β†’ Backpropagation β†’ Update ALL weights

text

Inference Mode

Image β†’ ResNet β†’ FPN β†’ RPN β†’ Proposals (1000) β”‚ β–Ό ROI Align β†’ ROI features (7x7, 14x14) β”‚ β–Ό Heads β†’ Predictions (class, bbox, mask) β”‚ β–Ό DetectionLayer β†’ Final detections (boxes, classes, scores, masks)

text


πŸ“Š Data Flow Pipeline

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ COMPLETE DATA FLOW β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ DATASET β”‚ β”‚ β”œβ”€β”€ Images + Annotations (boxes, classes, masks) β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ DataGenerator.getitem() β”‚ β”‚ β”œβ”€β”€ load_image_gt() β†’ Image + GT (resized, augmented) β”‚ β”‚ β”œβ”€β”€ build_rpn_targets() β†’ rpn_match + rpn_bbox β”‚ β”‚ └── Returns: [images, image_meta, rpn_match, rpn_bbox, gt_class_ids, gt_boxes, gt_masks] β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ MODEL.TRAIN() β”‚ β”‚ β”œβ”€β”€ ResNet β†’ C2, C3, C4, C5 β”‚ β”‚ β”œβ”€β”€ FPN β†’ P2, P3, P4, P5, P6 β”‚ β”‚ β”œβ”€β”€ RPN β†’ rpn_class, rpn_bbox β”‚ β”‚ β”œβ”€β”€ ProposalLayer β†’ rpn_rois (2000/1000) β”‚ β”‚ β”œβ”€β”€ DetectionTargetLayer β†’ rois (200) + targets β”‚ β”‚ β”œβ”€β”€ ROI Align β†’ ROI features (7Γ—7, 14Γ—14) β”‚ β”‚ β”œβ”€β”€ Heads β†’ Predictions β”‚ β”‚ β”œβ”€β”€ Loss β†’ Compare predictions to targets β”‚ β”‚ └── Backpropagation β†’ Update weights β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


✨ Key Features

Detection Capabilities

Feature Description
Bounding Box Detection Accurate localization with class labels
Instance Segmentation Pixel-perfect masks for each object
Multi-Object Detection Detect multiple objects of different classes
Confidence Scoring Probability score for each detection

Technical Features

Feature Description
End-to-End Training Train all components together
Multi-GPU Support Parallel training across GPUs
Custom Dataset Support Easy integration with your own data
Data Augmentation Built-in augmentation pipeline
Transfer Learning Pre-trained ImageNet weights support

πŸ› οΈ Technical Stack

Core Dependencies

tensorflow-macos==2.14.0          # TensorFlow for M1 Mac
tensorflow-metal==1.0.1           # GPU acceleration for M1
keras==2.14.0                     # High-level API
numpy==1.23.5                     # Numerical operations
opencv-python==4.8.0.76           # Image operations
matplotlib==3.7.1                 # Visualization
scipy==1.11.3                     # Scientific computing
h5py==3.9.0                       # HDF5 file handling
imgaug==0.4.0                     # Data augmentation
Hardware Requirements
Component	Minimum	Recommended
GPU	8GB VRAM	12GB+ VRAM
RAM	16GB	32GB+
Storage	50GB	100GB+
CPU	4 cores	8+ cores

Installation

# 1. Create environment
conda create -n maskrcnn python=3.11
conda activate maskrcnn

# 2. Install TensorFlow (M1 Mac)
conda install -c apple tensorflow-deps
pip install tensorflow-macos==2.14.0 tensorflow-metal==1.0.1

# 3. Install dependencies
pip install -r requirements.txt

# 4. Clone repository
git clone https://github.com/yourusername/mask-rcnn-from-scratch.git
cd mask-rcnn-from-scratch
Inference
python
# 1. Create inference model
inference_model = MaskRCNN(mode='inference', config=config, model_dir='./logs')
inference_model.load_weights('path/to/weights.h5', by_name=True)

# 2. Detect
image = cv2.imread('test.jpg')
results = inference_model.detect([image])

# 3. Visualize
r = results[0]
visualize.display_instances(image, r['rois'], r['masks'], 
                           r['class_ids'], class_names, r['scores'])
πŸ“ Project Structure
text
mask-rcnn-from-scratch/
β”‚
β”œβ”€β”€ README.md                       # This file
β”œβ”€β”€ requirements.txt                 # Dependencies
β”‚
β”œβ”€β”€ mrcnn/                           # Core package
β”‚   β”œβ”€β”€ model.py                     # Main implementation (3000+ lines)
β”‚   β”œβ”€β”€ utils.py                     # Utility functions
β”‚   β”œβ”€β”€ config.py                    # Configuration classes
β”‚   └── parallel_model.py            # Multi-GPU support
β”‚
β”œβ”€β”€ examples/                        # Example notebooks
β”‚   β”œβ”€β”€ train.ipynb                  # Training example
β”‚   └── inference.ipynb              # Inference example
β”‚
β”œβ”€β”€ logs/                            # Training logs
β”‚   └── mask_rcnn_YYYYMMDDTHHMM/     # Model checkpoints
β”‚
└── weights/                         # Pre-trained weights
    └── mask_rcnn_coco.h5            # COCO pre-trained
πŸŽ“ Learning Outcomes
By studying this implementation, you will understand:

Concept	What You'll Learn
ResNet Architecture	How identity and conv blocks work together
Feature Pyramid Networks	Multi-scale feature extraction
Region Proposal Networks	Anchor-based object proposal generation
ROI Align	Precise feature extraction without quantization
Instance Segmentation	Pixel-perfect mask prediction
End-to-End Training	How all components train together
Loss Functions	Multi-task learning with 5 losses
Data Pipeline	Efficient data loading and augmentation
πŸ“„ License & Acknowledgments
License
MIT License - See LICENSE file for details.

Acknowledgments
Original Implementation: Matterport Mask R-CNN by Waleed Abdulla

Research Paper: Mask R-CNN by Kaiming He et al.

ResNet Code: Adapted from fchollet/deep-learning-models


🌟 If you find this project useful, please give it a star on GitHub!

About

Mask R-CNN implementation built 100% from scratch using TensorFlow/Keras. Complete object detection and instance segmentation pipeline with ResNet50/101 backbone, FPN, RPN, ROI Align, and detection heads. No imported pre-trained models - every layer is defined from the ground up for complete control and understanding.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages