File size: 1,838 Bytes
48e3e9e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | """Exact training recipe for LibreYOLO9P2s-visdrone.
Reproduces the released checkpoint: yolo9_p2-s, VisDrone2019-DET, 768 px,
60 epochs, transfer init from stock LibreYOLO9s.pt.
Prepare the dataset first with build_visdrone.py, then:
python train_visdrone.py --data /abs/path/to/visdrone/visdrone.yaml
Notes discovered the hard way:
- lr0=0.01 (the family default) DIVERGES on transfer init; 0.005 is stable.
- Mosaic/mixup HURT on VisDrone (tiling shrinks tiny objects below
detectability); mild hsv + horizontal flip help.
- max_labels must be raised: dense aerial frames exceed the default 100-box
cap, silently dropping ground truth.
- Pass the dataset yaml by ABSOLUTE path.
"""
import argparse
from libreyolo import LibreYOLO9P2
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--data", required=True, help="Absolute path to visdrone.yaml")
parser.add_argument("--epochs", type=int, default=60)
parser.add_argument("--batch", type=int, default=2)
parser.add_argument("--imgsz", type=int, default=768)
parser.add_argument("--workers", type=int, default=2)
parser.add_argument("--name", default="visdrone_p2s_768")
args = parser.parse_args()
model = LibreYOLO9P2(None, size="s")
model.train(
data=args.data,
epochs=args.epochs,
batch=args.batch,
nbs=16, # effective batch 16 via gradient accumulation
imgsz=args.imgsz,
workers=args.workers,
lr0=0.005,
warmup_epochs=5,
mosaic_prob=0.0,
mixup_prob=0.0,
hsv_prob=1.0,
flip_prob=0.5,
max_labels=600,
pretrained="LibreYOLO9s.pt",
name=args.name,
exist_ok=True,
eval_interval=5,
save_period=5,
)
if __name__ == "__main__":
main()
|