Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
277 changes: 267 additions & 10 deletions README.md

Large diffs are not rendered by default.

122 changes: 122 additions & 0 deletions configs/AeroScapes_info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
[
{
"hasInstances": false,
"category": "void",
"catid": 0,
"name": "Background",
"ignoreInEval": false,
"id": 0,
"color": [0, 0, 0],
"trainId": 0
},
{
"hasInstances": false,
"category": "human",
"catid": 1,
"name": "Person",
"ignoreInEval": false,
"id": 1,
"color": [192, 128, 128],
"trainId": 1
},
{
"hasInstances": false,
"category": "vehicle",
"catid": 2,
"name": "Bike",
"ignoreInEval": false,
"id": 2,
"color": [0, 128, 0],
"trainId": 2
},
{
"hasInstances": false,
"category": "vehicle",
"catid": 2,
"name": "Car",
"ignoreInEval": false,
"id": 3,
"color": [128, 128, 128],
"trainId": 3
},
{
"hasInstances": false,
"category": "vehicle",
"catid": 2,
"name": "Drone",
"ignoreInEval": false,
"id": 4,
"color": [128, 0, 0],
"trainId": 4
},
{
"hasInstances": false,
"category": "vehicle",
"catid": 2,
"name": "Boat",
"ignoreInEval": false,
"id": 5,
"color": [0, 0, 128],
"trainId": 5
},
{
"hasInstances": false,
"category": "animal",
"catid": 3,
"name": "Animal",
"ignoreInEval": false,
"id": 6,
"color": [192, 0, 128],
"trainId": 6
},
{
"hasInstances": false,
"category": "void",
"catid": 0,
"name": "Obstacle",
"ignoreInEval": false,
"id": 7,
"color": [192, 0, 0],
"trainId": 7
},
{
"hasInstances": false,
"category": "construction",
"catid": 4,
"name": "Construction",
"ignoreInEval": false,
"id": 8,
"color": [192, 128, 0],
"trainId": 8
},
{
"hasInstances": false,
"category": "nature",
"catid": 5,
"name": "Vegetation",
"ignoreInEval": false,
"id": 9,
"color": [0, 64, 0],
"trainId": 9
},
{
"hasInstances": false,
"category": "flat",
"catid": 6,
"name": "Road",
"ignoreInEval": false,
"id": 10,
"color": [128, 128, 0],
"trainId": 10
},
{
"hasInstances": false,
"category": "nature",
"catid": 5,
"name": "Sky",
"ignoreInEval": false,
"id": 11,
"color": [0, 128, 128],
"trainId": 11
}
]
48 changes: 48 additions & 0 deletions configs/dataset/aeroscapes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Dataset Configuration for CABiNet training on AeroScapes
#
# dataset_path must point at the PRE-CONVERTED dataset produced by
# src/scripts/convert_aeroscapes_to_yolo.py:
#
# <dataset_path>/
# ├── images/{train,val}/ ← RGB JPEGs (uniformly 1280x720)
# └── masks/{train,val}/ ← single-channel PNGs, pixel value = class ID
#
# This is NOT the raw AeroScapes distribution (JPEGImages/, SegmentationClass/,
# ImageSets/) — convert it first:
# python src/scripts/convert_aeroscapes_to_yolo.py \
# --src /path/to/raw/aeroscapes --dst /path/to/converted
#
# All 12 classes are valid trainIds 0-11 — see configs/AeroScapes_info.json.
# No colour palette or lookup table is needed at load time; the conversion
# step's source masks were already single-channel class IDs.
#
# Unlike UAVid, AeroScapes source images are uniformly 1280x720, so there is
# no batch_size=1 validation constraint here — standard batched validation
# works.
#
# NOTE: the source dataset has no test split (only ImageSets/trn.txt and
# val.txt) — the converter only ever produces train/val.

name: aeroscapes
num_classes: 12 # Background(0) … Sky(11); all 12 classes valid, none ignored
cropsize: [720, 720] # native res is 1280x720 (uniform) — smaller than UAVid's 3840x2160
dataset_path: ${oc.env:AEROSCAPES_YOLO_ROOT,''} # path to the CONVERTED dataset root
ignore_idx: 255 # label for genuinely unrecognized pixel values (should not occur)
seed: 0

# Class weights are computed at training startup from a sample of the
# training set via training_config.cls_pw (see configs/train.yaml) — same
# mechanism as uavid.yaml, not a static per-dataset table.

# Training augmentation — same knobs/defaults as configs/dataset/uavid.yaml;
# AeroScapes is also UAV-captured imagery so the same recipe applies.
augmentation:
degrees: 10.0 # rotation ±10° (matches RandomRotate)
translate: 0.05 # small translation, fraction of image size
scale: 0.3 # scale jitter ±30% (continuous)
flipud: 0.2 # vertical flip — AeroScapes includes top-down and oblique views
fliplr: 0.5 # horizontal flip
hsv_h: 0.01 # small hue shift (controlled imaging conditions)
hsv_s: 0.4 # saturation jitter
hsv_v: 0.3 # brightness/value jitter
mixup: 0.1 # probability of blending with a second random sample
72 changes: 72 additions & 0 deletions configs/dataset/aeroscapes_yolo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# AeroScapes dataset configuration for Ultralytics YOLO semantic segmentation
#
# Format: https://docs.ultralytics.com/datasets/semantic/
# Masks: single-channel PNG, pixel value = class index (0-11). 255 remains
# reserved for genuinely unrecognized values.
#
# Pre-processing required
# -----------------------
# Convert the raw AeroScapes distribution (JPEGImages/, SegmentationClass/,
# ImageSets/) to the shared images/+masks/ layout first:
#
# python src/scripts/convert_aeroscapes_to_yolo.py \
# --src /path/to/aeroscapes \
# --dst /path/to/aeroscapes_yolo
#
# Then set the ``path`` field below to /path/to/aeroscapes_yolo.
#
# Class mapping (all 12 classes are valid; none are ignored)
# -----------------------------------------------------------
# 0 Background [ 0, 0, 0]
# 1 Person [192, 128, 128]
# 2 Bike [ 0, 128, 0]
# 3 Car [128, 128, 128]
# 4 Drone [128, 0, 0]
# 5 Boat [ 0, 0, 128]
# 6 Animal [192, 0, 128]
# 7 Obstacle [192, 0, 0]
# 8 Construction [192, 128, 0]
# 9 Vegetation [ 0, 64, 0]
# 10 Road [128, 128, 0]
# 11 Sky [ 0, 128, 128]

# Root path. Ultralytics parses this file with plain YAML (no Hydra/OmegaConf
# env-var resolution), so this must be a literal path — edit it directly for
# your machine, or point `data=` at a copy of this file with your own path.
path: /home/neural_debugger/Downloads/datasets/AeroScapes/AeroScapes-YOLO

train: images/train # relative to path
val: images/val # relative to path
# NOTE: no 'test:' key — the source AeroScapes distribution has no test
# split (only ImageSets/trn.txt and val.txt); the converter never produces one.

# Mask directory (must mirror images/ structure): images/train -> masks/train, etc.
masks_dir: masks # relative to path

# Number of semantic classes (all 12 AeroScapes classes)
nc: 12

# Class names — order must match the integer class IDs above
names:
0: Background
1: Person
2: Bike
3: Car
4: Drone
5: Boat
6: Animal
7: Obstacle
8: Construction
9: Vegetation
10: Road
11: Sky

# Ultralytics training command example
# -------------------------------------
# yolo semantic train \
# model=yolo26n-sem.pt \
# data=configs/dataset/aeroscapes_yolo.yaml \
# imgsz=896 \
# epochs=100 \
# batch=8 \
# device=0
47 changes: 47 additions & 0 deletions configs/dataset/vdd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Dataset Configuration for CABiNet training on VDD (Varied Drone Dataset)
#
# dataset_path must point at the PRE-CONVERTED dataset produced by
# src/scripts/convert_vdd_to_yolo.py:
#
# <dataset_path>/
# ├── images/{train,val,test}/ ← RGB JPEGs (uniformly 4000x3000)
# └── masks/{train,val,test}/ ← single-channel PNGs, pixel value = class ID
#
# This is NOT the raw VDD distribution (train/val/test with src/, gt/
# sub-dirs) — convert it first:
# python src/scripts/convert_vdd_to_yolo.py \
# --src /path/to/raw/VDD --dst /path/to/converted
#
# All 7 classes are valid trainIds 0-6 — see https://github.com/RussRobin/VDD.
# No colour palette or lookup table is needed at load time; the source masks
# were already single-channel class IDs.
#
# Like AeroScapes and unlike UAVid, VDD source images are uniformly
# 4000x3000, so there is no batch_size=1 validation constraint here —
# standard batched validation works. Unlike AeroScapes, VDD ships with a
# real train/val/test split already defined by the source distribution.

name: vdd
num_classes: 7 # Other(0), Wall(1), Road(2), Vegetation(3), Vehicle(4), Roof(5), Water(6)
cropsize: [1024, 1024] # native res is 4000x3000 (uniform) — much larger than UAVid/AeroScapes
dataset_path: ${oc.env:VDD_YOLO_ROOT,''} # path to the CONVERTED dataset root
ignore_idx: 255 # label for genuinely unrecognized pixel values (should not occur)
seed: 0

# Class weights are computed at training startup from a sample of the
# training set via training_config.cls_pw (see configs/train.yaml) — same
# mechanism as uavid.yaml/aeroscapes.yaml, not a static per-dataset table.

# Training augmentation — same knobs/defaults as configs/dataset/uavid.yaml
# and aeroscapes.yaml; VDD is also UAV-captured imagery so the same recipe
# applies.
augmentation:
degrees: 10.0 # rotation ±10° (matches RandomRotate)
translate: 0.05 # small translation, fraction of image size
scale: 0.3 # scale jitter ±30% (continuous)
flipud: 0.2 # vertical flip — VDD includes top-down and oblique views
fliplr: 0.5 # horizontal flip
hsv_h: 0.01 # small hue shift (controlled imaging conditions)
hsv_s: 0.4 # saturation jitter
hsv_v: 0.3 # brightness/value jitter
mixup: 0.1 # probability of blending with a second random sample
61 changes: 61 additions & 0 deletions configs/dataset/vdd_yolo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# VDD (Varied Drone Dataset) configuration for Ultralytics YOLO semantic segmentation
#
# Format: https://docs.ultralytics.com/datasets/semantic/
# Masks: single-channel PNG, pixel value = class index (0-6). 255 remains
# reserved for genuinely unrecognized values.
#
# Pre-processing required
# -----------------------
# Convert the raw VDD distribution (train/val/test, each with src/ and gt/)
# to the shared images/+masks/ layout first:
#
# python src/scripts/convert_vdd_to_yolo.py \
# --src /path/to/VDD \
# --dst /path/to/vdd_yolo
#
# Then set the ``path`` field below to /path/to/vdd_yolo.
#
# Class mapping (all 7 classes are valid; none are ignored)
# -----------------------------------------------------------
# 0 Other (background clutter)
# 1 Wall
# 2 Road
# 3 Vegetation
# 4 Vehicle
# 5 Roof
# 6 Water

# Root path. Ultralytics parses this file with plain YAML (no Hydra/OmegaConf
# env-var resolution), so this must be a literal path — edit it directly for
# your machine, or point `data=` at a copy of this file with your own path.
path: /home/neural_debugger/Downloads/datasets/VDD/VDD-YOLO

train: images/train # relative to path
val: images/val # relative to path
test: images/test # relative to path

# Mask directory (must mirror images/ structure): images/train -> masks/train, etc.
masks_dir: masks # relative to path

# Number of semantic classes
nc: 7

# Class names — order must match the integer class IDs above
names:
0: Other
1: Wall
2: Road
3: Vegetation
4: Vehicle
5: Roof
6: Water

# Ultralytics training command example
# -------------------------------------
# yolo semantic train \
# model=yolo26n-sem.pt \
# data=configs/dataset/vdd_yolo.yaml \
# imgsz=1024 \
# epochs=120 \
# batch=4 \
# device=0
13 changes: 12 additions & 1 deletion configs/train.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ training_config:
optimizer_power: 0.9
warmup_steps: 4000
warmup_start_lr: 1e-5
# Warm-start model weights from a full CABiNet checkpoint trained on a
# (possibly different) dataset — e.g. finetune AeroScapes/VDD from a
# UAVid-trained checkpoint, which converges much faster than
# backbone-only (ImageNet) init. Only parameters whose name AND shape
# match are loaded — the two classifier heads (sized by num_classes) are
# skipped when they differ, everything else (backbone/CAB/spatial/fusion)
# transfers. Independent of `resume` below: this never restores
# optimizer/EMA/epoch state, it's a fresh training run with warm-started
# weights. Accepts either a full training checkpoint (checkpoint_last.pth)
# or a raw model state_dict (*_best.pth).
pretrained_ckpt_path: null
# max_iterations is in OPTIMIZER STEPS (not batches).
# train.py computes this as ceil(epochs * batches_per_epoch / accum_steps).
# Setting it here is optional — if absent, train.py derives it automatically.
Expand All @@ -34,7 +45,7 @@ training_config:

max_grad_norm: 1.0 # Gradient clipping threshold; set to null/0 to disable
log_iter: 20 # Renamed from 'msg_iterations' — clearer intent
experiments_path: experiments/cabinet_experiments_large_1024x1024
experiments_path: experiments/${dataset.name}/cabinet_experiments_large_${dataset.cropsize[0]}x${dataset.cropsize[1]} # Output path for checkpoints, logs, etc.
model_save_name: cabinet.pth
resume: false # Set to true to resume from checkpoint_last.pth in experiments_path

Expand Down
Loading
Loading