New `hard_mining_k` parameter on InfoNCELoss. When >0 and queue is non-empty, each query row keeps only its K highest-similarity queue entries (via `torch.topk`) as negatives, instead of the full queue. Fully vectorized — no Python loop, no extra forward pass. Rationale: the memory bank grows to 4096 detached gallery embeddings, but most are easy negatives that contribute almost nothing to the gradient. Hard mining focuses compute on the small subset that actually shapes the decision boundary. +2-3% R@1 in similar contrastive setups. Edge cases: - K=0: mining disabled, full queue used (original behavior). - K >= queue size: falls back to full queue (e.g. warmup when queue is small). - Queue empty: in-batch only, no changes. Default in `gtauav_balanced.gin`: K=512 (1/8 of queue). Smoke-train updated to exercise the full memory-bank + mining path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 KiB
Caption Quality Test for Cross-View Geo-Localization
Архитектура системы (v3, 2026-04-21) — GTA-UAV эксперимент
QUERY BRANCH (drone + L1/L2/L3 captions):
drone_img [B,3,256,256] --> DINOv3 ViT-L/16 LVD-1689M (frozen) --> d_img [B,1024]
|
L1 --> DGTRS-CLIP (248 tok) --> z₁ [768] --\ |
L2 --> DGTRS-CLIP (248 tok) --> z₂ [768] ---+-- cat --> MLP(2304→1024→1024) --> d_txt [B,1024]
L3 --> DGTRS-CLIP (248 tok) --> z₃ [768] --/ |
|
q = σ(α_q)·d_img + (1−σ(α_q))·d_txt GatedFusion_q
|
q̂ = q/‖q‖₂ --> query [B,1024]
GALLERY BRANCH (satellite + satellite captions):
sat_img [B,3,256,256] --> DINOv3 ViT-L/16 SAT-493M (frozen) --> s_img [B,1024]
|
sat_L1 --> DGTRS-CLIP --> z₁ --\ |
sat_L2 --> DGTRS-CLIP --> z₂ ---+-- cat --> MLP (shared) --> s_txt [B,1024]
sat_L3 --> DGTRS-CLIP --> z₃ --/ |
|
g = σ(α_g)·s_img + (1−σ(α_g))·s_txt GatedFusion_g
|
ĝ = g/‖g‖₂ --> gallery [B,1024]
Retrieval space: 1024-dim (DINOv3 native, без projection layers)
TextFusionMLP shared между query и gallery (одинаковый формат captions)
Для sat images без captions: s_txt=None → g = s_img (gate passthrough)
LOSS: L = 0.6·CE(q̂·ĝᵀ/τ, targets) + 0.4·CE(ĝ·q̂ᵀ/τ, targets)
τ = 1/exp(logit_scale), learnable, clamped [0.01, 0.1], init=0.07
label_smoothing=0.1
BATCH SAMPLING: MutuallyExclusiveSampler — в одном батче нет двух drone'ов
с пересекающимися sat_candidates (исключает false negatives, которые
иначе появляются из-за multi-positive структуры GTA-UAV).
BASELINE: σ(α_q)=σ(α_g)=1.0, text disabled, DGTRS not loaded
Text hierarchy (L1/L2/L3)
- L1 overview: первое предложение P1 — краткое описание land-cover (15-30 tok)
- L2 full: полные P1 + P2 — inventory + spatial layout (100-200 tok)
- L3 fingerprint: P3 — уникальные landmarks для matching (20-50 tok)
- Fusion: z_text = MLP([z₁; z₂; z₃]) — concat 3×768 → Linear(2304,1024) → GELU → Linear(1024,1024)
- Shared MLP между query и gallery ветками (одинаковый формат captions)
- Satellite captions: 6,546 из 14,640 sat images имеют captions. Для остальных gate passthrough (g = s_img) — per-sample mask в
_fuse_with_maskвозвращает чистые image features для samples без caption (без шума от пустых строк)
Text encoder: DGTRS-CLIP (official architecture)
- Код:
src/models/dgtrs/— из github.com/MitsuiChen14/DGTRS (Apache-2.0) - KPS positional embedding: mask1 (pos 0-19, frozen) + mask2 (pos 20-247, trainable)
- Transformer: sequence-first (LND), nn.MultiheadAttention, 12 layers
- Tokenizer: BPE SimpleTokenizer (248 tokens, vocab 49408)
Trainable parameters: 17.6M из 748M (2.35%)
- MONA adapters (2×DINOv3): 14.0M (2 per block × 24 × 2 encoders, bottleneck=64)
- LoRA (DGTRS-CLIP): 147K (Q+V, rank=4, 12 blocks)
- TextFusionMLP (shared): Linear(2304,1024)+GELU+Linear(1024,1024) = ~3.4M
- gate α_q + α_g: 2 scalars
- logit_scale: 1 scalar (learnable temperature)
- DINOv3 x2 + DGTRS: frozen backbone weights
- Без projection layers — retrieval space = DINOv3 native 1024-dim
- AMP: frozen layers fp16, adapters + loss fp32
Optimizer & Scheduler
- AdamW с per-group LR: projections lr=1e-4, text encoder lr=1e-5
- Linear warmup (2 epochs) + cosine annealing (per-step)
- Gradient clipping: max_norm=1.0
- AMP: fp16 для model forward, fp32 для loss (learnable temperature overflow fix)
Image input: 256x256
DINOv3 ViT-L/16 с patch_size=16 → 16x16=256 patches на 256x256. Train: augmentations (drone: crop+flip+rot+jitter+blur, sat: crop+flip+jitter). Eval: Resize(256) + CenterCrop(256) + ImageNet normalization.
Предыдущая архитектура (v2) — UAV-GeoLoc эксперимент
Использовала GeoRSCLIP ViT-B/32 (512-dim) для обеих веток + template captions.
Код в src/models/dual_encoder.py, src/datasets/visloc_with_captions.py.
Ключевые файлы
V2 (UAV-GeoLoc, GeoRSCLIP)
| Файл | Назначение |
|---|---|
src/models/dual_encoder.py |
GeoRSCLIP + GatedFusion + projection heads |
src/losses/multi_infonce.py |
InfoNCE с cosine temperature schedule |
src/datasets/visloc_with_captions.py |
UAV-GeoLoc loader + template captions из path metadata |
src/training/train.py |
Training loop, логирование loss/gate/tau |
src/eval/evaluate.py |
R@K metrics, delta_r_at_1 |
scripts/compare_runs.py |
Markdown/JSON сравнение baseline vs caption runs |
scripts/generate_captions.py |
Offline caption generation (template/VLM/hybrid) |
V3 (GTA-UAV, DINOv3 + DGTRS-CLIP) — DONE
| Файл | Назначение |
|---|---|
src/models/dgtrs/model.py |
Официальная архитектура DGTRS-CLIP text encoder (Apache-2.0) |
src/models/dgtrs/simple_tokenizer.py |
BPE tokenizer (248 tokens, vocab 49408) |
src/models/asymmetric_encoder.py |
DINOv3ViT + TextFusionMLP + AsymmetricEncoder + GatedFusion + encode_query/encode_gallery (per-sample caption mask) |
src/datasets/gtauav_dataset.py |
GTA-UAV-LR loader + L1/L2/L3 captions + GTAUAVSatGallery/GTAUAVDroneQuery (full retrieval eval) |
src/datasets/mutually_exclusive_sampler.py |
BatchSampler: drone'ы в батче не делят sat_candidates (no false negatives) |
src/losses/multi_infonce.py |
Primary: SymmetricInfoNCE + MoCo queue, learnable τ clamp [0.01, 0.1], weights q2g=0.6 g2q=0.4, hard_mining_k для top-K hardest negatives |
src/losses/weighted_infonce.py |
Alternative: per-sample adaptive label smoothing (активируется loss_type="weighted") |
src/losses/hard_negatives.py |
NegativeMemoryBank (MoCo-style FIFO queue 4096 × 1024) |
src/training/train_gtauav.py |
Training loop: full-gallery _evaluate, mutex sampler wiring, loss_type switch |
scripts/smoke_eval.py / scripts/smoke_train.py |
Регрессионные smoke-тесты для eval и train pipeline |
src/training/trackers.py |
Unified experiment tracker: W&B + TensorBoard + CSV |
src/training/grad_monitor.py |
Gradient norm monitoring per param group |
src/training/gradcam.py |
Grad-CAM visualization для DINOv3 encoders |
src/training/profiling.py |
PyTorch Profiler wrapper + torchinfo model summary |
src/training/plot_metrics.py |
Seaborn/matplotlib plots (каждую эпоху) |
conf/gtauav_balanced.gin |
With text, gate=0.7, 10 epochs |
conf/gtauav_baseline.gin |
No text, gate=1.0 |
conf/gtauav_text_heavy.gin |
Text-heavy, gate=0.3 |
conf/gtauav_image_heavy.gin |
Image-heavy, gate=0.9 |
scripts/make_split.py |
80/20 random split из всех пар |
scripts/filter_segmentation.py |
Scan segm masks, output meta JSON (exclude >=90% bg+water) |
Backbones (v3)
DINOv3 ViT-L/16 — Drone (web pretrained)
- Checkpoint:
nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth - Arch: ViT-L/16, 24 layers, 16 heads, hidden=1024, MLP=4096, 303M params
- Input: 256x256, ImageNet normalization, patch=16 → 256 patches
- Register tokens: 4, RoPE theta=100.0
- Status: frozen
DINOv3 ViT-L/16 — Satellite (sat pretrained)
- Checkpoint:
nn_models/DINO_SAT/model.safetensors - HuggingFace:
facebook/dinov3-vitl16-pretrain-sat493m - Arch: идентична DINO_WEB (ViT-L/16, hidden=1024, 303M params)
- Input: 256x256
- Config:
nn_models/DINO_SAT/config.json— BROKEN (auth error), используем конфиг от DINO_WEB - Status: frozen
DGTRS-CLIP ViT-L-14 (LRSCLIP) — Text encoder
- Checkpoint:
nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt - Код:
src/models/dgtrs/— официальная архитектура из github.com/MitsuiChen14/DGTRS - Text dim: 768, max tokens: 248 (KPS: mask1 pos 0-19 frozen + mask2 pos 20-247 trainable)
- Transformer: 12 layers, 12 heads, sequence-first (LND), QuickGELU
- Tokenizer: BPE SimpleTokenizer (vocab 49408), 248 token context
- Содержит: полную CLIP модель (visual + text), используем только text encoder (124M params)
- Status: partial unfreeze (last resblock + ln_final + text_projection, ~7.6M trainable)
GeoRSCLIP ViT-B/32 (v2, legacy)
- Checkpoint:
checkpoints/RS5M_ViT-B-32.pt - Image encoder: ViT-B/32, 224x224, 512-dim, ~86M params — frozen
- Text encoder: 77 tokens, 512-dim — partial unfreeze
GatedFusion
query = sigma(alpha) * drone_feat + (1 - sigma(alpha)) * text_featalpha— один learnable scalar в logit-spaceinit_gate = 0.7→ начальный вес image = 70%, text = 30%baseline_mode = True→ gate = 1.0, text полностью игнорируется- Gate value логируется каждую эпоху для интерпретации вклада текста
Text Hierarchy (L1/L2/L3)
Три уровня описаний из VLM-generated captions:
| Уровень | Контент | Длина | Источник |
|---|---|---|---|
| L1 overview | Краткое описание сцены | <=30 tok | Конденсация P1 |
| L2 full description | Детальное описание через Qwen3-VL | <=200 tok | Полный P1+P2 |
| L3 fingerprint | Ключевые landmark'ы | <=30 tok | Конденсация P3 |
Все три уровня кодируются одним LRSCLIP (248 tok max). Альтернатива (Stage 2): RemoteCLIP для L1/L3 + LRSCLIP для L2.
Датасет: GTA-UAV-LR
-
RGB:
/home/servml/Документы/datasets/GTA-UAV-LR/- Drone: 33,763 PNG (512x384), altitudes 100-600m
- Satellite: 14,640 PNG (256x256 RGBA)
- Pairs:
cross-area-drone2sate-{train,test}.json(primary split) - Metadata:
*_drone_meta.csv(height, yaw, roll, pitch) - Origin: GTA V simulation (Los Santos)
-
Captions:
/home/servml/Документы/datasets/GTA-UAV-LR-captions/- Drone: 33,411 JSON (32,635 multi-paragraph P1/P2/P3 + 776 short water-only)
- Satellite: 6,546 JSON (все multi-paragraph)
- Формат: 3 абзаца (P1 Inventory + P2 Spatial + P3 Fingerprint)
- Token counts: ~430 output tokens per caption
-
Segmentation:
/home/servml/Документы/datasets/GTA-UAV-LR-aug/- 48,403 images, 17 классов (background, building, road, vegetation, water, ...)
- Modalities: segm/, depth/, edge/, chm/, safetensors/
- Query: 512x512, DB: 256x256
Фильтрация сегментации
Meta-файл meta/seg_filter.json: исключение изображений с >=90% background(class 0) + water(class 4).
- Total: 48,403 → Passed: 37,498 (77.5%) / Excluded: 10,905 (22.5%)
- Drone: 31,188 passed / 2,575 excluded
- Satellite: 6,310 passed / 8,330 excluded (преимущественно open water tiles)
Датасет: UAV-GeoLoc (v2, legacy)
- Путь:
/mnt/data1tb/cvgl_datasets/UAV-GeoLoc/ - Train: 206,108 queries, 94,709 DB crops (140 scenes, Terrain split)
- Val: 62,368 queries, 26,597 DB crops (40 scenes)
- Test: 33,472 queries, 11,684 DB crops (20 scenes)
- Index:
Index/train_query.txt—query_path 0 pos_crop1 pos_crop2 ...
Конфигурации
V3 (GTA-UAV)
Параметры:
- 10 epochs, batch 64, AMP, image 256x256
- Optimizer: AdamW, per-group LR: proj=1e-4, text=1e-5 (10x lower)
- Scheduler: linear warmup (2 epochs) + cosine annealing (per-step)
- Loss: SymmetricInfoNCE (q2g=0.6, g2q=0.4) с learnable τ (init=0.07, clamp [0.01, 0.1])
- Hard mining: top-K=512 hardest negatives per query из MoCo queue (размер 4096);
hard_mining_k=0отключает - Batch sampler: MutuallyExclusiveSampler — batches disjoint по sat_candidates (на bs=8 сохраняет 100% entries)
- Eval: full satellite gallery (~2684 unique tiles для test_20) с multi-match R@K (учитывает все positive/semi-positive)
- Augmentations:
- Drone: RandomResizedCrop(0.7-1.0), HFlip, Rotation(15°), ColorJitter, Grayscale(5%), GaussianBlur
- Satellite: RandomResizedCrop(0.7-1.0), HFlip, ColorJitter, Grayscale(5%)
- Eval: Resize+CenterCrop (clean, no augmentation)
- Split: 80/20 random из всех 33,708 пар (
meta/train_80.json/meta/test_20.json) - Train: 26,966 → 24,891 after seg filter
- Test: 6,742 → 6,252 after seg filter
- Скрипт:
python -m scripts.make_split --ratio 0.8 --seed 42
V3 (GTA-UAV, gin)
| Конфиг | Gate init | Описание |
|---|---|---|
conf/gtauav_balanced.gin |
0.7 (30% text) | Primary test |
conf/gtauav_baseline.gin |
1.0 (no text) | Reference baseline |
conf/gtauav_text_heavy.gin |
0.3 (70% text) | Stress test |
conf/gtauav_image_heavy.gin |
0.9 (10% text) | Image-dominant |
V2 (UAV-GeoLoc, gin)
| Конфиг | Gate init | Описание |
|---|---|---|
conf/balanced.gin |
0.7 (30% text) | Primary test |
conf/baseline_no_text.gin |
1.0 (no text) | Reference baseline |
conf/text_heavy.gin |
0.3 (70% text) | Stress test |
Запуск
V3 (GTA-UAV)
# 1. Filter segmentation (exclude 90%+ background/water)
python -m scripts.filter_segmentation --output meta/seg_filter.json
# 2. Train with gin config (recommended)
python -m src.training.train_gtauav --config conf/gtauav_balanced.gin \
--filter-meta meta/seg_filter.json
# 3. Baseline (no text)
python -m src.training.train_gtauav --config conf/gtauav_baseline.gin \
--filter-meta meta/seg_filter.json
# 4. With diagnostics (W&B + Grad-CAM + Profiler)
python -m src.training.train_gtauav --config conf/gtauav_balanced.gin \
--filter-meta meta/seg_filter.json --wandb --gradcam --profile
# 5. CLI overrides (gin params take priority)
python -m src.training.train_gtauav --config conf/gtauav_balanced.gin \
--filter-meta meta/seg_filter.json \
--gin-param 'TrainConfigGTAUAV.batch_size=16'
# 6. Compare
python -m scripts.compare_runs \
--baseline_report out/gtauav/baseline/eval_report.json \
--full_report out/gtauav/with_text/eval_report.json \
--output out/gtauav/comparison.md
# 7. TensorBoard
tensorboard --logdir out/gtauav/with_text/tb_logs
V2 (UAV-GeoLoc)
python -m src.training.train --config conf/baseline_no_text.gin
python -m src.training.train --config conf/balanced.gin
python -m scripts.compare_runs \
--baseline_report out/caption_test/baseline_no_text/eval_report.json \
--full_report out/caption_test/balanced/eval_report.json \
--output out/caption_test/comparison.md
Метрики и Decision rule
Primary metric: Delta R@1 (drone -> satellite)
| Delta R@1 | Verdict |
|---|---|
| >= +3% | PASS — captions informative, proceed to production |
| +1% to +3% | MARGINAL — add VLM refinement, re-run |
| 0 to +1% | WEAK — redesign caption pipeline |
| < 0 | HARMFUL — critical bug |
Eval metrics: R@1, R@5, R@10 для drone->satellite и satellite->drone Splits (GTA-UAV): cross-area (primary, harder) и same-area (sanity check) Logged per epoch: loss, temperature (tau), gate value (sigma(alpha)), lr
Бюджет времени (RTX 4090, 24 GB)
V3 (GTA-UAV, DINOv3 ViT-L/16, 256x256)
| Фаза | Оценка |
|---|---|
| VRAM: 2x DINOv3-L + LRSCLIP + batch 64 | ~18-22 GB |
| GPU mem (smoke test, batch 4) | 3.1 GB |
| Batch size | 64 (default) |
| Total params | 733M (10.9M trainable, 1.49%) |
V2 (UAV-GeoLoc, GeoRSCLIP)
| Фаза | Время |
|---|---|
| Один training run (10 epochs, 206K queries, batch 128) | ~15-30 мин |
| Full test (3 варианта) | ~1-1.5 ч |
| Evaluation per run | ~2-5 мин |
Связанные проекты
Text Annotation Pipeline
- Путь:
/home/servml/Документы/pikaliov_obsidian/(Полякова ВЕ_Система для генерации текстовых описаний для БПЛА)/2_work/2_text_annotation/code/ - VLM: Qwen3-VL-8B AWQ (1.68 s/img)
- Scoring: SigLIP 2 (drone P3) + CLIP-RSICD (satellite P1+P2)
- Формат описаний: 3 абзаца (P1 Inventory + P2 Spatial Map + P3 Fingerprint)
- Метрики: FDR, FNR, NumAcc, LLaVA-Critic C1-C6
UAV-VisLoc Prepare
- Путь:
/home/servml/Документы/code/Yaroslav/UAV-VisLoc-prepare/scripts/prepare_dataset.py - Статус: выполнен (2026-04-17), данные в
/home/servml/Документы/datasets/UAV_VisLoc_processed/(25 GB) - Задача: нарезка satellite кропов 512x512, stride 256 + resize drone -> 512x512
- Подробности: см. ниже
Downstream: NADEZHDA Teacher (DINOv3 + Multi-FiLM)
caption-test — первый этап валидации. При Δ R@1 >= +3% переход к полному teacher'у:
Этап 1 (caption-test): GeoRSCLIP + GatedFusion(text) → валидация текста
Этап 2 (teacher): DINOv3-L + Multi-FiLM(depth, seg, CHM, normals, text)
Этап 3 (distillation): teacher ~300M → student ~5M → Jetson Orin NX
Auxiliary modalities (предвычисляются из 512x512 офлайн)
| Модальность | Модель | Формат для teacher | Каналы |
|---|---|---|---|
| Depth | DepthAnything V2 | continuous, log(1+d) | 1 |
| Normals | Sobel от depth | continuous | 3 |
| Segmentation | SegFormer-B5 | binary per-class masks (top-K) | 16-17 |
| Canopy Height | Meta HRCH | binary bins (1-5m, 5-15m, >15m) + occupancy | 4-5 |
| Text | Qwen3-VL-8B / MobileCLIP2 | embedding | - |
Асимметрия sat/drone
- CHM: только satellite (модель обучена на nadir, на oblique drone не работает)
- Satellite: ~27 aux каналов, Drone: ~21 aux каналов
Fusion: Multi-FiLM
aux_features → FiLM(γ, β) → γ * DINOv3_tokens + β
Binary masks — natural FiLM gates. Modality dropout: text 0.3, CHM 0.5, seg 0.15, depth 0.1.
Планируемый эксперимент H5
Сравнение T_bin (binary masks) vs T_pyr (native feature pyramids) vs T_hybrid. Прогноз: binary masks лучше на cross-domain из-за робастности к aux-model artifacts.
Датасеты (справочник)
UAV-VisLoc
- Путь:
/home/servml/Документы/datasets/UAV_VisLoc_dataset/ - Структура: 11 маршрутов (папки
01-11), каждая содержит:drone/— drone-снимки (XX_NNNN.JPG)satelliteXX.tif— спутниковая картаXX.csv— GPS-метаданные drone (num, filename, date, lat, lon, height, Omega, Kappa, Phi1, Phi2)
- Исключение: маршрут
09— спутник разбит на 4 тайла (satellite09_01-01.tifи т.д.) - Satellite coordinates:
satellite_ coordinates_range.csv— bbox каждой карты (LT_lat_map, LT_lon_map, RB_lat_map, RB_lon_map) - Splits:
visloc_train.csv,visloc_test.csv— списки drone-снимков (TSV, full absolute paths) - Размеры: Drone 3976x2652 / 3000x2000 (6774 снимков), Satellite от 3000x170 до 43421x38408
- GSD спутника: ~0.30 м/px (единый zoom level Google Earth для всех карт). GSD по долготе варьируется 0.23-0.27 м/px из-за косинусного эффекта широты (40°N vs 25°N), но это не разная высота съёмки. Кроп 512x512 покрывает ~154x154 м везде.
UAV-GeoLoc
- Путь:
/mnt/data1tb/cvgl_datasets/UAV-GeoLoc/ - Подмножества: Country (171 scene), Terrain (200 scenes), Rot (1 scene)
- Формат пар:
positive.json,semi_positive.json,db_postion.txt - Index:
train_query.txt—query_path label pos_crop1 pos_crop2 ... - Drone: синтетика Google Earth Studio 3D, 512x512, FOV 30deg, heights 100/125/150m
- Satellite: кропы из merge.tif, доминирующий размер 200x200
Скрипт подготовки UAV-VisLoc
- Путь:
/home/servml/Документы/code/Yaroslav/UAV-VisLoc-prepare/scripts/prepare_dataset.py - Статус: выполнен (2026-04-17)
Запуск
python scripts/prepare_dataset.py \
--src /home/servml/Документы/datasets/UAV_VisLoc_dataset \
--dst /home/servml/Документы/datasets/UAV_VisLoc_processed \
--crop-size 512 --stride 256 --target-size 512
Pipeline
- Resize drone -> 512x512 (JPEG, quality=95)
- Stitch satellite tiles для маршрута 09 (4 тайла -> 44800x33280)
- Нарезка satellite -> кропы 512x512, stride 256, сохранение без downscale (PNG)
- GPS для каждого кропа из bbox карты + позиция в grid
- Match drone->crop через vectorized haversine (positive = ближайший, semi-positive = +/-1 в grid)
- Metadata:
positive.json,semi_positive.json,db_postion.txt(per route) - Index:
train_query.txt,test_query.txt,train_db.txt,test_db.txt,all_db.txt
Форматы выходных файлов (совместимость с UAV-GeoLoc)
| Файл | Формат |
|---|---|
positive.json |
{frame_id: [crop_name]}, ключ = frame ID без route prefix ("0001") |
semi_positive.json |
{frame_id: [crop1, crop2, ...]}, соседи +/-1 в grid |
db_postion.txt |
tab-separated: name\tlon\tlat\tscale_lon\tscale_lat |
train_query.txt |
route/drone/file.JPG 0 route/DB/img/crop1.png ... |
train_db.txt / test_db.txt |
все кропы всех маршрутов (gallery одинаковая, split по query) |
Результаты (target-size 512)
- Drone: 6,744 images 512x512 (без маршрута 07: 30 excluded)
- Satellite кропов: 74,807 (512x512, без downscale)
- Размер на диске: 25 GB
- Median distance drone->crop: 25.9m, P99: 45.7m
- Память при генерации: до ~8.7 GB RAM (маршрут 09 stitched 44800x33280)
- Разрешение 512 для downstream задач (сегментация, depth, normals); resize до 256x256 в dataloader
Ревью и исправления (2026-04-17)
train_db.txt/test_db.txtсодержали только matched кропы -> теперь все ~74K (полная gallery)db_position.txt->db_postion.txt(совместимость с UAV-GeoLoc), добавлены scale_lon/scale_lat, tab-separatorpositive.jsonключи были filename (01_0001.JPG) -> теперь frame_id (0001)- Semi-positive поиск O(n) -> O(1) через dict lookup по (x,y) grid
- Удален мёртвый код (
haversine_m,defaultdictimport)
Известные ограничения
- Нет val split (только train/test, как в оригинальном UAV-VisLoc)
- 6 drone в маршруте 06 (06_0093-06_0098) за пределами спутниковой карты (distance >1000m)
- Большие спутниковые карты загружаются целиком в RAM при генерации (до 8.7 GB для route 09)