Ocena głowicy defektów i testy dymne

Testy dymne głowicy defektów to zautomatyzowana procedura weryfikacyjna, która waliduje integralność strukturalną i podstawową funkcjonalność potoku uczenia maszynowego do detekcji defektów. Potwierdza, że potok — od wstępnego przetwarzania obrazu wejściowego przez transformer wizyjny DINOv3 do 5-etykietowej głowicy klasyfikacyjnej MLP (wielowarstwowy perceptron) — generuje oczekiwane wyniki na syntetycznych lub małych statycznych danych testowych bez awarii, błędów numerycznych lub strukturalnie nieprawidłowych predykcji. Test dymny różni się od pełnej ewaluacji: weryfikuje, że potok jest poprawnie podłączony i działa, a nie że generalizuje na niewidziane dane z wysoką dokładnością.

Schemat techniczny architektury głębokiego uczenia do detekcji defektów strukturalnych pokazujący szkielet transformera wizyjnego DINOv3 zasilający głowicę klasyfikacyjną MLP z pięcioma klasami defektów wyjściowych

Architektura Głowicy Defektów

Głowica defektów to końcowy komponent potoku detekcji defektów strukturalnych TarmacView, odpowiedzialny za mapowanie bogatych reprezentacji cech wyodrębnionych przez szkielet sieciowy na dyskretne przewidywania klas defektów. Zrozumienie architektury zarówno szkieletu, jak i głowicy jest niezbędne do projektowania skutecznych testów dymnych, które walidują integralność każdego komponentu.

Szkielet DINOv3

DINOv3 (samodestylacja bez etykiet, wersja 3), transformer wizyjny opracowany przez Meta AI i wydany w 2023 roku, służy jako szkielet ekstrakcji cech. DINOv3 został wytrenowany z użyciem paradygmatu uczenia samonadzorowanego na starannie dobranym zbiorze 142 milionów nieoznaczonych obrazów (LVD-142M), ucząc się ogólnych reprezentacji wizualnych bez potrzeby jakichkolwiek adnotacji ludzkich. To podejście produkuje cechy, które skutecznie transferują się do zadań downstream, w tym klasyfikacji defektów, segmentacji i detekcji — często przewyższając nadzorowane wstępne trenowanie na ImageNet-1K.

DINOv3 jest dostępny w wielu wariantach modelu o różnych profilach obliczeniowych:

WariantParametryWymiar osadzeniaRozmiar kafelkaWarstwyGłowice
ViT-S/1422 miliony38414×14126
ViT-B/1486 milionów76814×141212
ViT-L/14300 milionów102414×142416
ViT-g/141,1 miliarda153614×144024

Dla potoku detekcji defektów TarmacView wariant ViT-B/14 jest standardową konfiguracją. Z 86 milionami parametrów i 768-wymiarową przestrzenią osadzeń, równoważy zdolność reprezentacyjną z wydajnością obliczeniową odpowiednią do przetwarzania dużych ilości obrazów z inspekcji pasów startowych. Rozmiar kafelka 14×14 oznacza, że wejściowy obraz o rozdzielczości 224×224 pikseli jest dzielony na 16×16 = 256 nienakładających się kafelków, z których każdy jest projektowany w 768-wymiarową przestrzeń osadzeń poprzez wyuczoną projekcję liniową.

Metodologia trenowania DINOv3 łączy kilka kluczowych technik. Samodestylacja z architekturą nauczyciel-uczeń zapewnia, że sieć ucznia uczy się dopasowywać reprezentacje nauczyciela, przy czym nauczyciel jest wykładniczo średnią kroczącą ucznia. iBOT (wstępne trenowanie BERT-a obrazu z internetowym tokenizatorem) stosuje maskowane modelowanie obrazu, gdzie losowe kafelki są maskowane, a model musi przewidzieć reprezentacje zamaskowanych kafelków. Centrowanie Sinkhorn-Knopp z metody SwAV zapobiega zapadaniu się reprezentacji poprzez wymuszanie równomiernego rozkładu w próbkach batcha. Regularyzator KoLeo promuje różnorodność w wyuczonych cechach poprzez karanie podobieństwa cech między bliskimi próbkami.

Dla przypadku użycia detekcji defektów, DINOv3 jest ładowany z wstępnie wytrenowanymi wagami i zazwyczaj zamrażany podczas trenowania głowicy defektów. Zamrożony szkielet ekstrahuje ogólne cechy wizualne — krawędzie, tekstury, gradienty, wzory powierzchniowe — które są wysoce istotne do rozróżniania między nienaruszoną nawierzchnią a pięcioma klasami defektów. Zamrożenie szkieletu redukuje liczbę trenowalnych parametrów z 86 milionów do około 1-3 milionów (w zależności od głębokości głowicy MLP), drastycznie skracając czas trenowania, wymagania pamięci GPU i ryzyko katastroficznego zapominania na małych zbiorach danych specyficznych dla domeny.

Głowica Defektów MLP

Głowica defektów MLP (wielowarstwowy perceptron) to mała sieć neuronowa z przesyłaniem w przód, która przyjmuje zamrożone osadzenia DINOv3 jako dane wejściowe i generuje 5-wymiarowy rozkład prawdopodobieństwa dla pięciu klas defektów: pęknięcie, odprysk, wykwit, odsłonięte zbrojenie i korozja.

Standardowa architektura składa się z:

Warstwy wejściowej: Przyjmuje osadzenie DINOv3 — albo token [CLS] (768-wymiarowy wektor reprezentujący globalną zawartość obrazu), albo zagregowaną reprezentację wszystkich tokenów kafelków. Podejście z tokenem [CLS] jest standardowe, ponieważ DINOv3 jest specjalnie trenowany do produkowania bogatych informacji w tokenie [CLS] podczas samodestylacji.

Warstw ukrytych: Zazwyczaj 1-2 w pełni połączone warstwy z funkcjami aktywacji ReLU lub GELU. Pojedyncza warstwa ukryta może mieć konfigurację 768 → 256 → 5, podczas gdy głębsza konfiguracja może być 768 → 512 → 128 → 5. Każda warstwa ukryta jest followed przez normalizację batcha lub normalizację warstwy w celu stabilizacji trenowania i redukcji wewnętrznego przesunięcia kowariancji. Dropout (wskaźnik 0,2-0,5) jest stosowany między warstwami ukrytymi podczas trenowania jako regularyzator zapobiegający nadmiernemu dopasowaniu, biorąc pod uwagę, że zbiory danych defektów infrastruktury są zazwyczaj małe (500-5000 obrazów).

Warstwy wyjściowej: Liniowa projekcja do 5 jednostek odpowiadających pięciu klasom defektów, po której następuje aktywacja softmax, przekształcająca logity w rozkład prawdopodobieństwa dla klas. Funkcja softmax zapewnia, że wektor wyjściowy sumuje się do 1,0, a każdy element reprezentuje przewidywane prawdopodobieństwo, że obraz wejściowy należy do tej klasy defektu.

Procedura trenowania: Głowica MLP jest trenowana poprzez nadzorowane dostrajanie, podczas gdy szkielet DINOv3 pozostaje zamrożony. Funkcja straty to kategoryczna entropia krzyżowa, porównująca przewidywany rozkład prawdopodobieństwa z zakodowanymi w formacie one-hot etykietami prawdy podstawowej. Trenowanie zazwyczaj używa optymalizatora AdamW ze współczynnikiem uczenia 1e-3 do 1e-4, rozmiarem batcha 32-128 i wczesnym zatrzymywaniem na podstawie straty walidacyjnej. Augmentacja danych (losowa rotacja, poziome odbicie, szum koloru, losowe przycięcie) jest stosowana podczas trenowania w celu poprawy generalizacji.

Dla inferencji, szkielet DINOv3 przetwarza każdy obraz wejściowy w osadzenia tokenów kafelków i [CLS] w jednym przejściu w przód. Osadzenie [CLS] jest ekstrahowane i przepuszczane przez głowicę MLP. Wyjściowe prawdopodobieństwa softmax są progowane (zazwyczaj na poziomie 0,5 lub optymalizowane poprzez analizę ROC), aby wygenerować binarną predykcję dla każdej klasy defektu. Ponieważ pięć klas defektów nie wyklucza się wzajemnie — pojedynczy obszar nawierzchni może wykazywać jednocześnie pęknięcia i odpryski — prognozowane predykcje dla każdej klasy są niezależne, a wynik jest interpretowany jako wieloetykietowy, a nie jednoklasowy.

Integracja z Potokiem TarmacView

W potoku analitycznym TarmacView głowica defektów działa na dwóch poziomach granularności.

Analiza na poziomie kafelka: Powierzchnia pasa startowego jest dzielona na siatkę kafelków obrazu (typowe 224×224 lub 512×512 pikseli przy rozdzielczości inspekcji 0,5-2,0 mm/piksel). Każdy kafelek jest przetwarzany niezależnie przez szkielet DINOv3 i głowicę MLP defektów, generując 5-elementowy wektor prawdopodobieństwa na kafelek. Predykcje na poziomie kafelka są przechowywane jako kolumny na kafelek w wynikach analizy: tile_crack_conf, tile_spalling_conf, tile_efflorescence_conf, tile_exposed_rebar_conf, tile_corrosion_conf.

Agregacja na poziomie klatki: Poszczególne predykcje kafelków w ramach jednej klatki kamery lub sekcji pasa startowego są agregowane w celu uzyskania ocen defektów na poziomie klatki. Metody agregacji obejmują: maksymalne łączenie (maksymalna ufność wśród wszystkich kafelków w klatce), średnie łączenie (średnia ufność), głosowanie top-k (proporcja kafelków przekraczających próg) oraz gęstość przestrzenną (liczba kafelków z defektami na jednostkę powierzchni). Kolumny na poziomie klatki w wynikach obejmują frame_crack_flag, frame_spalling_flag, frame_defect_count i frame_max_defect_conf.

Schemat wyników analizy jest krytycznym komponentem, który testy dymne muszą walidować. Jeśli kolumny ufności na poziomie kafelka lub kolumny agregacji na poziomie klatki brakuje, zostały przemianowane lub zawierają nieprawidłowe wartości (NaN, inf, ujemne prawdopodobieństwa), obliczenia wskaźnika stanu nawierzchni (PCI) i potoki raportowania ulegną awarii.

Asercje Testów Dymnych

Asercje testów dymnych to konkretne, zautomatyzowane sprawdzenia, które weryfikują, czy potok głowicy defektów działa poprawnie. Każda asercja celuje w konkretny tryb awarii i generuje jasny wynik zaliczenia/niezaliczenia, który może być zintegrowany z bramkowaniem potoku CI/CD.

Asercje Walidacji Punktu Kontrolnego

Pierwsza kategoria asercji testów dymnych weryfikuje, czy punkt kontrolny głowicy defektów — zapisany plik wag modelu — jest prawidłowy i możliwy do załadowania. Asercje obejmują:

Istnienie pliku punktu kontrolnego: Test sprawdza, czy plik punktu kontrolnego istnieje pod określoną ścieżką. Wyłapuje to problemy, gdy sesja trenowania nie powiodła się, punkt kontrolny nie został przesłany do rejestru modeli lub ścieżka pliku została nieprawidłowo skonfigurowana w środowisku wdrożeniowym. Asercja to: assert os.path.exists(checkpoint_path), f"Punkt kontrolny nie znaleziony pod {checkpoint_path}".

Walidacja rozmiaru pliku i sumy kontrolnej: Test weryfikuje, że plik punktu kontrolnego ma niezerowy rozmiar i opcjonalnie waliduje jego sumę kontrolną MD5 lub SHA256 względem przechowywanej wartości bazowej. Plik o zerowej liczbie bajtów lub uszkodzone pobranie zostaną tutaj wychwycone. Asercja to: assert os.path.getsize(checkpoint_path) > 0 i opcjonalnie assert sha256(plik) == oczekiwane_sha256.

Możliwość załadowania przez torch: Test ładuje punkt kontrolny za pomocą torch.load() i sprawdza, czy operacja kończy się bez zgłoszenia wyjątku. Wyłapuje to uszkodzone pliki, niezgodności wersji (np. punkt kontrolny zapisany PyTorchem 2.0 próbujący załadować się w PyTorch 1.8) oraz brakujące zależności. Asercja otacza wywołanie ładowania blokiem try/except i kończy się niepowodzeniem przy każdym wyjątku.

Struktura słownika stanu: Po załadowaniu test sprawdza, czy punkt kontrolny zawiera oczekiwane klucze słownika stanu. Dla szkieletu DINOv3 oczekiwane klucze obejmują backbone.cls_token, backbone.patch_embed.proj.weight oraz parametry bloków transformera. Dla głowicy MLP oczekiwane klucze obejmują head.0.weight, head.0.bias, head.2.weight, head.2.bias (dla 2-warstwowego MLP). Test weryfikuje również, że wszystkie oczekiwane klucze są obecne i że nie istnieją nieoczekiwane klucze, co mogłoby wskazywać na niezgodność architektury modelu.

Asercje Przejścia w Przód

Druga kategoria weryfikuje, że przejście w przód przez połączony szkielet i głowicę generuje prawidłowe wyniki.

Walidacja kształtu tensora: Test tworzy syntetyczny tensor wejściowy o oczekiwanym kształcie (typowe [batch_size, 3, height, width] z batch_size=1-4, height=width=224 dla ViT-B/14), przepuszcza go przez model i sprawdza, czy kształt tensora wyjściowego to [batch_size, 5] — dokładnie 5 logitów odpowiadających 5 klasom defektów. Asercja to: assert output.shape == (rozmiar_batcha, 5), f"Oczekiwany kształt (rozmiar_batcha, 5), otrzymano {output.shape}".

Walidacja stabilności numerycznej: Test sprawdza, że żadna wartość wyjściowa nie jest NaN (Nie Liczba), nieskończonością lub ujemną nieskończonością. Wartości NaN mogą powstawać z niestabilności numerycznej w szkielecie transformera (np. przepełnienie logitów atencji), dzielenia przez zero w warstwach normalizacji lub uszkodzonych wag. Asercja to: assert not torch.isnan(output).any(), "Wynik zawiera wartości NaN" i assert not torch.isinf(output).any(), "Wynik zawiera wartości inf".

Walidacja prawdopodobieństwa softmax: Test stosuje softmax do surowych logitów i sprawdza, czy wynikowe prawdopodobieństwa sumują się do 1,0 dla każdej próbki w batchu (w ramach tolerancji zmiennoprzecinkowej, typowo 1e-5). Potwierdza to, że warstwa wyjściowa jest poprawnie skonfigurowana i że żaden krok post-processingu nie uszkadza rozkładu prawdopodobieństwa. Asercja to: assert torch.allclose(probs.sum(dim=1), torch.ones(rozmiar_batcha), atol=1e-5).

Asercje Rozkładu Predykcji

Trzecia kategoria weryfikuje, że model generuje rozsądne rozkłady predykcji, a nie zdegenerowane wyniki.

Sprawdzenie nierównomierności rozkładu: Test sprawdza, że przewidywane prawdopodobieństwa nie są równomierne we wszystkich klasach (co wskazywałoby na model, który nie nauczył się żadnych dyskryminacyjnych cech). Entropia przewidywanego rozkładu jest obliczana i porównywana z minimalnym progiem. Całkowicie równomierny rozkład ma maksymalną entropię (log(5) ≈ 1,61 natów dla 5 klas), podczas gdy pewna predykcja ma niską entropię. Asercja to: assert entropia < 1.5, "Predykcje są prawie równomierne, model może nie być wytrenowany".

Sprawdzenie pokrycia klas: Test uruchamia inferencję na małym zestawie różnorodnych obrazów wejściowych i sprawdza, że każda z 5 klas defektów jest predykcją o najwyższej ufności dla co najmniej jednego wejścia. Weryfikuje to, że żadna klasa nie jest systematycznie tłumiona — na przykład model, który nigdy nie przewiduje “wykwitu”, wskazywałby na brak równowagi w danych treningowych lub problem z konfiguracją głowicy. Asercja to: assert set(przewidziane_klasy) == set(range(5)), f"Klasy {brakujace} nigdy nie przewidziane".

Obsługa klasy tła: Jeśli model zawiera domyślną klasę “brak defektu” lub tła, test dymny weryfikuje, że obraz nienaruszonej nawierzchni — wolny od jakichkolwiek defektów — generuje predykcję tła z ufnością powyżej progu (typowe 0,8). Potwierdza to, że model może poprawnie odrzucać negatywne przykłady, co jest krytyczne dla unikania fałszywych alarmów w inspekcjach produkcyjnych.

Walidacja Punktu Kontrolnego

Walidacja punktu kontrolnego to podstawowy komponent testu dymnego, który potwierdza, że artefakt modelu — zapisane wagi sieci neuronowej — jest nienaruszony, możliwy do załadowania i strukturalnie zgodny z oczekiwaną architekturą. W produkcyjnych systemach ML uszkodzenie punktu kontrolnego lub niezgodność wersji jest jednym z najczęstszych trybów awarii, a wychwycenie go wcześnie w CI/CD zapobiega kaskadowym awariom w dalszych etapach.

Przechowywanie i Wersjonowanie Punktów Kontrolnych

Punkty kontrolne głowicy defektów TarmacView są przechowywane w rejestrze modeli — scentralizowanym magazynie artefaktów z wersjonowaniem, metadanymi i śledzeniem pochodzenia (MLflow Model Registry lub DVC). Każdy punkt kontrolny jest identyfikowany przez unikalną kombinację nazwy modelu, numeru wersji i ID uruchomienia. Sam plik punktu kontrolnego to serializowany słownik stanu PyTorch (typowy model.pt lub checkpoint.pt) zawierający wyuczone parametry zarówno szkieletu DINOv3 (jeśli dostrajany), jak i głowicy MLP.

Test dymny najpierw rozwiązuje ścieżkę punktu kontrolnego z rejestru modeli, obsługując następujące przypadki:

  • Określona wersja: Określona jest konkretna wersja (np. defect-head:v3), a test ładuje tę dokładną wersję.
  • Najnowsza wersja (produkcyjna): Alias “najnowsza produkcyjna” jest rozwiązywany do bieżącego produkcyjnego punktu kontrolnego.
  • Wersja stagingowa: Kandydacki punkt kontrolny oczekujący na promocję do produkcji jest ładowany w celu walidacji przedwdrożeniowej.
  • Punkt kontrolny specyficzny dla gałęzi: Punkt kontrolny z uruchomienia trenowania gałęzi funkcyjnej jest ładowany w celu walidacji na poziomie gałęzi.

Sprawdzenie Spójności Szkieletu

Szkielet DINOv3 to duży model z 86 milionami parametrów dla wariantu ViT-B/14. Test dymny weryfikuje, że załadowany szkielet odpowiada oczekiwanej architekturze poprzez sprawdzenie:

Kształtów tensorów wag: Każdy tensor parametrów w załadowanym słowniku stanu jest weryfikowany względem oczekiwanego kształtu. Na przykład tensor backbone.patch_embed.proj.weight powinien mieć kształt (768, 3, 14, 14) dla ViT-B/14 z 3 kanałami wejściowymi, 768 kanałami wyjściowymi i jądrem kafelka 14×14. Niezgodność kształtu wskazywałaby, że punkt kontrolny był trenowany z inną konfiguracją (inny rozmiar kafelka, inny wymiar osadzenia, inne kanały wejściowe).

Sprawdzenie zakresu numerycznego: Test weryfikuje, że wartości wag mieszczą się w oczekiwanych zakresach numerycznych. Wagi atencji transformera powinny mieć wartości rozłożone w przybliżeniu jako N(0, σ²) z σ zależnym od schematu inicjalizacji. Ekstremalne wartości (|w| > 10) we wszystkich warstwach wskazywałyby na dywergencję trenowania lub uszkodzenie punktu kontrolnego. Sprawdzenie oblicza średnią i odchylenie standardowe każdego tensora parametrów i oznacza wartości odstające.

Spójność osadzenia wyjściowego: Test uruchamia stałe syntetyczne wejście przez szkielet i porównuje rozkład osadzenia wyjściowego z przechowywaną wartością bazową. Wartość bazowa jest generowana podczas pierwszego udanego uruchomienia testu dymnego i przechowywana jako referencja. Asercja sprawdza, że średnia i wariancja osadzenia nie dryfują poza tolerancję (typowe ±5%). Wyłapuje to cichą degradację modelu, która nie generuje wartości NaN lub inf, ale nadal produkuje anormalne osadzenia.

Weryfikacja Architektury Głowicy

Głowica MLP jest mniejsza niż szkielet, ale równie krytyczna. Test dymny weryfikuje:

Liczbę warstw: Głowica powinna mieć dokładnie oczekiwaną liczbę warstw. Dla 2-warstwowego MLP z wymiarem ukrytym 256, oczekiwane klucze obejmują head.0.weight (768×256), head.0.bias (256), head.2.weight (256×5), head.2.bias (5). Numeracja warstw uwzględnia funkcję aktywacji (warstwa 1) między warstwami liniowymi.

Wymiar wyjściowy: Wymiar wyjściowy końcowej warstwy liniowej musi wynosić dokładnie 5, odpowiadający 5 klasom defektów. Jest to weryfikowane przez sprawdzenie head.2.weight.shape[0] == 5.

Spójność inicjalizacji wag: Test sprawdza, że wagi nie są zamrożone na wartościach inicjalizacyjnych (wszystkie zera lub wszystkie jedynki). Głowica z wagami wszystkimi zerowymi generowałaby jednolite logity niezależnie od wejścia, wskazując na niepowodzenie trenowania. Sprawdzenie weryfikuje, że head.2.weight.std() > 0.001.

Weryfikacja Metryk AP i F1

Podczas gdy test dymny dotyczy przede wszystkim integralności potoku, a nie jakości modelu, włączenie lekkiego obliczania metryk do testu dymnego zapewnia wczesne ostrzeżenie o znaczącej regresji modelu. Test dymny oblicza metryki skuteczności na syntetycznych lub małych statycznych danych testowych, porównując je z wartościami bazowymi przechowywanymi z poprzednich zwalidowanych uruchomień.

Obliczanie Średniej Precyzji

Średnia precyzja (AP) to pole pod krzywą precyzji i czułości, obliczane dla progów ufności od 0 do 1. Test dymny oblicza AP dla każdej z 5 klas defektów przy użyciu ewaluacji w stylu COCO:

  1. Predykcje modelu są generowane dla zbioru danych testu dymnego (typowe 50-100 syntetycznych obrazów ze znaną prawdą podstawową).
  2. Dla każdej klasy defektów, predykcje są sortowane według wyniku ufności w kolejności malejącej.
  3. Precyzja i czułość są obliczane dla każdej predykcji, tworząc krzywą precyzji i czułości.
  4. AP jest obliczane jako pole pod tą krzywą przy użyciu metody trapezów.

Asercje AP testu dymnego obejmują:

AP@0.50 (metryka PASCAL VOC): AP przy progu IoU 0,50. Asercja to, że AP@0.50 dla każdej klasy przekracza minimalny próg. Dla syntetycznych danych testowych ze znanymi, czystymi wzorcami defektów, typowy próg to AP@0.50 > 0,85 dla wszystkich 5 klas. Jeśli model osiąga AP@0.50 poniżej tego progu na trywialnych danych syntetycznych, wskazuje to na poważną regresję.

AP@0.50 :0.95 (główna metryka COCO): Średnia wartości AP obliczonych przy progach IoU 0,50, 0,55, …, 0,95. Próg asercji jest niższy — typowo AP@0.50 :0.95 > 0,50 — ponieważ rygorystyczne progi IoU są bardziej wymagające nawet na danych syntetycznych.

Spójność AP między klasami: Wariancja AP między 5 klasami jest sprawdzana. Odchylenie standardowe przekraczające 0,15 wskazywałoby, że jedna klasa uległa znaczącej regresji względem innych, sugerując problem specyficzny dla tego typu defektu (np. niewystarczająca liczba przykładów treningowych dla wykwitów).

Syntetyczny zbiór danych testowych jest starannie skonstruowany, aby zapewnić stabilność metryk. Każdy syntetyczny obraz zawiera dokładnie jeden typ defektu nałożony na teksturę tła przypominającą nawierzchnię. Defekty są generowane przy użyciu technik proceduralnych: pęknięcia jako cienkie, rozgałęzione czarne linie z rozmyciem gaussowskim dla realizmu; odpryski jako nieregularne okrągłe/owalne obszary z chropowatymi krawędziami; wykwity jako białe, amorficzne plamy o zmiennej nieprzezroczystości; odsłonięte zbrojenie jako okresowe ciemne okrągłe wzory; korozja jako nieregularne plamy w kolorze rdzy. Syntetyczny zbiór danych jest wersjonowany i zatwierdzany w repozytorium, aby zapewnić deterministyczne, powtarzalne wyniki testów dymnych.

Weryfikacja Wyniku F1

Wynik F1 to średnia harmoniczna precyzji i czułości, zapewniająca pojedynczą zrównoważoną miarę wydajności modelu. Test dymny oblicza F1 przy stałym progu ufności (typowe 0,5) dla każdej klasy defektów.

Asercje F1 obejmują:

Minimalne F1 na klasę: Każda klasa musi osiągnąć F1 > 0,80 na syntetycznym zestawie testowym. Wieloetykietowy charakter zadania predykcji defektów oznacza, że F1 jest obliczane niezależnie dla każdej klasy.

Makro-średnie F1: Nieważona średnia F1 we wszystkich 5 klasach jest obliczana. Próg asercji to makro-F1 > 0,85. Makro-średnia traktuje wszystkie klasy równo, więc regresja na rzadkiej klasie (np. odsłonięte zbrojenie) jest natychmiast widoczna.

Równowaga precyzji i czułości: Stosunek precyzji do czułości jest sprawdzany dla każdej klasy. Stosunek powyżej 1,5 lub poniżej 0,67 wskazuje na brak równowagi — model jest albo zbyt konserwatywny (wysoka precyzja, niska czułość, pomijając wiele defektów), albo zbyt agresywny (wysoka czułość, niska precyzja, generując wiele fałszywych alarmów). Asercja oznacza każdą klasę, w której stosunek jest poza zakresem [0,67, 1,5].

MetrykaPróg syntetycznego testuCel
AP@0.50> 0,85Podstawowa zdolność detekcji na klasę
AP@0.50 :0.95> 0,50Kompleksowa jakość detekcji
Odchylenie std. AP między klasami< 0,15Sprawdzenie równowagi klas
F1 na klasę> 0,80Zrównoważona precyzja-czułość na klasę
Makro-średnie F1> 0,85Ogólna jakość modelu
Stosunek precyzji/czułości[0,67, 1,5]Równowaga precyzji-czułości na klasę

Porównanie z Bazą i Wykrywanie Dryfu

Test dymny przechowuje wartości bazowe metryk z ostatniego zwalidowanego uruchomienia i porównuje bieżące metryki z tymi wartościami bazowymi. Znaczący spadek (>5% względnego spadku) w dowolnej metryce powoduje niepowodzenie testu dymnego, nawet jeśli bezwzględna wartość metryki jest powyżej minimalnego progu. Wyłapuje to stopniową degradację — modele, które przechodzą bezwzględne progi, ale stale tracą wydajność w kolejnych sesjach trenowania lub aktualizacjach danych.

Historie metryk są rejestrowane w bazie danych szeregów czasowych (MLflow, Weights & Biases lub prosty plik CSV w repozytorium). Test dymny odczytuje ostatnie 10 zwalidowanych wartości metryk i dopasowuje trend liniowy. Jeśli nachylenie jest ujemne i statystycznie istotne (p < 0,05), test generuje ostrzeżenie, ale nie kończy się niepowodzeniem — tylko niepowodzenie progowe jest używane do bramkowania CI/CD, aby uniknąć zakłóceń potoku z powodu drobnych wahań metryk.

Weryfikacja Kolumn Wyników Analizy

Krytyczny test dymny waliduje, że wyniki analizy — dane strukturalne wyprodukowane przez uruchomienie głowicy defektów na obrazach inspekcyjnych — zawierają wszystkie oczekiwane kolumny z prawidłowymi typami danych i prawidłowymi wartościami. Wypełnia to lukę między inferencją modelu a dalszym obliczaniem wskaźnika stanu nawierzchni (PCI), raportowaniem i integracją GIS.

Oczekiwany Schemat Kolumn

Wyniki analizy TarmacView to format tabelaryczny (Parquet, CSV lub tabela bazy danych) z kolumnami zorganizowanymi w poziomy:

Kolumny ufności defektów na poziomie kafelka — jedna kolumna zmiennoprzecinkowa na klasę defektu, reprezentująca ufność softmax głowicy MLP, że kafelek zawiera ten defekt:

Nazwa kolumnyTyp danychPrawidłowy zakresOpis
tile_crack_confFloat32[0.0, 1.0]Prawdopodobieństwo obecności pęknięcia
tile_spalling_confFloat32[0.0, 1.0]Prawdopodobieństwo obecności odprysku
tile_efflorescence_confFloat32[0.0, 1.0]Prawdopodobieństwo obecności wykwitu
tile_exposed_rebar_confFloat32[0.0, 1.0]Prawdopodobieństwo obecności odsłoniętego zbrojenia
tile_corrosion_confFloat32[0.0, 1.0]Prawdopodobieństwo obecności korozji

Kolumny agregacji na poziomie klatki — podsumowujące obecność defektów we wszystkich kafelkach w klatce kamery lub sekcji pasa startowego:

Nazwa kolumnyTyp danychPrawidłowy zakresOpis
frame_defect_countInt32[0, max_kafelki]Liczba kafelków z dowolnym defektem powyżej progu
frame_max_defect_confFloat32[0.0, 1.0]Maksymalna ufność we wszystkich defektach i kafelkach
frame_crack_flagBoolean{0, 1}Dowolny kafelek ma crack_conf > próg
frame_spalling_flagBoolean{0, 1}Dowolny kafelek ma spalling_conf > próg
frame_efflorescence_flagBoolean{0, 1}Dowolny kafelek ma efflorescence_conf > próg
frame_exposed_rebar_flagBoolean{0, 1}Dowolny kafelek ma exposed_rebar_conf > próg
frame_corrosion_flagBoolean{0, 1}Dowolny kafelek ma corrosion_conf > próg

Kolumny metadanych — identyfikujące kontekst przestrzenny i czasowy każdego rekordu analizy:

Nazwa kolumnyTyp danychOpis
image_idStringUnikalny identyfikator obrazu źródłowego
tile_xInt32Indeks kolumny kafelka w siatce pasa startowego
tile_yInt32Indeks wiersza kafelka w siatce pasa startowego
frame_timestampDateTimeCzas przechwycenia klatki źródłowej
gps_latFloat64Szerokość geograficzna GPS środka kafelka
gps_lonFloat64Długość geograficzna GPS środka kafelka

Asercje Obecności Kolumn

Test dymny ładuje wyniki analizy i sprawdza, że każda oczekiwana kolumna istnieje przy użyciu prostego dopasowania nazw kolumn:

expected_tile_cols = ["tile_crack_conf", "tile_spalling_conf",
                      "tile_efflorescence_conf", "tile_exposed_rebar_conf",
                      "tile_corrosion_conf"]
expected_frame_cols = ["frame_defect_count", "frame_max_defect_conf",
                       "frame_crack_flag", "frame_spalling_flag",
                       "frame_efflorescence_flag", "frame_exposed_rebar_flag",
                       "frame_corrosion_flag"]
expected_meta_cols = ["image_id", "tile_x", "tile_y",
                      "frame_timestamp", "gps_lat", "gps_lon"]

actual_cols = set(df.columns)
assert expected_cols.issubset(actual_cols), f"Brakujące kolumny: {expected_cols - actual_cols}"

Asercje Typu Danych i Zakresu Wartości

Dla każdej kolumny ufności defektów test dymny sprawdza:

Typ zmiennoprzecinkowy: Typ danych kolumny to float32 lub float64. Nieoczekiwane typy (int, string, object) wskazują na błąd serializacji lub potoku. Asercja używa assert df[col].dtype in [np.float32, np.float64].

Zakres wartości: Wszystkie wartości mieszczą się w [0.0, 1.0]. Wartości poza tym zakresem wskazują na awarię softmax lub normalizacji. Asercja używa assert df[col].between(0.0, 1.0).all().

Sprawdzenie brakujących wartości: Żadne wartości nie są NaN ani None. Wartości NaN w kolumnach ufności wskazują, że potok inferencji nie wyprodukował wyników dla niektórych kafelków — poważna awaria. Asercja używa assert df[col].notna().all().

Asercje Spójności Agregacji

Kolumny na poziomie klatki powinny być spójne z danymi na poziomie kafelka, z których pochodzą. Test dymny waliduje:

frame_defect_count równa się liczbie kafelków, gdzie maksymalna ufność przekracza próg: Dla każdej grupy klatek test ponownie oblicza liczbę defektów z danych na poziomie kafelka i sprawdza, czy odpowiada przechowywanej wartości klatki. Wyłapuje to błędy logiki agregacji w potoku.

frame_max_defect_conf równa się maksimum wszystkich wartości ufności kafelków: Test ponownie oblicza maksimum z danych na poziomie kafelka i sprawdza zgodność.

frame_flag jest zgodny z tile_conf: Dla każdej klatki flaga powinna wynosić 1, jeśli dowolny kafelek ma odpowiednią ufność powyżej progu, i 0 w przeciwnym razie. Test weryfikuje to dla wszystkich 5 typów defektów.

Te sprawdzenia spójności działają na zasadzie, że kolumny na poziomie klatki powinny być deterministycznie wyprowadzalne z kolumn na poziomie kafelka. Jeśli logika agregacji jest poprawna, sprawdzenia powinny zawsze przechodzić. Niepowodzenie wskazuje na błąd w kroku post-processingu potoku analitycznego, a nie w samym modelu.

Wykrywanie Dodawania i Usuwania Kolumn

Test dymny porównuje oczekiwany zbiór kolumn z rzeczywistym zbiorem kolumn i generuje ostrzeżenia dla:

  • Nieoczekiwanych nowych kolumn: Jeśli pojawi się nowa kolumna (np. tile_moisture_conf), test ostrzega, ale nie kończy się niepowodzeniem, ponieważ może to wskazywać na ulepszenie potoku wymagające aktualizacji integracji downstream.
  • Brakujących kolumn (warunek niepowodzenia): Jeśli oczekiwana kolumna jest nieobecna, test kończy się natychmiastowym niepowodzeniem. Może się to zdarzyć, jeśli głowica defektów została zastąpiona inną architekturą, która generuje inne klasy, lub jeśli kolumna została przypadkowo usunięta podczas refaktoryzacji potoku.
  • Przemianowanych kolumn: Jeśli nazwa kolumny ulegnie zmianie (np. tile_crack_conftile_cracking_conf), test kończy się niepowodzeniem, zapobiegając cichej awarii downstream, gdy pulpity raportowania, API lub bazy danych odwołują się do starych nazw kolumn.

Logika Bramkowania

Logika bramkowania określa, czy głowica defektów przechodzi czy nie przechodzi testu dymnego jako całość, w oparciu o ważoną kombinację wyników poszczególnych asercji. Bramkowanie to mechanizm, który zapobiega wdrożeniu zawodzącego modelu do produkcji.

Ważenie Asercji

Nie wszystkie asercje testów dymnych są równie krytyczne. System bramkowania przypisuje każdą asercję do poziomu ważności:

PoziomWagaWpływ na bramkęPrzykłady
Krytyczny1.0Bramkuje natychmiastNiepowodzenie ładowania punktu kontrolnego, NaN w wynikach
Poważny0.8Bramkuje jeśli >1 niepowodzenieBrakujące kolumny, niezgodność kształtu wyników
Ostrzeżenie0.4Bramkuje jeśli >3 niepowodzeniaAP na klasę poniżej progu
Informacja0.0Tylko logowanie, brak bramkowaniaTrendy metryk, powiadomienia o wycofaniu kolumn

Asercje Krytyczne to te, gdzie żadne prawidłowe wykonanie potoku nie jest możliwe — punkt kontrolny jest uszkodzony, model nie może się załadować lub inferencja generuje nieprawidłowe wartości numeryczne. Pojedyncze krytyczne niepowodzenie blokuje wdrożenie.

Asercje Poważne wskazują, że potok generuje strukturalnie prawidłowe, ale potencjalnie niepoprawne wyniki — brakujące kolumny spowodowałyby awarie raportowania downstream, niezgodność kształtu wyników wskazuje na niedopasowanie architektury modelu do infrastruktury serwującej.

Asercje Ostrzeżenia wskazują, że metryki modelu są poniżej nominalnych progów, ale potok jest strukturalnie sprawny. Są agregowane: jeśli więcej niż 3 ostrzeżenia wystąpią w pojedynczym uruchomieniu, bramka się aktywuje.

Asercje Informacyjne są czysto obserwacyjne — logują trendy dryfu metryk, powiadomienia o wycofaniu kolumn i porównania wydajności z poprzednimi uruchomieniami — ale nigdy nie bramkują wdrożenia.

Kryteria Zaliczania/Niezaliczania

Ogólny wynik testu dymnego jest obliczany jako:

gate_score = max(krytyczne_niepowodzenia,
                  poważne_niepowodzenia > 1 ? 1.0 : 0.0,
                  ostrzeżenia > 3 ? 1.0 : 0.0)

Jeśli gate_score >= 1.0, test dymny kończy się niepowodzeniem, a wdrożenie jest blokowane. Jeśli gate_score < 1.0, test dymny przechodzi, a potok przechodzi do pełnej ewaluacji lub wdrożenia.

Komunikat złożonego zaliczenia/niezaliczenia podsumowuje wynik:

TEST DYMNY: NIEPOWODZENIE
  - Krytyczne: 1 [checkpoint_load_failure]
  - Poważne: 0
  - Ostrzeżenia: 2 [class_crack_ap_below_threshold, class_efflorescence_f1_below_threshold]
  - Informacje: 1 [metric_class_crack_ap spadło o 3.2% od ostatniego uruchomienia]

Integracja Bramki Wdrożeniowej

Bramka testu dymnego integruje się z potokiem wdrożeniowym poprzez:

Hook po zatwierdzeniu: Test dymny jest uruchamiany przy każdym zatwierdzeniu pull requesta. Jeśli bramka nie przejdzie, system CI/CD blokuje scalenie (reguła ochrony gałęzi GitHub, niepowodzenie potoku scalania żądania GitLab).

Bramka przedwdrożeniowa: Zanim model zostanie promowany ze stagingu do produkcji, test dymny jest uruchamiany ponownie na dokładnym artefakcie kandydata do wdrożenia. Wyłapuje to problemy, które mogły nie występować podczas rozwoju — na przykład środowisko programistyczne z inną wersją CUDA niż środowisko produkcyjne.

Wyzwalacz wycofania: Jeśli test dymny przejdzie wdrożenie, ale późniejszy incydent produkcyjny zostanie powiązany z głowicą defektów, logika bramkowania testu dymnego jest audytowana. Jeśli asercja na poziomie ostrzeżenia powinna była być asercją poważną, konfiguracja bramkowania jest aktualizowana, aby zapobiec nawrotom.

Testy Przydatności Domenowej

Testy przydatności domenowej rozszerzają podstawowy test dymny, aby zweryfikować, że głowica defektów działa poprawnie w specyficznych warunkach operacyjnych, które TarmacView napotyka w inspekcji nawierzchni lotniskowych i infrastruktury. Testy te zapewniają, że potok jest nie tylko funkcjonalny, ale także odpowiedni do celu w docelowej domenie.

Typy Nawierzchni Lotniskowych

Głowica defektów musi działać spójnie na różnych typach nawierzchni spotykanych na powierzchniach lotniskowych:

Nawierzchnie asfaltowe (elastyczne): Pasy startowe, drogi kołowania i płyty postojowe zbudowane z mieszanki mineralno-asfaltowej (HMA). Defekty na asfalcie obejmują pęknięcia zmęczeniowe (wzór siatki), pęknięcia podłużne, pęknięcia poprzeczne, koleiny i wybrukowanie. Test dymny zawiera syntetyczne obrazy z teksturami podobnymi do asfaltu (ciemnoszary, widoczne kruszywo, zmienna chropowatość powierzchni) i weryfikuje, że detekcja pęknięć i odprysków utrzymuje nominalne poziomy ufności.

Nawierzchnie betonowe (sztywne): Pasy startowe i płyty postojowe zbudowane z cementu portlandzkiego (PCC). Defekty obejmują odpryski na stykach, pęknięcia narożne, pęknięcia liniowe, wykwity (białe osady wapnia na stykach), odsłonięte zbrojenie (w miejscach odprysków) i plamy korozji. Test dymny weryfikuje, że model poprawnie identyfikuje wykwity i odsłonięte zbrojenie — defekty znacznie częstsze na nawierzchniach betonowych niż asfaltowych.

Nawierzchnie kompozytowe: Nakładki asfaltowe na istniejącym betonie. Defekty obejmują pęknięcia odbite (pęknięcia asfaltu podążające za wzorem podłoża betonowego) i delaminację. Test weryfikuje, że model może wykrywać pęknięcia na powierzchniach kompozytowych bez pomyłek spowodowanych wzorem podłoża.

Porowate warstwy ścieralne (PFC): Wysokoprzepuszczalny asfalt stosowany na pasach startowych w celu poprawy drenażu i przyczepności. PFC ma charakterystyczną otwartą teksturę, która wygląda wizualnie inaczej niż gęstoziarnisty HMA. Test weryfikuje, że model nie generuje podwyższonego wskaźnika fałszywych alarmów na powierzchniach PFC, gdzie szorstka tekstura może być mylona z pęknięciami lub odpryskami.

Warunki Oświetleniowe i Pogodowe

Załącznik 14 ICAO i FAA AC 150/5320-5D określają, że oceny stanu nawierzchni pasów startowych muszą być ważne w warunkach operacyjnych. Test dymny przydatności domenowej weryfikuje, że głowica defektów utrzymuje wydajność w:

Bezpośrednim świetle słonecznym: Wysoki kontrast, silne cienie. Test weryfikuje, że wartości ufności nie są systematycznie niższe w warunkach wysokiego kontrastu z powodu fałszywych alarmów wywołanych cieniami.

Zachmurzeniu/świetle rozproszonym: Niski kontrast, brak cieni. Test weryfikuje, że drobne pęknięcia (wąskie, o niskim kontraście względem nawierzchni) są nadal wykrywalne przy obniżonych poziomach ufności.

Mokrej nawierzchni: Woda w pęknięciach zwiększa widoczność pęknięć, ale wprowadza odbicia zwierciadlane. Test weryfikuje, że mokre kafelki powierzchni nie generują podwyższonych fałszywych alarmów z powodu błysków odbitych mylonych z wykwitami (oba pojawiają się jako jasne obszary).

Świcie/zmierzchu: Niski poziom światła, długie cienie. Test weryfikuje, że model generuje wyniki w oczekiwanych zakresach ufności nawet przy obniżonych poziomach oświetlenia.

Test dymny symuluje te warunki poprzez stosowanie kontrolowanych przekształceń fotometrycznych do syntetycznych obrazów testowych: skalowanie jasności dla symulacji oświetlenia, rozmycie gaussowskie dla symulacji mgły i dostosowanie nasycenia dla symulacji mokrej powierzchni.

Zmiana Rozdzielczości Przestrzennej

Obrazy inspekcyjne różnią się odległością próbkowania terenu (GSD) w zależności od platformy przechwytywania:

PlatformaTypowa wysokośćGSD (mm/piksel)Pokrycie kafelka
UAV (wysoka rozdzielczość)15-20 m0,5-1,00,1-0,5 m²
UAV (standard)30-50 m1,0-2,00,5-2,0 m²
Zamontowana na pojeździe2-3 m0,3-0,80,05-0,2 m²
Ręczna1-1,5 m0,2-0,50,02-0,08 m²

Test dymny weryfikuje, że głowica defektów generuje spójne wyniki w zakresie różnych rozdzielczości wejściowych. Syntetyczne obrazy testowe są generowane w wielu skalach (0,5×, 1,0×, 2,0× nominalnego GSD) i przepuszczane przez model. Test sprawdza, że przewidywany rozkład klas nie przesuwa się o więcej niż 10% między rozdzielczościami, zapewniając, że model jest w przybliżeniu niezmienniczy względem skali w zakresie operacyjnym.

Poziomy Nasilenia Defektów

ASTM D5340 definiuje trzy poziomy nasilenia (Niski, Średni, Wysoki) dla każdego typu defektu. Test dymny weryfikuje, że wyniki ufności głowicy defektów korelują z nasileniem defektu:

Niskie nasilenie: Włoskowate pęknięcia (szerokość <1mm), małe odpryski (długość <150mm), lekkie wykwity, minimalne plamy korozji. Test sprawdza, że te generują wyniki ufności powyżej progu detekcji (>0,5), ale nie na maksymalnym poziomie ufności (<0,8).

Średnie nasilenie: Pęknięcia (szerokość 1-3mm), odpryski (długość 150-600mm), umiarkowane osady wykwitów, widoczne odsłonięte zbrojenie z lekką korozją. Test sprawdza, że wyniki ufności są wysokie (>0,7).

Wysokie nasilenie: Szerokie pęknięcia (szerokość >3mm), duże odpryski (długość >600mm), ciężkie wykwity z naruszeniem powierzchni, odsłonięte zbrojenie z silną korozją i utratą przekroju. Test sprawdza, że wyniki ufności są bardzo wysokie (>0,9).

Weryfikacja korelacji nasilenia jest asercją na poziomie ostrzeżenia w systemie bramkowania — model może nadal działać poprawnie, nawet jeśli korelacja nasilenia jest niedoskonała, ale test oznacza to jako obszar do poprawy modelu.

Test Dymny a Pełna Ewaluacja

Zrozumienie różnicy między testem dymnym a pełną ewaluacją jest kluczowe dla zaprojektowania skutecznej strategii zapewnienia jakości ML. Te dwa podejścia służą zasadniczo różnym celom i działają w różnych punktach cyklu rozwoju i wdrożenia.

Cel i Zakres

WymiarTest DymnyPełna Ewaluacja
CelWeryfikacja integralności potokuPomiar jakości modelu
Pytanie“Czy potok działa poprawnie?”“Czy model jest wystarczająco dokładny?”
DaneSyntetyczne / mały statyczny zestaw (10-100 obrazów)Duży wstrzymany zbiór walidacyjny (500-5000+ obrazów)
Czas trwaniaSekundy do minutMinuty do godzin
ObliczeniaCPU lub minimalny GPUPełny GPU (często multi-GPU)
CzęstotliwośćKażde zatwierdzenie / PRNocnie, tygodniowo lub na wydanie
Progi metrykŁagodne (AP > 0,50)Rygorystyczne (AP > 0,75)
ZasięgTylko integralność strukturalnaGeneralizacja statystyczna
Działanie po niepowodzeniuBlokada scalenia/wdrożeniaOznaczenie do przeglądu

Test dymny ma na celu wyłapanie błędów potoku — klasy błędów, które powodują całkowitą awarię systemu lub generowanie bezwartościowych wyników. Obejmują one uszkodzenie punktu kontrolnego, niezgodność wersji, przerwy w potoku wstępnego przetwarzania, brakujące kolumny, wyniki NaN i niezgodności kształtu. Dane branżowe od zespołów inżynierii ML pokazują, że błędy potoku stanowią 60-70% nieudanych sesji trenowania i 40% wycofań wdrożeń. Testy dymne wyłapują te błędy w sekundach, zanim zostaną uruchomione kosztowne pełne ewaluacje.

Pełna ewaluacja ma na celu pomiar jakości modelu — statystycznej dokładności, precyzji, czułości i generalizacji predykcji modelu. Wykorzystuje duże, różnorodne, reprezentatywne zbiory walidacyjne, oblicza rygorystyczne metryki (AP@0.50 :0.95, F1 dla klas, macierze pomyłek, krzywe precyzji i czułości przy wielu progach) i porównuje wyniki zarówno z bezwzględnymi progami, jak i względnymi wartościami bazowymi z poprzednich wersji modelu. Pełne ewaluacje są kosztowne obliczeniowo i czasochłonne, co czyni je nieodpowiednimi do wykonywania przy każdym zatwierdzeniu.

Wymagania Danych

Dane testu dymnego są generowane syntetycznie, aby były proste, czyste i deterministyczne. Każdy syntetyczny obraz zawiera dokładnie jeden typ defektu na jednolitym tle, bez okluzji, nakładających się defektów i trudnych warunków oświetleniowych. Minimalizuje to zmienność i zapewnia, że każda fluktuacja metryki w teście dymnym jest przypisywana modelowi, a nie zmienności danych.

Pełne dane ewaluacyjne to rzeczywiste obrazy inspekcyjne o następujących cechach: różnorodne typy i wieki nawierzchni, wszystkie operacyjne warunki oświetleniowe, różne poziomy nasilenia defektów, nakładające się i sąsiadujące defekty, rzeczywiste okluzje (gruz, ślady opon, woda) oraz dokładne adnotacje prawdy podstawowej na poziomie wielokątów. Dane te reprezentują prawdziwy rozkład, z którym model spotyka się w produkcji, i zapewniają wiarygodne oszacowanie wydajności wdrożeniowej.

Zapobieganie wyciekom danych jest krytyczne dla pełnej ewaluacji, ale nieistotne dla testów dymnych — ponieważ test dymny używa danych syntetycznych, nie ma ryzyka wycieku rzeczywistych danych testowych do trenowania. Zbiór danych pełnej ewaluacji jest starannie podzielony: zestawy treningowe, walidacyjne i testowe są dzielone na poziomie klatki lub pasa startowego (nie na poziomie kafelka), aby zapobiec wyciekom autokorelacji przestrzennej, gdzie sąsiednie kafelki z tego samego pasa startowego pojawiają się zarówno w zestawie treningowym, jak i testowym.

Profil Obliczeniowy

Typowe uruchomienie testu dymnego dla potoku głowicy defektów:

  1. Załaduj punkt kontrolny: 2-5 sekund (86M parametrów szkielet DINOv3 + 1-3M parametrów głowica MLP)
  2. Generuj syntetyczne wejścia: < 1 sekunda (50 syntetycznych obrazów, 224×224 pikseli)
  3. Przejście w przód (CPU): 10-30 sekund (inferencja DINOv3 ViT-B/14 na CPU)
  4. Weryfikacja kolumn: < 1 sekunda (sprawdzenia kolumn Pandas DataFrame)
  5. Obliczenie metryk: 2-5 sekund (AP, F1 na zbiorze 50 obrazów)
  6. Ocena bramki: < 1 sekunda
  7. Razem: 15-45 sekund

Typowe uruchomienie pełnej ewaluacji:

  1. Załaduj punkt kontrolny: 2-5 sekund
  2. Załaduj zbiór walidacyjny: 30-120 sekund (2000 obrazów z dysku/SSD)
  3. Przejście w przód (GPU): 5-30 minut (inferencja batchowa na NVIDIA A10G/A100)
  4. Obliczenie metryk: 1-5 minut (AP@0.50 :0.95 dla wszystkich klas i progów IoU)
  5. Generowanie raportu: 10-30 sekund
  6. Razem: 7-38 minut

Test dymny jest 10-100× szybszy niż pełna ewaluacja, umożliwiając wykonanie przy każdym zatwierdzeniu. Pełna ewaluacja jest uruchamiana w wolniejszym rytmie (na noc, na wydanie, na promocję do produkcji).

Pokrycie Trybów Awarli

Tryb awariiWykrywany przez
Uszkodzony plik punktu kontrolnegoTest dymny (krytyczny)
NaN/inf w wynikach modeluTest dymny (krytyczny)
Brakujące kolumny wyjścioweTest dymny (poważny)
Nieprawidłowy kształt tensora wyjściowegoTest dymny (poważny)
Niezgodność normalizacji wstępnego przetwarzaniaTest dymny (krytyczny)
Zdegenerowane predykcje (wszystkie ta sama klasa)Test dymny (ostrzeżenie)
10% spadek AP na nowych danychPełna ewaluacja
Nadmierne dopasowanie do konkretnego typu nawierzchniPełna ewaluacja
Dryf kalibracjiPełna ewaluacja
Szum etykiet w danych treningowychPełna ewaluacja

Macierz pokrycia pokazuje, że testy dymne i pełne ewaluacje są komplementarne — każdy wyłapuje tryby awarii, które drugi pomija. Kompleksowa strategia testowania ML wymaga obu.

Integracja z CI

Integracja testu dymnego głowicy defektów z potokami ciągłej integracji (CI) jest niezbędna do wczesnego wyłapywania regresji i zapewnienia, że każda zmiana kodu jest walidowana przed wpływem na systemy produkcyjne.

Etapy Potoku CI

Potok CI dla systemu detekcji defektów TarmacView jest zorganizowany w sekwencyjne etapy:

Etap 1 — Jakość kodu: Linting (flake8, pylint), sprawdzanie typów (mypy), testy jednostkowe (pytest dla narzędzi ładowania danych, funkcji wstępnego przetwarzania i funkcji obliczania metryk). Ten etap działa na CPU i kończy się w 1-3 minutach. Niepowodzenie blokuje wszystkie dalsze etapy.

Etap 2 — Walidacja danych: Walidacja schematu zbiorów danych treningowych i ewaluacyjnych przy użyciu Great Expectations lub TensorFlow Data Validation. Sprawdza obecność kolumn, typy danych, zakresy wartości i statystyki rozkładu względem oczekiwań zdefiniowanych w kontrakcie danych. Ten etap działa na CPU i kończy się w 2-5 minutach.

Etap 3 — Test dymny głowicy defektów: Pełny zestaw testów dymnych opisany w tym artykule. Działa na CPU (lub minimalnym GPU, jeśli dostępny) i kończy się w 15-60 sekundach. Niepowodzenie blokuje scalenie do gałęzi main.

Etap 4 — Testy jednostkowe ewaluacji: Testy obliczania metryk w małej skali, które weryfikują, że obliczanie AP, F1 i generowanie macierzy pomyłek generuje poprawne wyniki na ręcznie oznaczonych małych zbiorach danych (5-10 obrazów ze znaną prawdą podstawową). Działa na CPU, kończy się w 30 sekund.

Etap 5 — Trenowanie (na żądanie): Uruchamiane tylko wtedy, gdy oczekuje się zmiany wag modelu (nowe dane treningowe, zmiany architektury, dostrajanie hiperparametrów). Nie uruchamiane automatycznie przy każdym zatwierdzeniu. Działa na GPU i zajmuje 1-8 godzin w zależności od rozmiaru zbioru danych.

Etap 6 — Pełna ewaluacja (przy scalaniu do main): Uruchamiana, gdy kod jest scalany do gałęzi main. Uruchamia pełny zestaw ewaluacyjny na wstrzymanym zbiorze walidacyjnym, oblicza wszystkie metryki, porównuje z wartościami bazowymi i publikuje wyniki w rejestrze modeli. Działa na GPU i zajmuje 20-40 minut.

Konfiguracja Wyzwalaczy

Test dymny jest uruchamiany:

  • Przy każdym zatwierdzeniu pull requesta: Zapewnia, że każda zmiana kodu — w tym zmiany wstępnego przetwarzania, ładowania danych, architektury modelu lub obliczania metryk — nie psuje potoku inferencji.
  • Przy aktualizacjach rejestru modeli: Gdy nowy punkt kontrolny modelu jest rejestrowany (nowa sesja trenowania zakończona), test dymny waliduje artefakt przed jego promocją do stagingu.
  • Zaplanowane codzienne uruchomienia: Nawet przy braku zmian kodu, codzienne testy dymne wyłapują dryf infrastruktury — zmiany wersji CUDA, aktualizacje zależności, zmiany systemu plików — które mogą wpływać na działanie potoku.

Zarządzanie Artefaktami

Artefakty CI z testu dymnego są przechowywane i wersjonowane:

  • Logi testowe: Ustrukturyzowane logi JSON zawierające wszystkie wyniki asercji, wartości metryk i status zaliczenia/niezaliczenia dla każdej asercji.
  • Historia metryk: Rekord szeregów czasowych metryk testu dymnego (AP, F1, wynik bramki) dla każdego uruchomienia, umożliwiający analizę trendów i wykrywanie regresji.
  • Odcisk palca punktu kontrolnego modelu: Hash SHA256 słownika stanu modelu użytego w teście, łączący wynik testu z konkretną wersją modelu.
  • Wersja syntetycznych danych testowych: Identyfikator wersji syntetycznego zestawu danych, umożliwiający powtarzalność.

Te artefakty są przechowywane w rejestrze modeli obok samego artefaktu modelu, zapewniając pełny łańcuch audytu: “Ta wersja modelu przeszła test dymny z syntetycznymi danymi v3.2 w uruchomieniu CI #4827 z zatwierdzeniem a3f2c1.”

Powiadomienia o Niepowodzeniu

Gdy test dymny kończy się niepowodzeniem, powiadomienia są wysyłane przez wiele kanałów:

  • Powiadomienie systemu CI: API GitHub Checks lub interfejs potoku GitLab pokazuje niepowodzenie ze szczegółowymi wynikami asercji.
  • Alert Slack/Teams: Wiadomość jest wysyłana na kanał inżynierii ML z ID uruchomienia potoku, podsumowaniem niepowodzenia i linkiem do pełnych logów.
  • Powiadomienie e-mail: Dla niepowodzeń na krytycznych gałęziach (main, release), e-mail jest wysyłany do zespołu inżynieryjnego.
  • Integracja PagerDuty: Opcjonalna dla niepowodzeń produkcyjnych testów dymnych (przy walidacji modelu mającego być wdrożonym), eskalowana, jeśli nie potwierdzona w ciągu 15 minut.

Powiadomienie zawiera ustrukturyzowany raport błędu:

Temat: [TEST DYMANY: NIEPOWODZENIE] potok defect-head - main - uruchomienie #4827
Treść:
  Zatwierdzenie: a3f2c1 (scalone 12:34 UTC)
  Punkt kontrolny: defect-head:v3 (kandydat produkcyjny)
  Wynik: NIEPOWODZENIE (gate_score=1.0)

  Krytyczne (1):
    - [output_nan] Tensor wyjściowy zawiera wartości NaN
      Przejście w przód szkieletu wyprodukowało NaN w normalizacji warstwy 8

  Poważne (0):

  Ostrzeżenia (2):
    - [class_efflorescence_ap] AP@0.50 = 0,42 poniżej progu 0,50
    - [class_efflorescence_f1] F1 = 0,55 poniżej progu 0,60

  Wymagane działanie: Zbadaj NaN w normalizacji warstwy 8 szkieletu.
  Możliwe przyczyny: uszkodzony punkt kontrolny, niezgodność wersji CUDA,
  lub niestabilność numeryczna w obliczeniach atencji.

Interpretacja Wyników Testów

Poprawna interpretacja wyników testów dymnych jest niezbędna do diagnozowania problemów z potokiem i określania odpowiednich działań naprawczych.

Czytanie Raportu Testowego

Test dymny generuje kompleksowy raport JSON o następującej strukturze:

{
  "pipeline_id": "defect-head-smoke",
  "run_id": "2026-06-16-4827",
  "timestamp": "2026-06-16T12:34:56Z",
  "commit_sha": "a3f2c1d4e5b6...",
  "checkpoint_version": "defect-head:v3",
  "synthetic_data_version": "v3.2",
  "gate_result": "FAIL",
  "gate_score": 1.0,
  "assertions": {
    "checkpoint_file_exists": {"status": "PASS", "detail": "checkpoint.pt (842MB)"},
    "checkpoint_loadable": {"status": "PASS", "detail": "Stan załadowany pomyślnie"},
    "forward_pass_shape": {"status": "PASS", "detail": "Kształt wyjścia (8, 5)"},
    "output_no_nan": {"status": "FAIL", "detail": "NaN znalezione w 1 z 8 próbek batcha"},
    "output_no_inf": {"status": "PASS", "detail": "Brak wartości inf"},
    "softmax_sum": {"status": "PASS", "detail": "Wszystkie sumy w zakresie 1e-5 od 1.0"},
    "tile_columns_exist": {"status": "PASS", "detail": "Wszystkie 5 kolumn kafelków obecne"},
    "frame_columns_exist": {"status": "PASS", "detail": "Wszystkie 7 kolumn klatek obecne"},
    "column_value_ranges": {"status": "PASS", "detail": "Wszystkie wartości w [0.0, 1.0]"},
    "class_crack_ap50": {"status": "PASS", "detail": "AP@0.50 = 0.92"},
    "class_spalling_ap50": {"status": "PASS", "detail": "AP@0.50 = 0.88"},
    "class_efflorescence_ap50": {"status": "WARN", "detail": "AP@0.50 = 0.42"},
    "class_exposed_rebar_ap50": {"status": "PASS", "detail": "AP@0.50 = 0.91"},
    "class_corrosion_ap50": {"status": "PASS", "detail": "AP@0.50 = 0.90"}
  }
}

Raport należy czytać od góry do dołu, najpierw zajmując się niepowodzeniami krytycznymi (ponieważ unieważniają one wszystkie dalsze wyniki), następnie poważnymi (problemy strukturalne, które spowodowałyby awarie produkcyjne), a na końcu ostrzeżeniami (regresje jakości, które mogą wymagać zbadania).

Diagnostyka Niepowodzeń Krytycznych

Niepowodzenia krytyczne wskazują, że potok jest całkowicie niefunkcjonalny. Najczęstsze przyczyny i działania naprawcze:

Plik punktu kontrolnego nie znaleziony: Ścieżka punktu kontrolnego określona w konfiguracji potoku nie wskazuje na istniejący plik. Działanie naprawcze: zweryfikuj ścieżkę rejestru modeli, sprawdź, czy sesja trenowania zakończyła się i przesłała artefakt, lub zaktualizuj konfigurację z poprawną ścieżką.

Niepowodzenie ładowania punktu kontrolnego: torch.load() zgłosił wyjątek. Typowe przyczyny obejmują: uszkodzenie pliku (ponownie uruchom trenowanie lub przywróć z kopii zapasowej), niezgodność wersji PyTorch (sprawdź, czy środowisko wdrożeniowe ma tę samą wersję PyTorch co środowisko trenowania — torch.save() w PyTorch 2.0 produkuje pliki, które ładują się inaczej na PyTorch 1.x) lub niezgodność CUDA/bez CUDA (punkt kontrolny zapisany z tensorami CUDA może nie załadować się w środowisku tylko CPU bez map_location='cpu').

NaN w wynikach: Najbardziej wymagające technicznie krytyczne niepowodzenie. Typowe przyczyny obejmują: niestabilność numeryczną w mechanizmie atencji DINOv3 (przepełnienie normalizacji warstwy przy ekstremalnych wartościach wejściowych), uszkodzone wagi w konkretnej warstwie (sprawdź, która warstwa produkuje NaN, uruchamiając z torch.autograd.set_detect_anomaly(True)), lub wstępne przetwarzanie generujące wejścia poza zakresem (np. wartości pikseli poza [0,1] po normalizacji).

Niezgodność kształtu wyników: Tensor wyjściowy ma inny kształt niż oczekiwany. Typowe przyczyny obejmują: głowica MLP została zastąpiona inną architekturą (inna liczba klas wyjściowych), zmienił się wymiar osadzenia szkieletu (punkt kontrolny z innego wariantu DINOv3) lub wymiar batcha został ściśnięty/rozciągnięty nieprawidłowo w kodzie post-processingu.

Diagnostyka Niepowodzeń Poważnych

Niepowodzenia poważne wskazują na problemy strukturalne, które spowodowałyby nieprawidłowe działanie produkcyjne.

Brakujące kolumny: DataFrame wyników analizy nie zawiera oczekiwanych kolumn. Typowe przyczyny: konwencja nazewnictwa kolumn została zmieniona bez aktualizacji konsumentów downstream, logika agregacji została zmodyfikowana w celu zmiany nazw kolumn lub zmieniono wyniki głowicy defektów (np. z 5 klas na 4 klasy).

Naruszenia zakresu wartości: Wartości ufności poza [0.0, 1.0]. To prawie zawsze wskazuje na awarię softmax — albo softmax nie został zastosowany do logitów, albo użyto niewłaściwej osi do normalizacji softmax. Sprawdź, czy używane jest F.softmax(logits, dim=1) (wymiar klas, nie wymiar batcha).

NaN w kolumnach wyjściowych: Podobne do krytycznych NaN w wynikach modelu, ale występujące w kroku agregacji post-processingu. Sprawdź dzielenie przez zero w agregacji kafelek-do-klatki (np. dzielenie przez liczbę kafelków, gdy klatka ma zero kafelków) lub propagację brakujących wartości z NaN wyników modelu, które nie zostały wyłapane na poziomie modelu.

Diagnostyka Niepowodzeń Ostrzeżeń

Niepowodzenia ostrzeżeń wskazują na degradację jakości, która może nie wymagać natychmiastowego blokowania wdrożenia, ale powinna być zbadana.

AP dla konkretnej klasy poniżej progu: Pojedyncza klasa defektu wykazuje znacząco niższą wydajność niż inne. Typowe przyczyny: niewystarczająca liczba syntetycznych przykładów treningowych dla tej klasy (generator danych syntetycznych może produkować nierealistyczne przykłady dla niektórych klas), brak równowagi klas w rzeczywistych danych treningowych wpływający na zdolność dyskryminacyjną głowicy dla rzadkich klas lub cechy szkieletu będące mniej informacyjne dla niektórych typów defektów (np. wykwit charakteryzuje się kolorem (białe osady) bardziej niż teksturą, podczas gdy cechy DINOv3 mogą kłaść nacisk na teksturę ponad kolor).

Brak równowagi precyzji i czułości: Model jest zbyt konserwatywny lub zbyt agresywny dla określonych klas. Typowe przyczyny: próg ufności został zoptymalizowany pod kątem ogólnej wydajności, ale jest suboptymalny dla poszczególnych klas, lub dane treningowe mają asymetryczny szum (więcej fałszywie negatywnych niż fałszywie pozytywnych dla określonej klasy).

Dryf metryk od wartości bazowej: Metryki zmieniły się o więcej niż 5% od ostatniego zwalidowanego uruchomienia bez zmian kodu lub danych. Może to wskazywać na: niedeterminizm w modelu (warstwy dropout lub normalizacji batcha zachowujące się inaczej w trybie trenowania vs ewaluacji — upewnij się, że model.eval() jest wywoływane przed inferencją), dryf numeryczny spowodowany różnicami sprzętowymi (kolejność akumulacji zmiennoprzecinkowej CPU vs GPU) lub zmiany generatora danych syntetycznych produkujące inne próbki testowe.

Automatyczne Sugestie Naprawcze

Wyniki testu dymnego zawierają sugestie naprawcze dla typowych trybów awarii:

NiepowodzenieSugestia naprawcza
Punkt kontrolny nie znalezionyZweryfikuj ścieżkę rejestru modeli; uruchom trenowanie, aby wygenerować punkt kontrolny
NaN w szkieleciePrzełącz na precyzję float32, jeśli używasz float16; dodaj przycinanie gradientów
Brakująca kolumnaZaktualizuj nazwy kolumn w logice agregacji, aby dopasować do schematu
Niska AP dla konkretnej klasyDodaj więcej syntetycznych przykładów treningowych dla tej klasy; sprawdź równowagę klas
Dryf metrykUruchom inferencję z torch.inference_mode() i model.eval(); sprawdź operacje niedeterministyczne

Te sugestie są generowane przez system regułowy, który mapuje wzorce niepowodzeń asercji na znane działania naprawcze, redukując średni czas do rozwiązania (MTTR) dla typowych trybów awarii.

Pulpit analityczny nauki o danych pokazujący metryki ewaluacji modelu do detekcji defektów z krzywymi AP, wykresami precyzji i czułości, wynikami F1 i macierzą pomyłek
Szczegółowe zdjęcie z bliska betonowej nawierzchni lotniskowej pokazujące wiele defektów strukturalnych, w tym pęknięcia, odpryski, wykwity, odsłonięte zbrojenie i plamy korozji

Najczęściej Zadawane Pytania

Zweryfikuj swój potok detekcji defektów

TarmacView wdraża rygorystyczne potoki testów dymnych i ewaluacji dla wykrywania defektów strukturalnych opartego na AI na nawierzchniach lotniskowych i infrastrukturze betonowej. Umów się na demo, aby zobaczyć, jak zautomatyzowane testowanie zapewnia niezawodność wdrożenia.

Dowiedz się więcej

Test dymny (Smoke Test)

Test dymny (Smoke Test)

Test dymny to szybka, kompleksowa weryfikacja, czy pipeline oprogramowania wykonuje się bez awarii na reprezentatywnych danych, produkując oczekiwane wyniki. Sk...

25 min czytania
testing technology +4
Defect Gating — Kontekstowe filtrowanie prognoz wad konstrukcyjnych

Defect Gating — Kontekstowe filtrowanie prognoz wad konstrukcyjnych

Defect gating to strategia wnioskowania, która filtruje przewidywane etykiety wad w zależności od rodzaju nawierzchni i domeny strukturalnej, tłumiąc fałszywie ...

25 min czytania
Technology Defect Detection +3
Pomiary laboratoryjne a inspekcja wizualna w ocenie nawierzchni

Pomiary laboratoryjne a inspekcja wizualna w ocenie nawierzchni

Lab-only odnosi się do właściwości nawierzchni, których nie można wiarygodnie określić na podstawie pojedynczych obrazów RGB — zawartości lepiszcza asfaltowego,...

44 min czytania
assessment pavement testing +2