--- license: cc-by-nc-sa-3.0 pipeline_tag: object-detection library_name: libreyolo tags: - object-detection - small-object-detection - tiny-object-detection - aerial - drone - visdrone - yolov9 - libreyolo --- # LibreYOLO9P2s-visdrone: small-object aerial detector (research preview) **yolo9_p2** is a LibreYOLO model family: YOLOv9 with an added **stride-4 (P2) detection scale**. Stock YOLOv9 detects at strides 8/16/32; the P2 head adds a fourth scale at stride 4, so objects in the 4-16 px range land on a grid fine enough to be found. This checkpoint is the **s** size (7.2M params) trained on **VisDrone2019-DET** at **768 px**. > **Research preview.** These weights are trained on VisDrone2019-DET, which is > licensed **CC BY-NC-SA 3.0**, so they are for **non-commercial use only** and > are **not** covered by LibreYOLO's permissive license. The checkpoint detects > the 10 VisDrone aerial classes, not COCO. ## Results (VisDrone2019-DET val, 548 images, pycocotools) | model | AP | AP50 | AP_small | AP_med | AP_large | |---|---|---|---|---|---| | stock yolo9-t (control, 640) | 0.123 | 0.220 | 0.047 | 0.199 | 0.375 | | yolo9_p2-t 640 (same-recipe A/B) | 0.138 | 0.254 | 0.070 | 0.213 | 0.352 | | yolo9_p2-t 960 | 0.209 | 0.358 | 0.129 | 0.300 | 0.397 | | **yolo9_p2-s 768 (this model)** | **0.226** | **0.385** | **0.141** | 0.324 | 0.484 | In a controlled A/B (same recipe, resolution, and transfer init; the only difference was the P2 head), yolo9_p2-t beat stock yolo9-t by **+49% AP_small**, with the textbook size signature: large wins on small objects, slight loss on large ones. Across the project (P2 head + higher resolution + bigger size), small-object AP roughly **doubled** (0.070 → 0.141). The full per-epoch metric history is in [`results.csv`](results.csv). ## Honest scope notes - **Match the architecture to the arena.** On COCO, the same architecture is *worse* than stock YOLOv9 (COCO "small" is 16-32 px, already covered by the stride-8 level). Use this for aerial/tiny-object imagery where objects fall below ~16 px; it is not a general-purpose detector. - **Not SOTA.** Transformer-based small-object detectors (e.g. TinyFormer) reach higher AP on VisDrone at lower resolution. The value here is a simple, fast CNN that substantially improves its own small-object AP. - **Single seed.** Every number is one training run; treat ±1 point as noise. - **Evaluate at 768.** Train/test resolution mismatch tanks the numbers. ## Usage ```python from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9P2s-visdrone.pt") # auto-downloads from this repo results = model.predict("aerial.jpg", imgsz=768, conf=0.25) results[0].show() ``` The `yolo9_p2` family is merged on `dev` but not yet in a PyPI release. Until it is, install LibreYOLO from source: `pip install git+https://github.com/LibreYOLO/libreyolo@dev`. Classes: `pedestrian, people, bicycle, car, van, truck, tricycle, awning-tricycle, bus, motor`. ## Reproduce 1. Download VisDrone2019-DET (train + val) from the official source (https://github.com/VisDrone/VisDrone-Dataset). The images are **not** redistributed here. 2. Convert to YOLO layout with [`build_visdrone.py`](build_visdrone.py) (clean-room converter written from the public annotation spec). 3. Train with [`train_visdrone.py`](train_visdrone.py), the exact recipe that produced this checkpoint (60 epochs, transfer init from stock `LibreYOLO9s.pt`, lr0=0.005, mosaic/mixup off, hsv+flip on, max_labels=600, imgsz=768, effective batch 16). Roughly 10 min/epoch on an RTX 5070 Ti. Training notes that matter: the family default `lr0=0.01` **diverges** on transfer init; use 0.005. Mosaic **hurts** on VisDrone (tiling shrinks tiny objects below detectability); keep it off. ## Attribution - **Dataset:** VisDrone2019-DET, AISKYEYE team, Lab of Machine Learning and Data Mining, Tianjin University, China (CC BY-NC-SA 3.0). - **Base architecture:** YOLOv9 (MIT, MultimediaTechLab/YOLO); P2 extension by LibreYOLO. - **Transfer init:** stock `LibreYOLO9s.pt` (converted upstream YOLOv9-s weights).