Option
HeimHeim Skill Datenwissenschaft und ML tao-analyze-gaps-visual-changenet

tao-analyze-gaps-visual-changenet

NVIDIA/skills NVIDIA/skills

Ermittelt die schwächsten Beispiele pro Ground-Truth-Label in NVIDIA TAO VCN Classify-Experimenten, indem ein Docker-Container ausgeführt wird, der einen Schwellenwert-Durchlauf, eine Schwächebewertung und eine Erweiterung nach Beleuchtungsbedingungen durchführt, und stellt anschließend die Top-K schwachen Beispiele für die nachgelagerte Augmentierung oder Neukennzeichnung bereit.

...Alle erweitern
2
Zeit aktualisiert 28. September 2026

TAO VCN Classify – Kompetenz zur Lückenanalyse

Sie sind Analyst für die Inferenzergebnisse von NVIDIA TAO VCN Classify (Visual Component Net). Ihre Aufgabe besteht darin, die schwächsten Beispiele pro Ground-Truth-Label zu identifizieren, indem Sie den vorzeichenbehafteten Abstand vom Entscheidungsschwellenwert in die falsche Richtung messen, und diese anschließend für die nachgelagerte Augmentierung oder Neuklassifizierung herauszufiltern.

Diese Funktion ist bewusst schlank gehalten. Der „Classify“-Head von VCN ist eine binäre Grenze mit einem einzigen Wert (PASS vs. NO_PASS nach siamese_score), sodass die Analyse rechnerisch und nicht untersuchend erfolgt. Die gesamte Berechnung erfolgt über einen einzigen direkten Docker-Lauf des in ` versions.yaml ` deklarierten Images ` tao_toolkit.data_services ` (Auflösung zur Laufzeit – siehe „Setup“). Der Einstiegspunkt des Containers akzeptiert „ [Hydra-Überschreibungen...]“; wir übergeben „gap_analysis vcn_aoi key=value …“. Jede Überschreibung ist ein reines Hydra -Schlüssel-Wert-Paar, das das GapAnalysisConfig -Schema des Skripts selektiv überschreibt (Standardwerte sind im Container fest integriert; Überprüfung mit ` docker run ... gap_analysis vcn_aoi --cfg=job`). (Innerhalb des Containers gibt es kein „dataset“-Schlüsselwort – dies ist das Pillar-Präfix des TAO-Launchers und wird hier weggelassen.) Sie benötigen keine delegierte Analyse, mehrphasige Image-Audits oder Clustering nach Komponententyp – VCN stellt diese Dimensionen nicht zur Verfügung. Sehen Sie sich nach der Rückkehr des Containers nur eine kleine Auswahl repräsentativer schwacher Stichproben an, um die Lücken zu qualifizieren.

Die CLI-Oberfläche kann sich zwischen den Container-Builds der Datendienste unterscheiden. Wenn ein Aufruf von `gap_analysis vcn_aoi ` bei der Argumentauswertung fehlschlägt, überprüfen Sie das tatsächliche Schema einmal pro Image mit ` docker run --rm "$DS_IMAGE" gap_analysis vcn_aoi --cfg=job das tatsächliche Schema pro Image überprüfen und etwaige umbenannte Schlüssel (z. B. `inference_csv` vs. `inference_results_dir`, `output_dir` vs. `results_dir`) abgleichen, bevor Sie es erneut versuchen. Der Name der Parquet-Ausgabedatei lautet `kpi_gaps.parquet`.

Eingaben

  1. Verzeichnis mit den Versuchsergebnissen – enthält die Datei `inference/inference.csv ` aus der TAO-VCN-Classify-Inferenz. Erforderliche Spalten: `input_path`, `object_name`, `label`, `siamese_score`. Übergeben Sie das Verzeichnis (z. B. „inference/latest/“), nicht die CSV-Datei – der Container liest „inference_results_dir/inference.csv“.
  2. Verzeichnis mit Trainingscode/-konfiguration – enthält die VCN-Trainings-YAML-Datei. Der Container liest daraus „dataset.classify.input_map“ (Liste der Lichtverhältnisse) und „dataset.classify.image_ext“, um jede schwache Stichprobe auf eine Zeile pro Lichtverhältnissituation zu erweitern.
  3. Verzeichnis „dataset“ – dem relativen „input_path“ jeder Zeile (kpi_media_path) wird der Bildstamm vorangestellt.
  4. Schema-Überschreibungen – min_recall, top_k_per_label und optional ein festgelegter Schwellenwert werden als Hydra-Überschreibungen übergeben (Standardwerte: min_recall=1,0, top_k_per_label=50, threshold=-1,0, was einen Durchlauf bedeutet). top_k_per_label muss eine positive Ganzzahl sein – wird dieser Wert weggelassen, wechselt der Container in den Modus „Filter unterhalb des Schwellenwerts“, der bei min_recall=1,0 nur PASS-Fehlklassifikationen und null NO_PASS-Zeilen zurückgibt. Siehe „Häufige Fallstricke“.

Einrichtung

Der Schwellenwert-Sweep, das Schwachstellen-Ranking und die Erweiterung pro Beleuchtung laufen alle innerhalb des in ` versions.yaml` deklarierten Images `tao_toolkit.data_services`. Ermitteln Sie die konkrete URI einmalig zu Beginn des Durchlaufs, überprüfen Sie anschließend, ob Docker, das NVIDIA-Container-Toolkit und eine GPU vorhanden sind, und stellen Sie sicher, dass das Image zwischengespeichert ist:

# „tao_toolkit.data_services“ → konkrete URI „nvcr.io/...“ aus „versions.yaml“ auflösen
DS_IMAGE=$(python3 -c "import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'/versions.yaml'))['images']['tao_toolkit']['data_services'])")
echo "DS_IMAGE=$DS_IMAGE"

docker info > /dev/null && echo "OK: Docker"
nvidia-smi > /dev/null && echo "OK: GPU"
docker image inspect "$DS_IMAGE" > /dev/null \
  || docker pull "$DS_IMAGE"

TAO_SKILL_BANK_PATH wird in der Regel von der installierten Skill-Bank exportiert. Falls diese Variable nicht gesetzt ist, verweisen Sie sie vor der Auflösung auf das Stammverzeichnis des Skill-Bank-Repositorys. Eine GPU ist erforderlich; ein frühzeitiger Abbruch auf einem Host ohne GPU verhindert einen verwirrenden Fehler zu einem späteren Zeitpunkt.

Drei Einrichtungsregeln sind entscheidend und können leicht falsch umgesetzt werden:

  • Pfad-Einbindung – jeder Host-Pfad, den der Container liest oder in den er schreibt (inference.csv, Train-YAML, Stammverzeichnis des Datensatz-Images, Ausgabeverzeichnis), muss per Bind-Mount eingebunden werden, am einfachsten mit -v $WORKSPACE:$WORKSPACE -w $WORKSPACE, damit absolute Pfade auf beiden Seiten identisch aufgelöst werden.
  • Übergeben Sie nicht `--user $(id -u):$(id -g) ` – dies löst während des Imports von `transformers` durch den Container einen `KeyError: 'getpwuid(): uid not found: '` aus; stattdessen gibt `chown` anschließend die Host-UID zurück.
  • -e ist erforderlich, nicht optional – aktuelle Images verlangen dies zwingend und beenden den Vorgang mit „ValueError: Die Unteraufgabe vcn_aoi benötigt das folgende Argument: -e/--experiment_spec_file“, bevor CLI-Überschreibungen geparst werden.

Siehe „references/container-setup.md“ für das vollständige Muster zur Pfad-Einbindung, die Begründung für„--user/chown“ und den Alpine- Befehl „chown“, Hinweise zu „multi--v“ sowie Details zur Anforderung „-e “.

Vorgehensweise

Die gesamte Funktion besteht aus einem einzigen Aufruf von ` docker run`, gefolgt von einer kurzen visuellen Stichprobenprüfung. Der Container führt die Schritte 1–4 intern aus (Schwellenwertdurchlauf, Schwachstellenbewertung, Top-K-Auswahl, Erweiterung pro Beleuchtung). Sie führen Schritt 5 (visuelle Stichprobenprüfung) direkt mit dem Read-Tool durch.

Schritte 1–4 – Container ausführen

$DOCKER gap_analysis vcn_aoi \
    inference_results_dir=/inference/

Übergeben Sie immer „top_k_per_label“. Dies ist das Argument, das den Container vom Standardfilter „Beispiele unterhalb des Schwellenwerts“ auf ein korrektes Top-K-per-Label- Ranking umstellt. Bei `min_recall=1.0` liegt der Schwellenwert konstruktionsbedingt bei oder unter jedem `NO_PASS`-Wert, sodass der Filter „unterhalb des Schwellenwerts“ NUR falsch klassifizierte `PASS`-Zeilen und null `NO_PASS`-Zeilen zurückgibt – als Augmentationswarteschlange somit nutzlos. Wenn „top_k_per_label“ auf eine positive Ganzzahl gesetzt ist (entweder in der Spezifikation oder als Hydra-Überschreibung), berechnet der Container für jede Zeile die signierte Schwäche im Vergleich zum Schwellenwert und liefert die K schwächsten Zeilen pro Ground-Truth-Label, was die nach Label geordnete Ausgabe darstellt, die von den nachgelagerten Schritten verarbeitet wird.

Liest „inference.csv“, durchläuft jeden eindeutigen „siamese_score“-Wert sowie einen Wert knapp unterhalb des Minimums, behält die Kandidaten mit einem „NO_PASS“-Recall ≥ „min_recall“ (mit einer Toleranz von 1e-12 ) bei und wählt dann den Schwellenwert mit dem besten F1-Wert aus (bei Gleichstand: Präzision, dann Schwellenwert). Für jede Zeile wird die vorzeichenbehaftete Schwäche ausgehend von diesem Schwellenwert berechnet (positiv = falsch klassifiziert, negativ = korrekt, Betrag = Abstand). Sortiert nach Schwäche in absteigender Reihenfolge und wählt die besten top_k_per_label pro Ground-Truth-Label aus; anschließend wird jede schwache Zeile mithilfe von dataset.classify.input_map und dataset.classify.image_ext aus der Trainings-YAML-Datei in eine Zeile pro Beleuchtungsbedingung erweitert.

Wenn kein Schwellenwertkandidat das Recall-Ziel erfüllt, beendet der Container den Vorgang mit einem Ergebnis ungleich Null und schreibt die Datei „unreachable_kpi.txt“ in das Verzeichnis „results_dir“, in der erläutert wird, welchen Recall das Modell tatsächlich erreichen kann. In diesem Fall brechen Sie die Analyse nach dem Docker-Aufruf ab, erstellen einen einteiligen Bericht, in dem erläutert wird, dass das Modell den KPI grundsätzlich an keinem Betriebspunkt erreichen kann, und empfehlen ein erneutes Training oder eine Neuklassifizierung – überspringen Sie dabei die visuelle Stichprobenprüfung.

Der Container schreibt in das Verzeichnis „results_dir“:

Artefakt Inhalt
kpi_gaps.parquet Die Top-K schwächsten Ergebnisse pro Label, aufgeschlüsselt nach Beleuchtungsbedingungen. Spalten: Dateipfad, Label, siamese_score, Schwäche.
threshold.txt Gewählter Entscheidungsschwellenwert (einzelner Float-Wert, Klartext).
metrics.json Bei dem gewählten Schwellenwert: Präzision, Recall, F1, Verwechslungsmatrix {tp, fp, tn, fn}, sowie pro Label {Gesamt, mean_weakness, median_weakness, max_weakness, n_misclassified}.
weak_samples_breakdown.txt Aufschlüsselung der beibehaltenen Zeilen pro Label: Gesamt, <%> von allen beibehaltenen Zeilen: N falsch klassifiziert (Schwäche > 0), N grenzwertig (Schwäche ≤ 0).
unreachable_kpi.txt Wird nur geschrieben, wenn das Recall-Ziel unerreichbar ist. Das Vorhandensein dieser Datei bedeutet: Schritt 5 überspringen, den gekürzten Bericht schreiben, ein erneutes Training empfehlen.

Geben Sie die Zusammenfassung der Standardausgabe des Containers (gewählter Schwellenwert, Anzahl der beibehaltenen Zeilen, Aufschlüsselung nach Label) in Ihre eigene Standardausgabe aus, damit der Skript-Check-Hook die vom Lauf erzeugte Ausgabe überprüfen kann.

Schritt 5 – Visuelle Stichprobenprüfung (klein, fest)

Überspringe diesen Schritt, wenn „unreachable_kpi.txt“ existiert. Andernfalls verwende das Read-Tool, um die 5 schwächsten PASS-Beispiele und die 5 schwächsten NO_PASS-Beispiele aus „kpi_gaps.parquet“ anzuzeigen (dedupliziert auf eine Zeile pro Beispiel unter Verwendung des FIRST-Lighting-Dateipfads), klassifizieren Sie jede als genau eine der Kategorien „falsch beschriftet“ / „Grenzfall“ / „Datenqualität“ / „systematisch“ und kopieren Sie jedes angezeigte Bild (auf 128×128 skaliert, falls PIL verfügbar ist, andernfalls einfach kopieren) in „/rca_images/“. Dies ist die einzige erforderliche Bildprüfung – betrachten Sie keine Dutzende von Bildern, führen Sie kein Clustering nach Fehlermodi durch und prüfen Sie keine „Golden Images“ (VCN verfügt über keine „Golden Images“).

Siehe „references/visual-spot-check.md“ für die genaue Sortierreihenfolge bei der Stichprobenauswahl, die Regel zur Duplikatsbereinigung pro Beleuchtungsbedingung, die vollständige Definition jeder Bewertungskategorie und die Details zum Kopieren der Bilder.

Aufruf des Skripts

Fügen Sie den Arbeitsbereich, die vier Pfade und die beiden numerischen Einstellparameter ein und bearbeiten Sie sie; dies führt den Test durchgängig aus. Erfassen Sie die Standardausgabe, damit der Skript-Prüf-Hook die Zeilenanzahlen erkennt.

WORKSPACE=           # wird innerhalb des Containers identisch eingebunden
EXP_DIR=     # enthält „inference/inference.csv“ und „train.yaml“; muss sich innerhalb von $WORKSPACE befinden
DATASET_ROOT=         # Bildstammverzeichnis für Einträge in „inference.csv“ unter „input_path“; muss sich innerhalb von $WORKSPACE befinden
MIN_RECALL=1.0                       # Standardwert „zero-miss“; niedriger einstellen, wenn die KPI-Anforderungen gelockert werden
TOP_K=50                             # Augmentationsbudget pro Label
OUT="$EXP_DIR/rca_results/$(date +%Y-%m-%d_%H%M%S)"
SPEC="$OUT/vcn_aoi_spec.yaml"
IMG=$(python3 -c "import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'/versions.yaml'))['images']['tao_toolkit']['data_services'])")

mkdir -p "$OUT"

# Schreibe die Spezifikation für die Lückenanalyse für diesen Lauf
cat > "$SPEC" <<EOF
min_recall: $MIN_RECALL
top_k_per_label: $TOP_K
EOF

docker run --gpus all --rm --ipc=host \
    -v "$WORKSPACE:$WORKSPACE" -w "$WORKSPACE" \
    "$IMG" gap_analysis vcn_aoi \
    -e "$SPEC" \
    inference_results_dir="$EXP_DIR/inference/latest/" \
    train_config="$EXP_DIR/train.yaml" \
    kpi_media_path="$DATASET_ROOT" \
    results_dir="$OUT"

# Der Container schreibt als Root, wobei --user deaktiviert ist; bei Bedarf wird die Eigentümerschaft wieder auf die Host-UID zurückgesetzt.
docker run --rm -v "$WORKSPACE:/w" alpine chown -R "$(id -u):$(id -g)" "/w/$(realpath --relative-to="$WORKSPACE" "$OUT")"

# Testausgabe, damit der „script-check“-Hook echte Zahlen sieht
python3 - "$OUT" << 'PYEOF'
import json, os, sys
out = sys.argv[1]
unreachable = os.path.join(out, „unreachable_kpi.txt“)
if os.path.isfile(unreachable):
    print(„KPI UNREACHABLE — siehe“, unreachable)
    sys.exit(0)
with open(os.path.join(out, "threshold.txt")) as f:
    print("Schwellenwert:", f.read().strip())
with open(os.path.join(out, "metrics.json")) as f:
    m = json.load(f)
print(f"precision={m['precision']:.4f} recall={m['recall']:.4f} f1={m['f1']:.4f}")
import pandas as pd
df = pd.read_parquet(os.path.join(out, "kpi_gaps.parquet"))
print(f"kpi_gaps.parquet: rows={len(df)}, cols={list(df.columns)}")
print(df['label'].value_counts())
PYEOF

Ausgaben

Schreiben Sie alles in einen Ordner mit Zeitstempel im Verzeichnis für die Versuchsergebnisse. Die Ausgaben des Containers werden direkt dorthin geschrieben; die visuelle Stichprobenprüfung schreibt in den Ordner „rca_images/“; etwaige Laufzeit-Paketierungs-Hooks können nach dem Schreiben von „RCA_Report.md“ Artefakte zur Erfassung von „session/config“ hinzufügen.

/rca_results/JJJJ-MM-TT_HHMMSS/
├── RCA_Report.md              # Vollständiger Bericht zur Lückenanalyse (von Ihnen zu erstellen)
├── kpi_gaps.parquet           # Container: Top-K der schwächsten Ergebnisse pro Label, aufgeschlüsselt nach Beleuchtungsbedingungen
├── threshold.txt              # Container: gewählter Entscheidungsschwellenwert (einzelner Float-Wert)
├── metrics.json               # Container: Verwechslungsmatrix + Verteilungsstatistiken pro Label
├── weak_samples_breakdown.txt # Container: Anzahl pro Label / falsch klassifizierte / marginale Werte
├── unreachable_kpi.txt        # Container: NUR, wenn kein Schwellenwert min_recall erfüllt
├── rca_images/                # Sie: Miniaturansichten der 10 angezeigten schwachen Beispiele
├── rca_config/                # Wird automatisch per Hook kopiert
└── session log/artifacts      # Optional, laufzeitabhängige Erfassung der Paketdaten

Rufen Sie zu Beginn des Laufs den tatsächlichen Zeitstempel ab, indem Sie in Bash den Befehl „date +%Y-%m-%d_%H%M%S“ ausführen. Verwenden Sie KEINE fest codierten Werte und machen Sie keine Schätzungen. Wenn der Benutzer einen benutzerdefinierten Ausgabepfad angibt, verwenden Sie diesen stattdessen, behalten Sie jedoch die gleiche interne Struktur bei.

Häufige Fallstricke

Der schwerwiegendste Fehlermodus ist das Vergessen von „top_k_per_label“, wenn „min_recall=1.0“ gilt: Bei diesem Recall liegt der gewählte Schwellenwert bei oder unter jedem NO_PASS-Wert; ohne „top_k_per_label“ greift der Container daher auf einen Filter „Samples unterhalb des Schwellenwerts“ zurück, der NUR falsch klassifizierte PASS-Zeilen und null NO_PASS-Zeilen zurückgibt, wodurch die Augmentationswarteschlange unterbrochen wird. Fügen Sie immer einen expliziten positiven Wert für „top_k_per_label“ (Standardwert 50) in die Spezifikation oder als Hydra-Überschreibung ein.

Siehe „references/pitfalls.md“ für die vollständige Checkliste, die Folgendes abdeckt: Vergessen von „top_k_per_label“; Übergabe von „--user“; Aufruf nur mit Hydra-Überschreibungen (kein „-e “); Spezifikationsdatei außerhalb von „$WORKSPACE“; Spezifikationsdatei mit ungelösten ??? -Sentinels; Bild nicht abgerufen / falsches Tag; Nichtübereinstimmung bei der Pfad-Einbindung; „unreachable_kpi.txt“ wurde geschrieben; in „inference.csv“ fehlen erforderliche Spalten; im Trainings-YAML-File fehlen „dataset.classify.input_map“ oder „image_ext“; „kpi_media_path“ stimmt nicht mit den „input_path “-Präfixen überein; und im Container wurde keine GPU erkannt.

Struktur des Berichts

Verfassen Sie „RCA_Report.md“ als prägnante (1000–1800 Wörter) Analyse der Rechenlücken – die Tiefe ergibt sich aus genauen Zahlen und einer klaren Maßnahmenliste, nicht aus narrativen Ausführungen. Die vollständige Berichtsvorlage (7 Abschnitte: Fazit, Schwellenwertauswahl, Schwachstellenverteilung, Top-K der schwächsten Beispiele, visuelle Stichprobenprüfung, Aufschlüsselung nach Label, empfohlene Maßnahmen – einschließlich Verwechslungsmatrix und Tabellenlayouts) befindet sich in „references/output-template.md“. Wenn die Datei „unreachable_kpi.txt“ vorhanden ist, ersetzen Sie die Abschnitte 3–6 durch einen einzigen kurzen Abschnitt, in dem der Inhalt dieser Datei zitiert wird, und fassen Sie Abschnitt 7 zu einer einzigen Empfehlung zusammen: Neu trainieren oder neu beschriften.

Ausführungsreihenfolge

  1. Lösen Sie DS_IMAGE aus der Datei „versions.yaml“ (images.tao_toolkit.data_services) auf und führen Sie anschließend einmalig die Befehle „docker info“, „nvidia-smi“ und „docker image inspect "$DS_IMAGE"“ (mit Abruf, falls nicht vorhanden) aus, um die Umgebung zu überprüfen. Brechen Sie den Vorgang mit einer eindeutigen Meldung ab, falls einer der Schritte fehlschlägt.
  2. Führen Sie „date +%Y-%m-%d_%H%M%S“ aus, um den Zeitstempel zu erhalten; erstellen Sie „/rca_results//“.
  3. Schreiben Sie „vcn_aoi_spec.yaml“ in das Verzeichnis mit dem Zeitstempel und füllen Sie dabei „min_recall“ und „top_k_per_label“ aus. Speichern Sie die Datei unter „$WORKSPACE“, damit der Pfad „-e“ innerhalb des Containers aufgelöst wird.
  4. Führen Sie folgenden Befehl aus: `docker run … "$DS_IMAGE" gap_analysis vcn_aoi -e vcn_aoi_spec.yaml inference_results_dir=… train_config=… kpi_media_path=… output_dir=…`. Der Container schreibt die Dateien` kpi_gaps.parquet`, `threshold.txt`, `metrics.json` und `weak_samples_breakdown.txt ` in das Verzeichnis `results_dir`. Geben Sie den gewählten Schwellenwert und die Anzahl der beibehaltenen Zeilen auf die Standardausgabe aus, damit der „script-check“-Hook die vom Lauf erzeugte Ausgabe überprüfen kann.
  5. Falls unreachable_kpi.txt vorhanden ist, überspringe Schritt 6 und schreibe den gekürzten Bericht. Andernfalls fahre fort.
  6. Wähle 10 schwache Samples (die 5 schwächsten „PASS“ + die 5 schwächsten „NO_PASS“) aus „kpi_gaps.parquet“ aus, zeige jedes Testbild mit „Read“ an, klassifiziere es und kopiere es jeweils in „rca_images/“.
  7. Schreiben Sie „RCA_Report.md“ zuletzt – das Schreiben löst den Packaging-Hook aus, der die Sitzungsprotokolle und die Skill-Konfiguration mitkopiert.
Auf GitHub ansehen
---
name: tao-analyze-gaps-visual-changenet
description: Identifies the weakest samples per ground-truth label in NVIDIA TAO VCN Classify experiments by running a Docker container that performs threshold sweep, weakness scoring, and per-lighting expansion, then surfaces top-K weak samples for downstream augmentation or relabeling.
license: Apache-2.0
---

# TAO VCN Classify Gap Analysis Skill

You are an analyst for NVIDIA TAO VCN Classify (Visual Component Net) inference results. Your job is to identify the **weakest samples per ground-truth label** by measuring signed distance from the decision threshold *in the wrong direction*, then surface them for downstream augmentation or relabeling.

This skill is intentionally lightweight. VCN's classify head is a single-score binary boundary (PASS vs NO_PASS by `siamese_score`), so the analysis is computational, not investigative. The whole computation lives behind one direct `docker run` invocation against the `tao_toolkit.data_services` image declared in `versions.yaml` (resolved at runtime — see Setup). The container's entrypoint takes `<category> <action> [hydra overrides...]`; we pass `gap_analysis vcn_aoi key=value …`. Each override is a bare Hydra `key=value` that selectively overrides the script's `GapAnalysisConfig` schema (defaults are baked into the container; introspect with `docker run ... gap_analysis vcn_aoi --cfg=job`). (There is no `dataset` keyword inside the container — that's the TAO launcher's pillar prefix and is dropped here.) You do **not** need delegated analysis, multi-phase image audits, or component-type clustering — VCN does not expose those dimensions. View only a small set of representative weak samples to qualify the gaps after the container returns.

CLI surface can shift between data-services container builds. If a `gap_analysis vcn_aoi` invocation fails on argument parsing, introspect the actual schema once per image with `docker run --rm "$DS_IMAGE" gap_analysis vcn_aoi --cfg=job` and reconcile any renamed keys (e.g. `inference_csv` vs `inference_results_dir`, `output_dir` vs `results_dir`) before retrying. Output parquet name is `kpi_gaps.parquet`.

---

## Inputs

1. **Experiment result directory** — contains `inference/inference.csv` from TAO VCN Classify inference. Required columns: `input_path`, `object_name`, `label`, `siamese_score`. Pass the **directory** (e.g. `inference/latest/`), not the CSV file — the container reads `inference_results_dir/inference.csv`.
2. **Training code/config directory** — contains the VCN train YAML. The container reads `dataset.classify.input_map` (lighting condition list) and `dataset.classify.image_ext` from it to expand each weak sample into one row per lighting.
3. **Dataset directory** — image root prepended to the relative `input_path` from each row (`kpi_media_path`).
4. **Schema overrides** — `min_recall`, `top_k_per_label`, and optionally a hard-pinned `threshold` are passed as Hydra overrides (defaults: `min_recall=1.0`, `top_k_per_label=50`, `threshold=-1.0` meaning sweep). **`top_k_per_label` must be a positive integer** — omitting it flips the container into "below-threshold filter" mode, which at `min_recall=1.0` returns only PASS misclassifications and zero NO_PASS rows. See Common pitfalls.

---

## Setup

The threshold sweep, weakness ranking, and per-lighting expansion all run inside the `tao_toolkit.data_services` image declared in `versions.yaml`. Resolve the concrete URI once at the top of the run, then confirm Docker, the NVIDIA container toolkit, and a GPU are present and ensure the image is cached:

```bash
# Resolve tao_toolkit.data_services → concrete nvcr.io/... URI from versions.yaml
DS_IMAGE=$(python3 -c "import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'/versions.yaml'))['images']['tao_toolkit']['data_services'])")
echo "DS_IMAGE=$DS_IMAGE"

docker info > /dev/null && echo "OK: docker"
nvidia-smi > /dev/null && echo "OK: GPU"
docker image inspect "$DS_IMAGE" > /dev/null \
  || docker pull "$DS_IMAGE"
```

`TAO_SKILL_BANK_PATH` is usually exported by the installed skill bank. If it is unset, point it at the skill-bank repo root before resolving. A GPU is required; aborting early on a GPU-less host saves a confusing late error.

Three setup rules are load-bearing and easy to get wrong:

- **Path mounting** — every host path the container reads or writes (`inference.csv`, train YAML, dataset image root, output dir) must be bind-mounted, simplest with `-v $WORKSPACE:$WORKSPACE -w $WORKSPACE` so absolute paths resolve identically on both sides.
- **Do not pass `--user $(id -u):$(id -g)`** — it triggers `KeyError: 'getpwuid(): uid not found: <uid>'` during the container's `transformers` import; `chown` outputs back to the host UID afterwards instead.
- **`-e <spec>` is required, not optional** — current images hard-require it and exit with `ValueError: The subtask vcn_aoi requires the following argument: -e/--experiment_spec_file` before parsing CLI overrides.

See `references/container-setup.md` for the full path-mounting pattern, the `--user`/`chown` rationale and `alpine` chown command, multi-`-v` guidance, and the `-e <spec>` requirement detail.

---

## Method

The whole skill is a single `docker run` invocation followed by a small visual spot-check. The container does Steps 1–4 internally (threshold sweep, weakness scoring, top-K selection, per-lighting expansion). You handle Step 5 (visual spot-check) directly with the Read tool.

### Step 1–4 — Run the container

```bash
$DOCKER gap_analysis vcn_aoi \
    inference_results_dir=<exp_dir>/inference/<label>/ \
    train_config=<exp_dir>/train.yaml \
    kpi_media_path=<dataset_root> \
    results_dir=<rca_results_dir> \
    top_k_per_label=50
```

> **Always pass `top_k_per_label`.** This is the argument that switches the container
> from the default "samples below threshold" filter into proper top-K-per-label
> ranking. At `min_recall=1.0` the threshold is by construction at-or-below every
> NO_PASS score, so the below-threshold filter returns ONLY misclassified PASS rows
> and zero NO_PASS rows — useless as an augmentation queue. With `top_k_per_label`
> set to a positive integer (either in the spec or as a Hydra override), the
> container computes signed weakness against the threshold for every row and
> surfaces the K weakest **per ground-truth label**, which is the per-label ranked
> output downstream steps consume.

Reads `inference.csv`, sweeps every unique `siamese_score` plus one value just below the minimum, keeps the candidates with NO_PASS-class recall ≥ `min_recall` (with `1e-12` tolerance), then picks the threshold with the best F1 (tie-break: precision, then threshold value). For every row, computes signed weakness from that threshold (positive = misclassified, negative = correct, magnitude = margin). Sorts by weakness descending and takes the top `top_k_per_label` per ground-truth label, then expands each weak row into one row per lighting condition using `dataset.classify.input_map` and `dataset.classify.image_ext` from the train YAML.

If **no** candidate threshold meets the recall target, the container exits non-zero and writes `unreachable_kpi.txt` into `results_dir` explaining which recall the model can actually achieve. In that case, stop the analysis after the docker call, write a one-section report explaining the model fundamentally cannot reach the KPI at any operating point, and recommend retraining or relabeling — skip the visual spot-check.

**Container writes into `results_dir`:**

| Artifact | Contents |
|----------|----------|
| `kpi_gaps.parquet` | Top-K weakest per label, expanded per lighting. Columns: `filepath`, `label`, `siamese_score`, `weakness`. |
| `threshold.txt` | Chosen decision threshold (single float, plain text). |
| `metrics.json` | At the chosen threshold: `precision`, `recall`, `f1`, confusion matrix `{tp, fp, tn, fn}`, plus per-label `{total, mean_weakness, median_weakness, max_weakness, n_misclassified}`. |
| `weak_samples_breakdown.txt` | Per-label kept-row breakdown: `<count>` total, `<%>` of all kept rows, `N` misclassified (weakness > 0), `N` marginal (weakness ≤ 0). |
| `unreachable_kpi.txt` | Only written when the recall target is unreachable. Presence of this file means: skip Step 5, write the abridged report, recommend retrain. |

Print the container's stdout summary (chosen threshold, kept-row counts, per-label breakdown) to your own stdout so the script-check hook can verify the run produced output.

### Step 5 — Visual spot check (small, fixed)

Skip this step if `unreachable_kpi.txt` exists. Otherwise use the Read tool to **view** the 5 weakest PASS samples and the 5 weakest NO_PASS samples from `kpi_gaps.parquet` (deduplicated to one row per sample, using the FIRST-lighting `filepath`), classify each as exactly one of **mislabeled** / **edge case** / **data quality** / **systematic**, and copy each viewed image (resized to 128×128 if PIL is available, otherwise just copy) into `<results_dir>/rca_images/`. This is the only image inspection required — do not view dozens of images, run failure mode clustering, or audit goldens (VCN has no golden images).

See `references/visual-spot-check.md` for the exact sample-selection sort, the per-lighting deduplication rule, the full definition of each verdict category, and the image-copy detail.

---

## Reference invocation

Paste-and-edit the workspace, the four paths, and the two numeric knobs; this runs end-to-end. Capture stdout so the script-check hook sees row counts.

```bash
WORKSPACE=<absolute path>            # mounted identically inside the container
EXP_DIR=<experiment_result_dir>      # contains inference/inference.csv and train.yaml; must be inside $WORKSPACE
DATASET_ROOT=<dataset_root>          # image root for inference.csv input_path entries; must be inside $WORKSPACE
MIN_RECALL=1.0                       # zero-miss default; lower if KPI relaxes
TOP_K=50                             # per-label augmentation budget
OUT="$EXP_DIR/rca_results/$(date +%Y-%m-%d_%H%M%S)"
SPEC="$OUT/vcn_aoi_spec.yaml"
IMG=$(python3 -c "import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'/versions.yaml'))['images']['tao_toolkit']['data_services'])")

mkdir -p "$OUT"

# Write the gap-analysis spec for this run
cat > "$SPEC" <<EOF
min_recall: $MIN_RECALL
top_k_per_label: $TOP_K
EOF

docker run --gpus all --rm --ipc=host \
    -v "$WORKSPACE:$WORKSPACE" -w "$WORKSPACE" \
    "$IMG" gap_analysis vcn_aoi \
    -e "$SPEC" \
    inference_results_dir="$EXP_DIR/inference/latest/" \
    train_config="$EXP_DIR/train.yaml" \
    kpi_media_path="$DATASET_ROOT" \
    results_dir="$OUT"

# Container writes as root with --user dropped; chown back to host UID if needed.
docker run --rm -v "$WORKSPACE:/w" alpine chown -R "$(id -u):$(id -g)" "/w/$(realpath --relative-to="$WORKSPACE" "$OUT")"

# Sanity print so the script-check hook sees real numbers
python3 - "$OUT" << 'PYEOF'
import json, os, sys
out = sys.argv[1]
unreachable = os.path.join(out, "unreachable_kpi.txt")
if os.path.isfile(unreachable):
    print("KPI UNREACHABLE — see", unreachable)
    sys.exit(0)
with open(os.path.join(out, "threshold.txt")) as f:
    print("threshold:", f.read().strip())
with open(os.path.join(out, "metrics.json")) as f:
    m = json.load(f)
print(f"precision={m['precision']:.4f} recall={m['recall']:.4f} f1={m['f1']:.4f}")
import pandas as pd
df = pd.read_parquet(os.path.join(out, "kpi_gaps.parquet"))
print(f"kpi_gaps.parquet: rows={len(df)}, cols={list(df.columns)}")
print(df['label'].value_counts())
PYEOF
```

---

## Outputs

Write everything into a timestamped folder under the experiment result directory. The container's outputs go straight there; the visual spot-check writes `rca_images/`; any runtime packaging hook may add session/config capture artifacts after `RCA_Report.md` is written.

```
<experiment_result_dir>/rca_results/YYYY-MM-DD_HHMMSS/
├── RCA_Report.md              # Full gap analysis report (you write this)
├── kpi_gaps.parquet           # Container: top-K weakest per label, expanded per lighting
├── threshold.txt              # Container: chosen decision threshold (single float)
├── metrics.json               # Container: confusion matrix + per-label distribution stats
├── weak_samples_breakdown.txt # Container: per-label count/misclassified/marginal counts
├── unreachable_kpi.txt        # Container: ONLY when no threshold meets min_recall
├── rca_images/                # You: thumbnails of the 10 viewed weak samples
├── rca_config/                # Auto-copied by hook
└── session log/artifacts      # Optional, runtime-dependent packaging capture
```

At the start of the run, get the real timestamp by running `date +%Y-%m-%d_%H%M%S` in Bash. Do NOT hardcode or guess. If the user specifies a custom output path, use that instead but maintain the same internal structure.

---

## Common pitfalls

The single most consequential failure mode is **forgetting `top_k_per_label` when `min_recall=1.0`**: at that recall the chosen threshold sits at or below every NO_PASS score, so without `top_k_per_label` the container falls back to a "samples below threshold" filter that returns ONLY misclassified PASS rows and zero NO_PASS rows, breaking the augmentation queue. Always include an explicit positive `top_k_per_label` (default 50) in the spec or as a Hydra override.

See `references/pitfalls.md` for the complete checklist, covering: forgetting `top_k_per_label`; passing `--user`; calling with only Hydra overrides (no `-e <spec>`); spec file outside `$WORKSPACE`; spec file with unresolved `???` sentinels; image not pulled / wrong tag; path-mount mismatch; `unreachable_kpi.txt` written; `inference.csv` missing required columns; train YAML missing `dataset.classify.input_map` or `image_ext`; `kpi_media_path` not matching `input_path` prefixes; and no GPU detected from inside the container.

---

## Report Structure

Write `RCA_Report.md` as a tight (1000–1800 word) computational gap analysis — depth comes from accurate numbers and a clear action list, not narrative. The full report template (7 sections: Verdict, Threshold Selection, Weakness Distribution, Top-K Weakest Samples, Visual Spot Check, Per-Label Breakdown, Recommended Actions — with the confusion-matrix and table layouts) is in `references/output-template.md`. When `unreachable_kpi.txt` exists, replace sections 3–6 with a single short section quoting that file's contents and collapse section 7 to one recommendation: retrain or relabel.

---

## Execution Order

1. Resolve `DS_IMAGE` from `versions.yaml` (`images.tao_toolkit.data_services`), then run `docker info`, `nvidia-smi`, and `docker image inspect "$DS_IMAGE"` (pulling if missing) once to confirm the environment. Abort with a clear message if any fail.
2. Run `date +%Y-%m-%d_%H%M%S` to get the timestamp; create `<experiment_result_dir>/rca_results/<timestamp>/`.
3. Write `vcn_aoi_spec.yaml` into the timestamped dir with `min_recall` and `top_k_per_label` filled in. Keep it under `$WORKSPACE` so the `-e` path resolves inside the container.
4. Run `docker run … "$DS_IMAGE" gap_analysis vcn_aoi -e vcn_aoi_spec.yaml inference_results_dir=… train_config=… kpi_media_path=… output_dir=…`. The container writes `kpi_gaps.parquet`, `threshold.txt`, `metrics.json`, `weak_samples_breakdown.txt` into `results_dir`. Print the chosen threshold and kept-row counts to stdout so the script-check hook can verify the run produced output.
5. If `unreachable_kpi.txt` exists, skip Step 6 and write the abridged report. Otherwise continue.
6. Pick 10 weak samples (5 weakest PASS + 5 weakest NO_PASS) from `kpi_gaps.parquet`, view each test image with Read, classify, and copy each into `rca_images/`.
7. Write `RCA_Report.md` last — writing it triggers the packaging hook, which copies session logs and skill config alongside.

Alle Dateien

1 Dateien

tao-analyze-gaps-visual-changenet installieren

Laden Sie die Skill-Dateien herunter und entpacken Sie sie in Ihr Verzeichnis „.claude/skills/“.

ZIP herunterladen

Klonen Sie das Repository und kopieren Sie die Skill-Dateien in Ihr Projekt.

git clone https://github.com/NVIDIA/skills/tree/main/skills/tao-analyze-gaps-visual-changenet # Copy SKILL.md to your .claude/skills/ directory

Kopieren Kopieren
Schnelle Einrichtung: Kopiere den Skill-Ordner nach .claude/skills/ Claude erkennt den Skill automatisch und nutzt ihn.
Repository NVIDIA/skills

Ähnliche Skills

web-search
Zeit aktualisiert 29. Juni 2026
webapp-testing
Zeit aktualisiert 29. Juni 2026
lark-base
Zeit aktualisiert 5. Juli 2026
agentmail
Zeit aktualisiert 29. Juni 2026
OR