Fix gin config loading + source filter, docs updates
- config_loader: add base_gin_files() to exclude dataset-specific pipeline_*.gin variants from default `python -m src.main` load (pipeline_uav_visloc.gin was overriding pipeline.gin) - main.py: use base_gin_files() in the --gin override branch too - pipeline.gin: source None (both DB + query) — was 'query', which silently dropped all DB satellite crops from discovery - README/CLAUDE/docs: sync source default, tensor format spec Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -118,7 +118,7 @@ SegConfig.default_resolution = 1008
|
||||
|---|---|
|
||||
| `snow and ice` | SegEarth-OV3 классифицирует лёд/снег как `water` при виде сверху — промпт не работает. Проверено на Glacier (Athabasca) |
|
||||
| `beach` / `sand` | Покрыт `sand and gravel ground` |
|
||||
| `bridge` | Слишком редко, перекрывается с `road` |
|
||||
| `bridge` | Слишком редко, перекрывается с `road`. Мосты уже покрываются комбинацией `road` (2) + `water` (4) — для cross-view geolocation достаточно. Open-vocabulary SAM конфликтует между `bridge` и `road` на одних пикселях (нестабильные предсказания). Доли процента площади в аэрофото — near-zero representation, шум без вклада в loss. Добавление 18-го класса потребует перегенерации SafeTensors для всех датасетов (~1.1M изображений). Комбинация road + water на depth map — достаточно уникальная сигнатура моста |
|
||||
| `grassland` / `lawn` | Перекрывается с `vegetation` |
|
||||
| `river` / `sea` / `lake` | Всё покрыто единым `water` |
|
||||
| `sports field` | Слишком редко на полном датасете |
|
||||
@@ -333,6 +333,72 @@ SegConfig(threshold=0.15, prompts=UNIFIED_PROMPTS)
|
||||
|
||||
---
|
||||
|
||||
## Анализ текущего набора 17 классов (2026-04-18)
|
||||
|
||||
### Покрытие по датасетам
|
||||
|
||||
| ID | Класс | World-UAV | UAV_VisLoc | GTA-UAV | Примечания |
|
||||
|:--:|:---|:--:|:--:|:--:|:---|
|
||||
| 0 | background | + | + | + | Catch-all |
|
||||
| 1 | building | + | + | + | Универсальный |
|
||||
| 2 | road | + | + | + | Универсальный |
|
||||
| 3 | vegetation | + | + | + | Универсальный |
|
||||
| 4 | water | + | + | + | + лёд/снег (ограничение модели) |
|
||||
| 5 | sand and gravel ground | + | + | + | Desert, Busan, пляжи |
|
||||
| 6 | rocky terrain | + | — | + | Volcano, Karst, Gorge |
|
||||
| 7 | farmland | + | + | + | Terrace, Plain, с/х сцены |
|
||||
| 8 | railway | + | + | — | Munich, Sydney, городские сцены |
|
||||
| 9 | parking lot | + | + | + | Городские сцены |
|
||||
| 10 | sidewalk | + | + | + | Городские сцены |
|
||||
| 11 | bare soil and plowed field | + | + | + | Главная потеря bg в UAV_VisLoc (~15-20%) |
|
||||
| 12 | roof and rooftop | + | + | + | Дополняет building для вида сверху |
|
||||
| 13 | sports field and playground | — | + | — | Уникальная геометрия, landmark |
|
||||
| 14 | muddy ground and wetland | + | + | **reclassify** | В GTA-UAV 14% false positives → 0% |
|
||||
| 15 | embankment and levee | — | + | — | Прибрежные сцены UAV_VisLoc |
|
||||
| 16 | swimming pool | — | — | + | Пригороды GTA V (Vinewood/Rockford) |
|
||||
|
||||
### Известные перекрытия между классами
|
||||
|
||||
| Пара классов | Проблема | Критичность |
|
||||
|:---|:---|:---|
|
||||
| `farmland` (7) ↔ `bare soil` (11) | Поле без всходов — bare soil, с всходами — farmland. Граница размытая, SAM колеблется. | Низкая — оба покрывают «землю», для CVGL matching семантически близки |
|
||||
| `sidewalk` (10) ↔ `embankment` (15) | Набережная = тротуар или дамба? Промпты конкурируют. | Низкая — embankment активен только в UAV_VisLoc |
|
||||
| `building` (1) ↔ `roof` (12) | Фасад vs крыша сверху. При наклонном виде граница нечёткая. | Низкая — при виде строго сверху roof доминирует, при наклоне — building |
|
||||
| `sand and gravel` (5) ↔ `bare soil` (11) | Песчаная почва — sand или soil? Зависит от контекста. | Низкая — оба покрывают грунт без растительности |
|
||||
|
||||
### Проблемные классы
|
||||
|
||||
1. **`muddy ground and wetland` (14)** — наиболее нестабильный. В GTA-UAV полностью рекласcифицируется (14% ложных → 0%). В World-UAV Wetland (Danube) есть в terrain, но SAM плохо различает от vegetation + bare soil. Класс с наибольшим числом false positives среди всех.
|
||||
|
||||
2. **`rocky terrain` (6)** — нестабилен на красных скалах. Danxia/GrandCanyon плохо определяются как rocky terrain. Известное ограничение SegEarth-OV3, не решаемое сменой промпта.
|
||||
|
||||
3. **`water` (4)** — поглощает лёд/снег. Glacier = water. Промпт `snow and ice` не работает (проверено на Athabasca). Ограничение модели, не набора классов.
|
||||
|
||||
### Узкоспециализированные классы
|
||||
|
||||
- **`swimming pool` (16)** — актуален только для GTA-UAV. В реальных датасетах бассейнов почти нет. Не мешает (0 пикселей = 0 вклад в loss), но занимает слот.
|
||||
- **`embankment` (15)** — актуален преимущественно для UAV_VisLoc (прибрежные сцены). В World-UAV роль минимальна.
|
||||
- **`sports field` (13)** — актуален преимущественно для UAV_VisLoc. В GTA-UAV стадионы закрыты сверху.
|
||||
|
||||
### Отклонённые кандидаты на добавление
|
||||
|
||||
| Класс | Причина отказа | Дата |
|
||||
|:---|:---|:---|
|
||||
| `bridge` | Покрывается комбинацией road (2) + water (4). SAM конфликтует bridge/road на одних пикселях. Доли % площади — near-zero representation. Потребовал бы перегенерации ~1.1M изображений. Комбинация road + water на depth map — достаточная сигнатура моста для CVGL. | 2026-04-18 |
|
||||
| `snow and ice` | SegEarth-OV3 классифицирует лёд/снег как water при виде сверху — промпт не работает. Проверено на Glacier (Athabasca). | — |
|
||||
| `highway` | Покрыт road — SegEarth не различает шоссе и обычную дорогу. | — |
|
||||
| `beach` / `sand` | Покрыт sand and gravel ground. | — |
|
||||
| `grassland` / `lawn` | Перекрывается с vegetation. | — |
|
||||
| `courtyard` | Семантически = bare ground + building. | — |
|
||||
| `fence` / `road marking` | Слишком мелкие объекты для SegEarth на 1008px. | — |
|
||||
| `solar panel` | Редко, мелко, часть rooftop (12). | — |
|
||||
|
||||
### Вывод
|
||||
|
||||
Набор из 17 классов сбалансирован для задачи cross-view geolocation. Основные риски — перекрытия farmland/bare_soil и sidewalk/embankment, но они не критичны для matching. **Расширять набор не рекомендуется** — каждый новый класс замедляет инференс (~0.1-0.2x на промпт) и увеличивает конфликты между промптами SAM.
|
||||
|
||||
---
|
||||
|
||||
## Оценка влияния на производительность
|
||||
|
||||
- Инференс: ~1.8–2.2x медленнее (11 vs 5 text prompts)
|
||||
|
||||
126
docs/tensor_format_spec.md
Normal file
126
docs/tensor_format_spec.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Спецификация тензорных форматов
|
||||
|
||||
Ответы на ключевые вопросы о формате извлечённых данных для downstream использования в NADEZHDA (cross-view geolocation).
|
||||
|
||||
---
|
||||
|
||||
## 1. Формат: dense spatial maps [1, H, W]
|
||||
|
||||
Все 4 модальности — **dense spatial maps** с сохранением пространственной размерности. Не pooled descriptors, не feature maps промежуточных слоёв.
|
||||
|
||||
| Модальность | Key | Shape | Dtype | Диапазон | Тип данных |
|
||||
|:---|:---|:---|:---|:---|:---|
|
||||
| depth | `"depth"` | [1, H, W] | float16 | [0, 1] | Непрерывная relative depth |
|
||||
| edge | `"edge"` | [1, H, W] | float16 | [0, 1] | Непрерывная Sobel magnitude |
|
||||
| chm | `"chm"` | [1, H, W] | float16 | [0, 1] | Непрерывная relative canopy height |
|
||||
| segm | `"segm"` | [1, H, W] | uint8 | [0, 16] | Дискретные class IDs (argmax) |
|
||||
|
||||
**Что это значит для downstream:**
|
||||
|
||||
- Depth, edge, chm — одноканальные continuous maps. Подаются напрямую в lightweight aux-encoder (Conv1x1 или shallow CNN), затем через FiLM injection в DINOv3 patch tokens.
|
||||
- Segmentation — дискретная карта из 17 классов (argmax, не soft probabilities, не logits). Требует embedding layer (one-hot → Conv или `nn.Embedding(17, C)`) перед injection.
|
||||
- Промежуточные feature maps моделей (backbone ViT tokens ~1024 dim) **не сохраняются**. Сохраняются только финальные predictions. Обоснование: backbone features трёх ViT-Large моделей сильно коррелируют с features основного DINOv3 в NADEZHDA — мало complementary информации. Ценность auxiliary модальностей именно в **другом представлении** (геометрия, границы, семантика), а не в дублировании ViT features.
|
||||
|
||||
---
|
||||
|
||||
## 2. Какие слои cached
|
||||
|
||||
### Depth (DA3-LARGE-1.1, 411M параметров)
|
||||
|
||||
- **Тип:** Relative depth, не метрическая (не Metric3D)
|
||||
- **Модель:** Depth Anything 3 с DinoV2-ViTL backbone (24 блока, patch 14, embed 1024)
|
||||
- **Что сохраняется:** Финальный output после DualDPT head — одноканальная карта глубины
|
||||
- **Нормирование:** Per-frame min-max → [0, 1]. Абсолютные значения глубины (в метрах) **теряются** при нормализации
|
||||
- **Что НЕ сохраняется:** Промежуточные features из layers [11, 15, 19, 23], DPT pyramid features (256-1024 ch), confidence maps
|
||||
|
||||
### Edges (Sobel из depth, CPU)
|
||||
|
||||
- **Тип:** Sobel magnitude — непрерывный gradient magnitude, не Canny binary и не learned edges
|
||||
- **Вычисление:** `sqrt(dz_dx² + dz_dy²)` из depth map, ядра Sobel 3×3 нормализованные (/8.0)
|
||||
- **Что сохраняется:** Финальная magnitude map после per-frame max normalization → [0, 1]
|
||||
- **Что НЕ сохраняется:** Направление градиента (dx, dy компоненты по отдельности), ненормализованные значения
|
||||
|
||||
### Segmentation (SegEarth-OV3, SAM 3.1 backbone)
|
||||
|
||||
- **Тип:** Dense class ID map (argmax), не soft probabilities и не raw logits
|
||||
- **Модель:** ViTDet-32L backbone (32 блока, patch 14, embed 1024) + mask decoder + text grounding
|
||||
- **Что сохраняется:** Финальный argmax из 17-class logits → uint8 class IDs [0, 16]
|
||||
- **Что НЕ сохраняется:**
|
||||
- Soft probabilities / logits (потеря информации о confidence и inter-class uncertainty)
|
||||
- Backbone features [B, 1024, H/14, W/14] из global attention blocks [7, 15, 23, 31]
|
||||
- Neck pyramid features [B, 256, H/14..H/1.75, W/14..W/1.75]
|
||||
- Pixel decoder features [B, 256, H, W]
|
||||
- Text embeddings от 17 промптов (вычисляются в runtime, кешируются только в GPU memory)
|
||||
- **Post-processing:** Опционально применяются dark water fix и wetland reclassify **до** сохранения — результат уже post-processed
|
||||
|
||||
### CHM (DINOv3-ViTL16 CHMv2, 337M параметров)
|
||||
|
||||
- **Тип:** Relative canopy height, не абсолютная высота в метрах
|
||||
- **Модель:** DINOv3-ViTL16 backbone (24 блока, patch 16, embed 1024) + DPT head
|
||||
- **Что сохраняется:** Финальный output DPT head → per-frame min-max normalized [0, 1]
|
||||
- **Что НЕ сохраняется:** Backbone features, DPT pyramid, абсолютные значения высоты
|
||||
- **Ограничение:** Инференс **только FP32** (NaN в FP16), конвертация в float16 только при сохранении
|
||||
|
||||
---
|
||||
|
||||
## 3. Captions и text embeddings
|
||||
|
||||
**Не сохраняются.** Ни raw text, ни text embeddings.
|
||||
|
||||
- **SegEarth-OV3** использует text embeddings от 17 промптов (через VETextEncoder) для open-vocabulary grounding. Эти embeddings вычисляются в runtime из строковых промптов и кешируются **только в GPU memory** во время инференса. В SafeTensors файлы не попадают.
|
||||
- **Raw text промптов** хранится в `scripts/seg_classes.py:UNIFIED_PROMPTS` — это исходный код, не часть выходных данных.
|
||||
- Никакие caption/description для изображений не генерируются и не сохраняются.
|
||||
|
||||
**Следствия для downstream:**
|
||||
- Если нужны text-conditioned fusion варианты (F0/F1/F2), text embeddings нужно вычислять заново из raw промптов в `seg_classes.py`. Это не проблема — промпты фиксированы (17 строк), embeddings вычисляются за доли секунды.
|
||||
- Привязки к конкретному text encoder нет — можно использовать любой (CLIP, SigLIP, и т.д.) для вычисления embeddings из тех же промптов.
|
||||
|
||||
---
|
||||
|
||||
## 4. Нормирование
|
||||
|
||||
| Модальность | Нормирование | Per-sample | Диапазон | Исходные значения восстановимы? |
|
||||
|:---|:---|:---:|:---|:---|
|
||||
| depth | min-max: `(x - min) / (max - min + 1e-8)` | Да | [0, 1] | Нет — min/max теряются |
|
||||
| edge | max-normalize: `x / max(x)` | Да | [0, 1] | Нет — max теряется |
|
||||
| chm | min-max: `(x - min) / (max - min + 1e-8)` | Да | [0, 1] | Нет — min/max теряются |
|
||||
| segm | Нет (class IDs) | N/A | {0, 1, ..., 16} | N/A |
|
||||
|
||||
### Влияние на FiLM heads initialization
|
||||
|
||||
**Depth, edge, chm (float16, [0, 1]):**
|
||||
- Диапазон стабилен между изображениями (всегда [0, 1]), но **распределение внутри диапазона сильно варьируется**: пустыня — равномерное, город — бимодальное (здания vs земля), вода — сконцентрировано около одного значения.
|
||||
- Рекомендуемый init: `gamma=1, beta=0` (identity FiLM) — безопасный старт, нормализация уже в [0, 1].
|
||||
- Альтернатива: предварительно вычислить dataset-level mean/std по каждой модальности для BatchNorm перед FiLM.
|
||||
|
||||
**Segmentation (uint8, class IDs):**
|
||||
- Дискретные значения [0, 16] — нельзя подавать как continuous input в FiLM напрямую.
|
||||
- Варианты encoding перед FiLM injection:
|
||||
1. `nn.Embedding(17, C)` → lookup table → spatial [C, H, W] — компактно, learned
|
||||
2. `F.one_hot(segm, 17)` → Conv1x1 → [C, H, W] — явное, deterministic init возможен
|
||||
- Для варианта 2 init: Xavier uniform для Conv1x1 weights, zero bias.
|
||||
|
||||
### Статистика входных тензоров (для калибровки)
|
||||
|
||||
Все три continuous модальности нормализованы per-frame в [0, 1], поэтому:
|
||||
- **Global mean** по датасету ≈ 0.3–0.5 (зависит от модальности и датасета)
|
||||
- **Global std** ≈ 0.2–0.35
|
||||
- Для точной калибровки рекомендуется пройти по subset (1000-5000 изображений) и вычислить running mean/std
|
||||
|
||||
---
|
||||
|
||||
## Сводная таблица
|
||||
|
||||
| Свойство | Depth | Edge | Segm | CHM |
|
||||
|:---|:---|:---|:---|:---|
|
||||
| **SafeTensors key** | `"depth"` | `"edge"` | `"segm"` | `"chm"` |
|
||||
| **Shape** | [1, H, W] | [1, H, W] | [1, H, W] | [1, H, W] |
|
||||
| **Dtype** | float16 | float16 | uint8 | float16 |
|
||||
| **Value range** | [0, 1] | [0, 1] | [0, 16] | [0, 1] |
|
||||
| **Type** | Relative depth | Sobel magnitude | Class IDs (argmax) | Relative height |
|
||||
| **Model** | DA3-LARGE-1.1 | Sobel from depth | SegEarth-OV3 | DINOv3 CHMv2 |
|
||||
| **Backbone** | DinoV2-ViTL (24L) | — | ViTDet (32L) | DINOv3-ViTL (24L) |
|
||||
| **Normalization** | Per-frame min-max | Per-frame max | None | Per-frame min-max |
|
||||
| **Dense/Pooled** | Dense spatial | Dense spatial | Dense spatial | Dense spatial |
|
||||
| **Features cached** | Final output only | Final output only | Final output only | Final output only |
|
||||
| **Captions/embeddings** | — | — | Not saved | — |
|
||||
Reference in New Issue
Block a user