Gözlemlenebilirlik ve Kayma
Sessiz doğruluk kaybını yakalayan ölçümleri günlüğe kaydet, güven dağılımlarını kayma açısından test et ve yalnızca eyleme dönüştürülebilir sinyaller için uyarı ver.
Bir görüntü hizmeti çalışır durumda ve hızlı olabilir, ama yanlış sonuç verebilir. Bir kamera yerinden oynar, aydınlatma değişir, yeni bir ürün grubu gelir; model kutular döndürmeye devam ederken tüm altyapı panoları yeşil kalır. Bu derste, akşam karanlığını taklit etmek için bir klibi karartmak ortalama güven değerini yalnızca 0.01 değiştirdi; bu fark grafikte görünmüyordu ama iki örnekli KS testi p = 0.007 değeriyle değişimi saptadı. Bu kontrolü ve kontrolü besleyen günlük kaydını oluşturacaksın.
Uygulamalı
Sinyallerin Üç Katmanı#
| Katman | Soru | Sinyaller |
|---|---|---|
| Altyapı | Hizmet çalışıyor ve talebe yetişiyor mu? | Gecikme, verim, düşen kareler, CPU ve GPU kullanımı |
| Model davranışı | Model geçen haftaki gibi mi davranıyor? | Kare başına algılama sayısı, ortalama güven, sınıf dağılımı, kutu boyutları |
| Model doğruluğu | Model hâlâ doğru sonuç veriyor mu? | Doğrulama kümesinde mAP (performans ölçümleri), örneklem üzerinden insan incelemesi, yanlış alarm oranı |
Çoğu ekip ilk katmanı standart araçlarla izler ve orada durur. Görüntü sistemlerinin sessizce başarısız olduğu yerler ikinci ve üçüncü katmanlardır; model izleme kılavuzu bakım döngüsünün tamamını ele alır.

Ultralytics Platform üzerinden dağıtım yaparsan dağıtım sayfası, yukarıdaki örnekte olduğu gibi, altyapı katmanını (istekler, hata oranı, P95 gecikmesi) ve hatalara göre filtreleyebileceğin istek günlüklerini sunar; Sağlığı ve Doğruluğu İzleme dersi bunları ele alır. Davranış ve doğruluk katmanlarını sen oluşturmalısın; bu dersin geri kalanı da bunları oluşturuyor.
Kare Başına Ölçümler Üret#
Her Results nesnesi zamanlama bilgilerini ve kutuları içerir. Her kare için bir JSON satırı yaz ve kullandığın ölçüm sistemine gönder:
import json
import time
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
video = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
with open("metrics.jsonl", "w") as log:
for r in model.predict(video, stream=True, verbose=False):
conf = r.boxes.conf
record = {
"ts": time.time(),
"camera": "lobby-1",
"inference_ms": round(r.speed["inference"], 1),
"detections": len(r.boxes),
"mean_conf": round(conf.mean().item(), 3) if len(conf) else None,
"confs": [round(c, 3) for c in conf.tolist()], # kayma testi için ham değerler
}
log.write(json.dumps(record) + "\n")
print({k: v for k, v in record.items() if k != "confs"}){'ts': 1792003254.33, 'camera': 'lobby-1', 'inference_ms': 34.7, 'detections': 22, 'mean_conf': 0.543}Her alanın amacı:
- inference_ms: p95 bütçeni aşarsa uyarı ver.
- detections: sayının aniden sıfıra yaklaşması genellikle kameranın bağlantısının kesildiği veya bozulduğu anlamına gelir; artış ise sahne değişikliğine ya da yanlış pozitiflere işaret eder.
- mean_conf: hızlı bir eğilim çizgisi sunar, ancak tek başına kaymayı tespit etmek için fazla kabadır.
- confs: aşağıdaki kayma testinin ihtiyaç duyduğu tam dağılım.
Güven Dağılımlarını Kayma Açısından Test Et#
Veri kayması, yeni verileri biri etiketlemeden çok önce güven değerlerinde kendini gösterir. Başlangıçta bir referans noktası olarak güven değerlerini topla, yakın tarihli bir pencereyi de topla ve iki dağılımı iki örneklemli Kolmogorov-Smirnov testiyle (pip install scipy) karşılaştır. Bu betik, aynı klibi karartarak gün batımını simüle eder:
import cv2
import numpy as np
from scipy.stats import ks_2samp
from ultralytics import YOLO
from ultralytics.utils.downloads import safe_download
model = YOLO("yolo26n.pt")
video = str(safe_download("https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"))
def confidences(darken=1.0):
"""Collect every detection confidence from the clip, optionally darkened to simulate dusk."""
cap, out = cv2.VideoCapture(video), []
while True:
ok, frame = cap.read()
if not ok:
break
out += model((frame * darken).astype(np.uint8), verbose=False)[0].boxes.conf.tolist()
return np.array(out)
baseline = confidences() # what "normal" looked like at launch
for name, recent in (("same scene", confidences()), ("dusk (35% brightness)", confidences(darken=0.35))):
stat, p = ks_2samp(baseline, recent)
print(f"{name:22s} n={len(recent):4d} mean_conf={recent.mean():.3f} KS={stat:.3f} p={p:.2g}")same scene n=1376 mean_conf=0.519 KS=0.000 p=1
dusk (35% brightness) n=1337 mean_conf=0.508 KS=0.064 p=0.0068Satır satır incele:
- Aynı sahne: özdeş dağılımlar, kontrol örneği olan 0 KS istatistiği ve p = 1 sonucunu verir.
- Gün batımı: 39 daha az tespit ve yalnızca 0.011 daha düşük bir ortalama; bunu grafikte kimse fark etmezdi. KS istatistiği (iki kümülatif dağılım arasındaki en büyük fark) 0.064'tür ve p = 0.0068 < 0.01 olması kaymanın gerçek olduğunu gösterir.
Kayma uyarısı, örnek karelere bakmak için bir nedendir; başarısızlığın kanıtı değildir. Kayma gerçekse, etkilenen kameralardan kareler topla ve etiketle: veri toplama ve anotasyon kılavuzu hangi verileri toplayacağını, ince ayar kılavuzu ise yeniden eğitimi açıklar. Kutu boyutları (genişlik × yükseklik), ikinci ve düşük maliyetli bir kayma sinyali sunar: yeni montajlar ve optikler önce burada kendini gösterir.
Bekletilen Veri Kümesini Her Hafta Doğrula#
Davranış sinyalleri bir şeylerin değiştiğini gösterir; doğruluğun düşüp düşmediğini ise yalnızca etiketler ortaya koyar. 200–500 etiketli üretim görüntüsünden oluşan bir bekletilen veri kümesi ayır ve her model sürümünü, ayrıca her hafta doğrula:
yolo val model=yolo26n.pt data=coco8.yaml > weekly_metrics.txt # use your production model and holdout YAMLmAP50-95 ve sınıf başına AP değerlerini zaman içinde kaydet; mAP haftalık olarak 1 puandan fazla düşerse uyarı ver. En yaygın neden, hiçbir şeyi değiştirmemesi gereken bir model geçişidir; ikinci yaygın neden ise kaymadır. Aynı bekletilen veri kümesinde oluşturulan bir karmaşıklık matrisi, sınıf başına gerilemeleri kolayca fark etmeni sağlar.

Bu grafikteki soruyu yanıtlayan, bekletilen veri kümesidir. Kalitenin düşmeye başladığını gösterdiğinde veya kaymanın yaşandığı koşullardan yeterince yeni etiketli veri topladığında yeniden eğitim yap; sabit bir takvime göre hareket etme.
Sayılara Değil, Eylemlere Göre Uyarı Ver#
| Sinyal | Uyarıyı tetikleme koşulu | Eylem |
|---|---|---|
p95 inference_ms | 3+ dakika boyunca bütçenin üzerinde | Kapasiteyi artır veya optimize edilmiş dışa aktarımı kullan |
| Kare başına tespit sayısı | 5 dakika boyunca %50+ düşüş | Önce kamera akışını, ardından model sürümünü kontrol et |
| Atlanan kareler | 10 dakika boyunca %5'in üzerinde | Kapasite ekle veya akış başına FPS'yi düşür |
| Güven değerleri için KS testi | Günlük pencerelerde p < 0.01 | Kareleri incele, ardından bekletilen veri kümesini çalıştır |
| Bekletilen veri kümesinde mAP50-95 | Haftadan haftaya 1+ puan düşüş | Veri topla, etiketle ve ince ayar yap |
Yaygın Hatalar#
Belirti: KS testi her akşam ve her pazartesi tetikleniyor. Çözüm: Günlük ve haftalık döngüler gerçek dağılım değişiklikleridir. Benzer koşulları karşılaştır (aynı kameralar, aynı saatler, aynı haftanın günü) ve binlerce tespitten oluşan zaman aralıkları kullan.
Belirti: Ayırma kümesindeki mAP iyi görünürken kullanıcılar kaçırılan nesnelerden şikâyet ediyor. Çözüm: Ayırma kümesi mevcut üretim verilerine benzemeli. Önemli kameralardan yeni etiketlenmiş karelerle üç ayda bir yenile.
Her uyarı için yazılı bir sonraki adım gerekir. Yalnızca izlemek istediğin bir sinyal, çağrı cihazında değil panoda yer almalıdır.
Çözümü göster
monitor.py çıktısındaki ilk sağlıklı pencereyi baseline.jsonl olarak sakla ve ardından her yeni pencereyi bununla karşılaştır:
import json
import numpy as np
from scipy.stats import ks_2samp
def load(path):
"""Flatten the per-frame 'confs' lists written by monitor.py."""
with open(path) as f:
return np.array([c for line in f for c in json.loads(line)["confs"]])
baseline, recent = load("baseline.jsonl"), load("metrics.jsonl")
stat, p = ks_2samp(baseline, recent)
print(f"KS={stat:.3f} p={p:.2g} -> {'review frames' if p < 0.01 else 'ok'}")KS=0.000 p=1 -> okHer iki dosya da aynı görüntülerden geldiğinde beklenen sonuç budur. Bunu bir zamanlayıcıyla her gün çalıştır, istatistiği ve p değerini kare başına günlüklerle aynı metrik sistemine gönder ve review frames uyarısını çağrı cihazına değil, bir kişiye yönlendir.