Given a dataset of ground-truth boxes, run k-means on (w, h) and return anchor sets per FPN level plus coverage statistics. Use when you need help with skill anchor designer.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill skill-anchor-designer --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Skill Anchor Designer?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-skill-anchor-designer)More formats (shields.io, HTML) on the badges page.
---
name: skill-anchor-designer
description: Given a dataset of ground-truth boxes, run k-means on (w, h) and return anchor sets per FPN level plus coverage statistics. Use when you need help with skill anchor designer.
license: CC-BY-NC-SA-4.0
phase: 4
lesson: 6
metadata:
version: 1.0.0
tags: [computer-vision, detection, anchors, kmeans]
---
# Anchor Designer
Anchors are the single most dataset-specific hyperparameter in an anchor-based detector. Default COCO anchors underperform on cell-culture images, satellite tiles, or small-object surveillance. This skill derives anchors that actually match the target data.
## When to use
- Before a first training run on a new dataset.
- When recall on very small or very large objects is weak on an otherwise healthy model.
- After a major dataset expansion where box size distribution may have shifted.
## Inputs
- `boxes`: numpy array of shape (N, 4) in either `(cx, cy, w, h)` or `(x1, y1, x2, y2)` format; at least 1000 positive boxes recommended.
- `num_anchors_per_level`: usually 3.
- `num_fpn_levels`: usually 3 (P3, P4, P5) or 4.
- `input_size`: training-resolution HxW.
- Optional `strides`: per-level strides; when omitted, take the first `num_fpn_levels` entries of `[8, 16, 32, 64]`. Pass a longer or shorter array explicitly if the detector's FPN has different strides.
## Steps
1. **Normalise boxes** to `(w, h)` pairs in pixel units at `input_size`. Drop any with w or h < 2 pixels.
2. **Run k-means** on `(w, h)` pairs, with `k = num_anchors_per_level * num_fpn_levels`. Use `1 - IoU(box, cluster)` as the distance function, not Euclidean distance — Euclidean on `(w, h)` collapses thin tall boxes and square boxes together. All boxes contribute equally (unweighted); if you have a class-imbalanced dataset and want larger-box recall, repeat rare-class boxes in the input array rather than passing a weight vector.
3. **Sort clusters by area** ascending. Split into `num_fpn_levels` groups of `num_anchors_per_level`. Smallest areas go to the highest-resolution level (smallest stride).
4. **Compute coverage statistics** per level:
- `median IoU` of each ground-truth box to its best anchor at that level.
- `recall@IoU=0.5` — percentage of boxes whose best anchor has IoU >= 0.5.
- `area coverage` — fraction of boxes whose area falls within `[anchor_min_area / 4, anchor_max_area * 4]` of the level.
5. **Report per-level anchors** and flag levels where `recall@IoU=0.5 < 0.9`; that level's anchors do not match the data well and should be retuned or the number of anchors per level increased.
## Report format
```
[anchor-designer]
total boxes: <N>
clusters: <k>
distance metric: 1 - IoU
[level P3 stride=8]
anchors (w, h): [(A, B), (C, D), (E, F)]
median IoU: <X>
recall@IoU=0.5: <X>
coverage: <X>
flag: ok | retune
[level P4 stride=16]
...
[summary]
overall recall@IoU=0.5: <X>
smallest anchor: <w x h>
largest anchor: <w x h>
recommendation: <one sentence if any level flagged>
```
## Rules
- Always use IoU-based distance; Euclidean k-means produces visually reasonable but empirically worse anchors.
- Sort clusters by area, then assign to levels in ascending order.
- When `num_anchors_per_level = 1`, skip k-means entirely: split boxes into `num_fpn_levels` bins by area quantile (e.g. terciles for 3 levels), and set each level's anchor to the per-bin median (w, h). This is more robust than running k-means with `k = num_fpn_levels` on small datasets.
- Never output negative anchor dimensions; clamp at 1.
- If the dataset has < 200 boxes, warn the user that anchor search is unreliable and recommend using default COCO anchors plus more training data.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!