Tüm lab yazıları

Lab notu

LOG-003Yapay zekâ

O elde eldiven var mı?

Yalnızca önceden eğitilmiş modellerle kurulmuş bir eldiven denetim sistemi. İlk tasarım kararı — eldivenin, eli bulma işine karışmasına izin vermemek — sonradan düzeltilemeyecek tek karar çıktı.

10 dk okuma
  • Computer Vision
  • YOLO
  • SigLIP
  • DINOv3
  • Python
  • Safety

Bir presin tehlike bölgesi var. Bölgeye bir el giriyor. Önemli olan tek soru, o elde eldiven olup olmadığı — ve cevabın hem işe yarayacak kadar hızlı gelmesi hem de güvenilecek kadar sık doğru olması gerekiyor.

Bu iki gereksinim ters yönlere çekiyor ve simetrik de değiller. Yanlış alarm, durdurulması gerekmeyen bir makineyi durduruyor; sürekli yalan söyleyen bir hat, koruduğu insanlar tarafından kapatılıyor. Kaçırılan alarm ise birini sakatlıyor. Yani bu bir "F1'i yükseltelim" problemi değil; hangi hataları yapmaya razı olduğunuzun problemi.

GloveWatch'ı, yalnızca önceden eğitilmiş modellerle nereye kadar gidilebileceğini görmek için yazdım — veri seti toplamadan, eğitim koşusu yapmadan, çalışmaya başlaması için hiçbir şey etiketlemeden.

Dikey işlem hattı şeması: video kaynağı, vücut pozu, el kutusu, bölge testi, el takipçisi, eldiven sınıflandırıcı, zamansal oylayıcı, çıktılar
Bir karenin alarma giden yolu. Renkli iki aşama, tasarımın tesisat değil iddia ürettiği yerler.

Her şeyi biçimlendiren tuzak

Akla gelen ilk hamle, elleri bir el dedektörüyle bulmak. MediaPipe Hands ve benzerleri mükemmel, hızlı ve bedava.

Ayrıca ezici çoğunlukla çıplak eller üzerinde eğitilmişler ve tam da bu uygulamanın onlara en çok ihtiyaç duyduğu yerde bozuluyorlar. Kalın bir iş eldiveni takın, landmark modeli eli tümden kaçırmaya başlıyor — ki bu bir güvenlik sistemi için mümkün olan en kötü hata biçimi: eldivenli el görünmez oluyor, dolayısıyla sistemin gördüğü tek eller çıplak olanlar kalıyor ve varabileceği tek sonuç zaten baştan varsaydığı şey oluyor. Eldiveni göremeyen bir dedektör, eldiven dedektörünü çalışıyormuş gibi gösteriyor.

Bu yüzden eldivenin, eli bulma işine yaklaşmasına asla izin verilmiyor. Konumlandırma yalnızca vücut pozundan geliyor:

  1. YOLO26x-pose her kişi için 17 COCO anahtar noktası veriyor — dirsekler ve bilekler dâhil.
  2. El, dirsek→bilek vektörünün bileği aşan yönde önkol uzunluğunun 0.6'sı kadar uzatılmasıyla yerleştiriliyor.
  3. O uzatmanın 1.5 katı kenarlı kare bir kutu; uzaktaki eller kaybolmasın diye 48 piksel tabanla.

Bu zincirde hiçbir şey tene bakmıyor. Eldiven, sargı, elin üstüne çekilmiş bir kolluk — kutu yine aynı yere düşüyor, çünkü koldan çıkarsanıyor.

Veri seti olmadan sınıflandırmak

Bölgede bir el kutusu varken asıl soru, küçük bir kırpıntı üzerinde tek bir ikili karar. İlk sürüm bunu sıfır-atışlı (zero-shot) yapıyor: SigLIP 2 istem topluluğu — her sınıf için altı farklı ifade, skorlar ortalanıyor:

glove_prompts:
  - "a photo of a hand wearing a work glove"
  - "a gloved hand"
  # …
bare_prompts:
  - "a bare human hand"
  - "a hand with no glove"
  - "a close-up photo of bare skin on a hand"
  # …

Her el iki ölçekte inceleniyor — dar bir kırpıntı ve %25 dolgulu bir tanesi — ve iki olasılık ortalanıyor; çünkü çoğunlukla el olacak kadar dar bir kırpıntı genellikle bileği kesiyor ve bir eldivenin en eldiven duran yeri tam da orası.

Bu, hiçbir şey eğitilmeden ilk çalıştırmada iş görüyor. Sıfır-atışlı katmanın bütün amacı da bu: sistem, daha kimse hiçbir şey etiketlemeden faydalı oluyor ve veri istemeyi ancak ondan sonra hak ediyor.

Yükseltme ve dürüstçe ne kazandırdığı

Doğruluk oyununun sonu az-atışlı (few-shot): gerçek görüntüden bölge içi kırpıntıları topla, iki klasöre ayır, dondurulmuş bir DINOv3 gövdesiyle göm ve üstüne StandardScaler + LogisticRegression otur. models/glove_head.pkl ortaya çıktığında uygulama onu otomatik alıyor.

386 kırpıntı topladım — 287 çıplak, 99 eldivenli — ve eğittim:

CV accuracy: 0.837 +/- 0.019
folds:       0.833, 0.831, 0.857, 0.805, 0.857

%83.7. Bir güvenlik sistemi için bu sayı iyi değil ve süslemektense açıkça söylemeyi tercih ederim. Sebebi, sınıflandırıcıya gerçekte ne verildiğine bakınca anında görünüyor:

İki sıra küçük el kırpıntısı: üstte çıplak eller, altta eldivenli eller, çoğu ağır hareket bulanıklığında
Eğitim setinden gerçek kırpıntılar. 80–200 piksel, 30 fps'te hareket hâlindeki bir elden kesilmiş. Bulanıklık render hatası değil, verinin kendisi.

Bunlar küçük, hareket bulanıklı, tuhaf ışıklı yamalar ve hareket hâlindeki bir elden geliyorlar — duran el zaten ilginç durum değil. Üstüne, 386'sının tamamı tek bir kişiden, tek bir odada, iki çift eldivenle toplandı. Buna uydurulan bir model, eldiveni öğrendiği kadar benim mutfak ışığımı da öğrenmiştir.

Dürüst okuma şu: %83.7, bu veri setinin desteklediği şey; yöntemin desteklediği şey değil. Çözüm, gerçek hattan gelen daha çok ve daha çeşitli veri — daha iyi bir sınıflandırıcı başlığı değil.

Tek bir karenin neden karar vermesine izin yok

%84'lük bir sınıflandırıcı 30 fps'te her karede tetiklense, saniyede kabaca beş yanlış karar üretir. Hiçbir makine bununla sürülemez.

Bu yüzden hiçbir tek kareye bir sonuca varma izni verilmiyor. Kayan bir pencere, takip edilen her el için son 9 bölge-içi kareyi tutuyor ve bir hüküm için bunların 7'sinin hemfikir olması gerekiyor. İzler kareler arasında bilek mesafesiyle eşleştiriliyor, el bölgeden çıkınca pencere sıfırlanıyor ve alarm bir kez çaldığında el gerçekten çıkana kadar mandallanıyor — bölge sınırında gezinen bir el, alarmı yakıp söndürebilmemeli.

Bu epey kararlılık kazandırıyor ve gecikme olarak fatura ediliyor; faturası da olay kaydından ölçülebiliyor:

Solda: el girişinden hükme kadar geçen sürenin histogramı, 233 ms işaretli kesikli çizginin hemen üstünde kümelenmiş. Sağda: alarm ve onay olayları için karar güveni histogramı.
15 kayıtlı koşudan 833 olay. Solda: hüküm dağılımı, 30 fps'te 7 karelik teorik tabanın tam üstünde oturuyor. Sağda: kaydedilen her karara iliştirilen güven.

Elin bölgeye girmesinden NO_GLOVE_ALERT'e kadar medyan süre 292 ms; 30 fps'te 7 karelik sert taban ise 233 ms. Tasarım ile ölçüm birbirini tutuyor — bu yazının en içi rahatlatan tarafı da bu: oylayıcı tam söylediği şeyi yapıyor ve üstüne neredeyse hiçbir şey eklemiyor.

GLOVE_OK daha yavaş: medyan 511 ms. İki hüküm de 9'da 7 istiyor, dolayısıyla asimetrinin kaynağı sınıflandırıcı olmak zorunda — eldivenli kareler çıplaklardan daha tutarsız sınıflandırılıyor, pencere de hemfikirlikle daha geç doluyor. Yani eğitim setindeki 99'a 287 dengesizliği, bir katman aşağıda tekrar karşımıza çıkıyor.

Asıl endişelendiğim sayı

Sahaya çıkış açısından önemli olan B paneli ve önemli olan medyan değil.

Alarm güvenleri 0.566 ile 1.000 arasında. Tüm alarmların üçte biri — 308'in 102'si — 0.8'in altında, %13'ü ise 0.7'nin altında tetiklendi. Eşik 0.5, yani o kuyruğun dibi yazı-turadan biraz fazlasıyla verilmiş bir karar — ve bir makineyi durduran bir karar.

Hüküm gecikmesi
292 ms
Başlık CV doğruluğu
%83.7
Uçtan uca
~20 FPS
0.8 altı alarm
%33

Medyan size sistemin çalıştığını söyler. Kuyruk ise en kötü gününde ne yapacağını söyler ve bir güvenlik sisteminde en kötü gün, şartnamenin kendisidir. Bariz sonraki hamle daha iyi bir model değil — düşük güvenli hükümlere hiç eyleme geçmemek ve onları makine durdurmaya değil bir insana yönlendirmek.

Şu an nerede

Bir RTX 4080 üzerinde uçtan uca yaklaşık 20 FPS koşuyor; hedef 15'ti. YOLO26x-pose 960 pikselde TensorRT FP16 motoruna aktarılmış durumda. O motor o belirli GPU için derleniyor ve başka bir GPU'da yeniden aktarılması gerekiyor — unutulması kolay, ısırdığında kafa karıştırıcı bir ayrıntı.

Bitmiş değil ama. Yukarıdaki her şey bir odada, tek bir kişi tarafından, tek çift eldiven bir web kamerasına sallanarak ölçüldü. İşlem hattı ayakta duruyor ve zamanlama gerçek; ama sınıflandırıcı bugüne kadar yalnızca benim ellerimi gördü. Sıradaki iş bu ve bir veri işi, model işi değil.

Yeniden yapsam aynı şekilde kuracağım kısım ilk karar: elleri, eldiveni görebilen hiçbir şeyle konumlandırmayı reddetmek. Ondan sonraki her şey daha iyi veriyle iyileştirilebilir. O karar ise sonradan hiç düzeltilemezdi.