পাঠ ২০ · ৩৫-এর মধ্যে · মডিউল ৩
Home / AI Courses / Computer Vision / Anchor & NMS

Anchor box ও NMS

Anchor boxes & Non-Maximum Suppression
৭ মিনিট পড়া মাঝারি · Intermediate NumPy কোডসহ

এই পাঠে যা শিখবেন

  • Anchor box-এর role ও design
  • NMS algorithm step-by-step
  • Soft-NMS, Matrix NMS variants
  • NumPy-এ NMS implement

১ · Anchor box কেন

Detection-এ "এই pixel-এ কী object?" — এই question-এর সরাসরি উত্তর কঠিন। কারণ — object size variable, position variable, scale variable।

Solution: pre-define কয়েকটি "guess" box (anchor)। Network-এর কাজ — anchor-এর offset predict (much easier)।

কেন্দ্রীয় ধারণা

Anchor = "starting hypothesis"। Network refine করে "actual box"-এ। Direct regression-এর চেয়ে — anchor-relative regression-এ training stable।

২ · Anchor design

Standard Faster R-CNN/YOLO setup:

  • Scales: 32, 64, 128, 256, 512 px (multi-scale)।
  • Aspect ratios: 1:1, 1:2, 2:1 (sometimes 1:3, 3:1)।
  • Per location: 3 scales × 3 ratios = 9 anchor।
  • FPN: different scale per pyramid level।

৩ · Anchor matching (during training)

Each anchor — match with ground-truth (GT) box:

  • Positive: IoU(anchor, GT) > 0.7 → predict GT class + offset।
  • Negative: IoU < 0.3 → predict "background"।
  • Ignore: 0.3 ≤ IoU ≤ 0.7 → no gradient (ambiguous)।

৪ · Box parameterization

Network predict offset, not absolute box:

$$t_x = (x - x_a) / w_a, \quad t_y = (y - y_a) / h_a$$ $$t_w = \log(w / w_a), \quad t_h = \log(h / h_a)$$

  • $(x_a, y_a, w_a, h_a)$ — anchor box।
  • $(t_x, t_y, t_w, t_h)$ — predicted offsets।
  • Log scale on w, h — multiplicative-এ stable।

৫ · NMS — Non-Maximum Suppression

Detection output dense — same object multiple time। NMS removes duplicates।

Algorithm:

  1. Confidence-এ sort detections (descending)।
  2. Top detection keep।
  3. IoU > threshold (typical 0.5)-এ যেগুলো — discard।
  4. Repeat with next top।
  5. Continue till empty।

৬ · Soft-NMS (২০১৭, Bodla et al.)

Hard discard problem: crowded scene-এ — দু'টি car touching, একটি keep, একটি miss।

Soft-NMS solution: confidence-কে decay (not zero):

$$s_i' = s_i \cdot e^{-\frac{\text{IoU}^2}{\sigma}}$$

  • High IoU — confidence drastically reduce।
  • Low IoU — confidence preserve।
  • Final filter — confidence threshold।

৭ · NMS variants

  • Greedy NMS: standard, simple।
  • Soft-NMS: gradual decay।
  • Weighted NMS: overlapping box-এর coordinate average।
  • Matrix NMS (SOLO): parallelizable।
  • DIoU-NMS: distance-aware IoU।
  • Cluster-NMS: multi-class joint।
Anchor = "guess where boxes might be"। Network's job: refine each guess। NMS = "yelled answers — keep loudest, ignore similar duplicates"। Both heuristic kept ML-based detectors practical for years।
NMS — duplicate detection suppression Before NMS — many overlapping boxes true cat 0.92 0.88 0.81 0.76 NMS IoU > 0.5 After NMS — clean detection cat 0.92 ✓ Algorithm 1) Sort by confidence 2) Pick top 3) Discard IoU > threshold 4) Repeat
NMS — overlapping detections-এর মধ্যে শ্রেষ্ঠ keep, বাকি discard। IoU threshold দিয়ে নিয়ন্ত্রণ।

৮ · NumPy-তে NMS implement

Python · NumPy
import numpy as np

def iou(box, boxes):
    """Compute IoU between one box and array of boxes."""
    x1 = np.maximum(box[0], boxes[:, 0])
    y1 = np.maximum(box[1], boxes[:, 1])
    x2 = np.minimum(box[2], boxes[:, 2])
    y2 = np.minimum(box[3], boxes[:, 3])
    inter = np.maximum(0, x2-x1) * np.maximum(0, y2-y1)
    a1 = (box[2]-box[0]) * (box[3]-box[1])
    a2 = (boxes[:,2]-boxes[:,0]) * (boxes[:,3]-boxes[:,1])
    return inter / (a1 + a2 - inter + 1e-9)

def nms(boxes, scores, thresh=0.5):
    """Greedy NMS. boxes: (N, 4), scores: (N,)."""
    order = scores.argsort()[::-1]
    keep = []
    while len(order) > 0:
        i = order[0]
        keep.append(i)
        ious = iou(boxes[i], boxes[order[1:]])
        order = order[1:][ious <= thresh]
    return keep

# Example
boxes = np.array([
    [10, 10, 50, 50],
    [12, 12, 52, 52],   # overlap with first
    [60, 60, 100, 100], # different region
    [62, 62, 105, 105], # overlap with third
])
scores = np.array([0.9, 0.85, 0.8, 0.75])
keep = nms(boxes, scores, thresh=0.5)
print("Keep indices:", keep)             # [0, 2]
print("Survived boxes:", boxes[keep])

    
৩০ লাইন NumPy-এ pure NMS implementation। Production-এ — torchvision-এর nms() CUDA-optimized।

৯ · Modern: anchor-free + NMS-free

  • FCOS (২০১৯): per-pixel center + size — no anchor।
  • CenterNet: heatmap-based — local maxima।
  • YOLOv8: anchor-free।
  • DETR: NMS-free + anchor-free — set prediction।
Anchor + NMS — ২০১৫-২০২০-এর pillar। Modern paradigm towards anchor-free + NMS-free। কিন্তু production system এখনো বহু এদের use করে। Concept understanding essential।

ভাবনার প্রশ্ন

প্র ০১ NMS threshold (IoU 0.5) — কম বা বেশি করলে কী হয়? Crowded scene-এ optimal কী?

NMS threshold — detection-এর critical hyperparameter।

Threshold low (e.g., 0.3):

  • Aggressive suppression।
  • Touching object-এ একটি miss।
  • Output cleaner কিন্তু missed detection।

Threshold high (e.g., 0.7):

  • Conservative suppression।
  • Duplicate detection survive।
  • Output cluttered, but recall high।

Standard 0.5: COCO benchmark — balanced।

Crowded scene strategies:

  • Higher threshold (0.7) + post-filter।
  • Soft-NMS — gradient decay।
  • DETR — set prediction native।
  • CrowdHuman dataset — specialized model।

Per-class threshold: people 0.7, car 0.5 — empirical tuning।

Bangladesh use case: traffic — overlap inevitable। Soft-NMS or DETR preferred।

মূল উপলব্ধি: Single-number tuning rarely optimal। Domain-specific NMS strategy পরিগণিত।

প্র ০২ Anchor-free detector (FCOS, CenterNet) traditional anchor-based-এর চেয়ে কেন simpler? Performance gap কী?

Anchor-free — design simplification, not just trick।

Anchor-based complexity:

  • Hyperparameter: scale, ratio, count।
  • Matching strategy: IoU thresholds।
  • Domain-specific tuning।
  • Class-agnostic anchor — class-specific scale awkward।

Anchor-free philosophy:

  • Each pixel — predict directly: in object? center? size?
  • FCOS: per-pixel (center, top, bottom, left, right) distance।
  • CenterNet: heatmap of center + size regression।
  • No matching IoU needed।

Advantages:

  • Fewer hyperparameter।
  • Adaptable across dataset।
  • Easy multi-task extension (FCOS supports keypoint, segmentation)।
  • Better small object — direct prediction।

Performance comparison:

  • FCOS COCO: 41.5 mAP (vs RetinaNet 39.1)।
  • YOLOv8 anchor-free: 53.9 mAP (vs YOLOv5 50.7)।
  • Modern era — anchor-free competitive বা better।

Why anchor-free historically lost:

  • Earlier (2018-2019) — anchor-based dominated।
  • Required stronger backbone, FPN।
  • ২০২০+ — DenseBox, FCOS, CenterNet — proper attention।

মূল উপলব্ধি: Anchor — historical solution, not necessary। Modern shift natural progression। Architecture simplicity often wins।

প্র ০৩ Soft-NMS-এর Gaussian decay formula — কেন exponential? Linear decay কী হবে?

Soft-NMS-এর math choice — empirical + principled।

Linear decay:

  • $s' = s \cdot (1 - \text{IoU})$ if IoU > threshold।
  • Simple, no hyperparameter।
  • Works OK।

Gaussian decay:

  • $s' = s \cdot e^{-\text{IoU}^2 / \sigma}$।
  • Smooth, differentiable everywhere।
  • Hyperparameter $\sigma$ controls decay rate।
  • $\sigma$ small — aggressive। Large — gentle।

Comparison (paper):

  • Standard NMS: 39.4 mAP।
  • Linear: 40.0।
  • Gaussian: 40.8।
  • Gaussian wins by 0.8%।

Why Gaussian smoother:

  • Continuous decay — no discontinuity at threshold।
  • Differentiable — useful in trainable NMS variants।
  • Statistically motivated (similar to confidence calibration)।

Implementation:

def soft_nms(boxes, scores, sigma=0.5, conf_thresh=0.001):
    indices = np.argsort(-scores)
    keep = []
    while len(indices) > 0:
        i = indices[0]
        keep.append(i)
        ious = iou(boxes[i], boxes[indices[1:]])
        scores[indices[1:]] *= np.exp(-ious**2 / sigma)
        indices = indices[1:][scores[indices[1:]] > conf_thresh]
    return keep

মূল উপলব্ধি: Math choice — both empirical তাত্ত্বিক justification। Soft-NMS — principled refinement of greedy NMS।

প্র ০৪ DETR (২০২০) NMS-free। কীভাবে set prediction কাজ করে — Hungarian matching মানে কী?

DETR — Carion et al. (Facebook AI Research, 2020) — paradigm shift।

Idea:

  • Fixed N "object queries" (e.g., 100)।
  • Each query — predict (class, box) or "no object"।
  • One-to-one matching with ground-truth।

Hungarian matching:

  • Combinatorial optimization — Kuhn-Munkres algorithm।
  • Bipartite graph: predictions ↔ ground-truth।
  • Edge weight: matching cost (class + bbox + IoU)।
  • Find perfect matching minimum cost।

Cost function:

$\mathcal{L}_{\text{match}} = \lambda_{\text{cls}} \mathcal{L}_{\text{cls}} + \lambda_{\text{bbox}} \mathcal{L}_{\text{bbox}} + \lambda_{\text{IoU}} \mathcal{L}_{\text{IoU}}$

Effect:

  • Each ground-truth → exactly one prediction।
  • Other predictions → "no object" (penalty)।
  • No duplicate by construction।
  • NMS unnecessary।

Why end-to-end?

  • Loss differentiable through Hungarian matching (with smoothing)।
  • Training optimizes detection directly।
  • No anchor matching heuristic।

DETR drawbacks:

  • Slow convergence — 500 epoch typical।
  • Small object struggle।
  • Computationally heavy (transformer)।

Improvements:

  • Deformable DETR — sparse attention।
  • DINO-DETR — anchor-aware queries।
  • RT-DETR — realtime, NMS-free।
  • Co-DETR — collaborative head।

NMS-free trend implication:

  • End-to-end training cleaner।
  • Hyperparameter কম।
  • Crowded scene natural handle।
  • Still GPU expensive।

মূল উপলব্ধি: DETR's set prediction — detection-এর philosophical change। NMS heuristic-এর end ushering. Future direction clear।

অনুশীলন

  1. Anchor count: RetinaNet-এ FPN 5 level, 9 anchor per pixel — 800×800 input-এ total anchor কত?

    FPN levels: 100×100, 50×50, 25×25, 13×13, 7×7। Total spatial = 12463। × 9 anchor = ~112K anchor। NMS-এর importance বোঝা যায়।

  2. NMS torchvision: Multiple-class NMS — torchvision-এর ops use।
    from torchvision.ops import nms, batched_nms
    # Single-class
    keep = nms(boxes, scores, iou_threshold=0.5)
    # Multi-class — batched
    keep = batched_nms(boxes, scores, classes, iou_threshold=0.5)
  3. ভাবুন: Bangladesh CCTV-এ rickshaw dense crowd। Standard NMS-এ অর্ধেক miss। কী করবেন?

    (1) Soft-NMS try। (2) Higher NMS threshold (0.6-0.7)। (3) DETR/RT-DETR — NMS-free। (4) Specialized crowd detector।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

কোড রানার কাজ না করলে? ব্রাউজারে কাজ না করলে Google Colab ব্যবহার করুন — Google-এর ফ্রি অনলাইন Python পরিবেশ, শুধু Gmail অ্যাকাউন্ট লাগে।
পূর্ববর্তী পাঠ
পাঠ ১৯ · YOLO