İçeriğe geç
academia.sh

Ders 12 / 14

Bölütleme

Piksel düzeyinde kararın kendi tabanına karşı okunması: sınamadaki 17.280 pikselin 2.193'ü nesne olduğu için her pikseli baskın sınıfa atayan taban piksel doğruluğunda 0,8731 alıyor, aynı çıktının nesne örtüşme oranı 0,0000. Tek piksel değerinden karar veren doğrusal model 0,9540 ve 0,6412, aynı model 3x3 komşuluk penceresiyle 0,9851 ve 0,8843 veriyor; fark modelden değil temsilden geliyor. Yüz yirmi görüntünün 45'i bitişik blok taşıyor ve kusursuz maskeyle bile bağlı bileşen sayarak örnek sayısı bu 45 görüntüde yanlış çıkıyor; dikdörtgen ayrıştırma 24'ünü düzeltip 21'inde duruyor, kestirilen maskede ise yanlış sayı 46'dan 79'a çıkıyor.

İçindekiler

Önceki ders nesnenin nerede olduğunu bir kutuyla söyledi ve o kutunun örtüşme oranını görüntünün ortasına konan sabit bir kutunun aynı ölçütteki sayısıyla karşılaştırdı; boyutu da arayan pencere 0,9076 ortalama örtüşme aldı. Kutunun söylemediği bir şey kaldı: bulunan dikdörtgenin içindeki her piksel nesne sayılıyor. Bir kutu, dört sayıdan oluşan kaba bir yanıttır; “hangi pikseller” sorusunun yanıtı ise piksel sayısı kadar karardır.

Bu dersin kurgusunda nesneler dikdörtgen bloklardır, yani kusursuz bir kutu zaten kusursuz bir maske verir. Kurgu bu yönüyle kutunun lehinedir ve ders yine de iki şey gösterir. Birincisi, piksel düzeyine inildiğinde alanın tabanı değişir ve şaşırtıcı biçimde yüksek çıkar. İkincisi, piksel düzeyinde ne kadar iyi karar verilirse verilsin, iki nesnenin bitiştiği yerde anlamsal bölütleme ikisini ayıramaz; bu bir doğruluk sorunu değil, çıktının biçimiyle ilgili bir sınırdır.

  • BG31. Görüntü kurgudur. 12x12 kapsama ızgarası burada gri düzeyli küçük bir görüntüdür; ızgara M26/K06’dan gelir ve M27/K05’te öğrenme girdisine çevrilmişti. Tohum 20260218.
  • BG32. Nesneler kurgu dikdörtgen bloklardır. Yükseklik ve genişlik 2 ile 4 arasındadır, blok pikselleri zeminden daha yüksek bir gri düzeye oturur ve gürültü üç düzgün sayının toplamıyla üretilir; iki düzeyin dağılımları uçlarda örtüşür.
  • BG33. Bir görüntüde bir, iki ya da üç blok bulunur. İkinci ve üçüncü blok 0,40 olasılıkla bir öncekinin kenarına dayanır; dayanmıyorsa aralarında en az bir hücre boşluk bırakılır.
  • BG34. İki etiket vardır. Nesne maskesi her piksel için 0/1’dir ve anlamsal bölütlemenin hedefidir; örnek maskesi her piksele blok numarasını yazar ve örnek bölütlemenin hedefidir.
  • BG35. Bölme 80/120’dir ve bu görüntü kümesinde sabittir. Eğitim kümesi bilerek küçüktür.
  • BG36. Alanın tabanı her pikseli baskın sınıfa atamaktır. Baskın sınıf zemindir; seçimin gerekçesi piksel oranıdır ve o oran basılır.
  • BG37. İki ölçüt yan yana okunur. Piksel doğruluğu (büyük iyi) bütün pikselleri sayar; nesne sınıfının örtüşme oranı (kesişim bölü birleşim, büyük iyi) yalnız nesne pikselini sayar. Örtüşme oranı 03. derste kutular üzerinde tanımlanmıştı, burada piksel kümeleri üzerinde okunur.
  • BG38. Model doğrusaldır ve en küçük karelerle uydurulur; karar eşiği 0,5’te sabittir. Eşik seçiminin sayıyı oynatması M27/K03’te ölçüldü ve tekrarlanmaz. Kütüphane çağrılmaz.
  • BG39. Örnek sayısı iki yordamla okunur: bağlı bileşenler, ve “nesneler dikdörtgendir” önbilgisiyle dikdörtgen ayrıştırma.

Kurgu Görüntü ve Alanın Tabanı

# goruntu.py — MODELDIR. Goruntu kumesi KURGUDUR: M26/K06 ve M27/K05'in 12x12
# kapsama izgarasi burada gri duzeyli kucuk bir goruntudur ve uzerine kurgu
# dikdortgen bloklar yerlestirilir. Tohum 20260218.
TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
ZEMIN, BLOK, GURULTU = 0.30, 0.74, 0.30


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def ortusuyor(a, b, bosluk):
    return not (a[0] + a[2] + bosluk <= b[0] or b[0] + b[2] + bosluk <= a[0]
                or a[1] + a[3] + bosluk <= b[1] or b[1] + b[3] + bosluk <= a[1])


def goruntu(no):
    """Bir kapsama karesi: gri duzeyler, nesne maskesi, ornek maskesi, blok sayisi."""
    r = uretec(TOHUM + 400000 + no)
    bloklar = []
    for _ in range(1 + ayrik(r(), [0.24, 0.46, 0.30])):
        h, w = 2 + int(r() * 3), 2 + int(r() * 3)
        bitisik = bool(bloklar) and r() < 0.40
        for _ in range(24):
            if bitisik:                       # onceki blogun kenarina dayali
                a, yan = bloklar[int(r() * len(bloklar))], int(r() * 4)
                sy = a[0] - h if yan == 0 else a[0] + a[2] if yan == 1 else a[0]
                sx = a[1] if yan < 2 else a[1] - w if yan == 2 else a[1] + a[3]
            else:
                sy, sx = int(r() * (BOY - h + 1)), int(r() * (BOY - w + 1))
            yeni = (sy, sx, h, w)
            if not (0 <= sy <= BOY - h and 0 <= sx <= BOY - w):
                continue
            if any(ortusuyor(yeni, b, 0 if bitisik else 1) for b in bloklar):
                continue
            bloklar.append(yeni)
            break
    g = [[ZEMIN + (r() + r() + r() - 1.5) * GURULTU for _ in range(BOY)] for _ in range(BOY)]
    ornek = [[0] * BOY for _ in range(BOY)]
    for sira, (sy, sx, h, w) in enumerate(bloklar, 1):
        for i in range(sy, sy + h):
            for j in range(sx, sx + w):
                g[i][j] += BLOK - ZEMIN
                ornek[i][j] = sira
    maske = [[1 if ornek[i][j] else 0 for j in range(BOY)] for i in range(BOY)]
    return g, maske, ornek, len(bloklar)


VERI = [goruntu(i) for i in range(200)]
EGT, SIN = VERI[:80], VERI[80:]
PIKSEL = len(SIN) * BOY * BOY
NESNE = sum(sum(sum(s) for s in m) for _, m, _, _ in SIN)
print(f"kurgu: 200 goruntu {BOY}x{BOY}, egitim {len(EGT)}, sinama {len(SIN)}; "
      f"sinamada {NESNE} nesne pikseli / {PIKSEL}")
print(f"taban - her pikseli baskin sinifa (zemin) atamak: "
      f"piksel dogrulugu {(PIKSEL - NESNE) / PIKSEL:.4f}, nesne ortusme orani 0.0000")
g, _, o, k = VERI[97]
for i in range(BOY):
    print("   " + "".join(str(min(9, max(0, int(g[i][j] * 10)))) for j in range(BOY))
          + "    " + "".join(".12345"[o[i][j]] for j in range(BOY)))
print(f"   solda gri duzey, sagda ornek numarasi; bu karede {k} blok var")
kurgu: 200 goruntu 12x12, egitim 80, sinama 120; sinamada 2193 nesne pikseli / 17280
taban - her pikseli baskin sinifa (zemin) atamak: piksel dogrulugu 0.8731, nesne ortusme orani 0.0000
   102330223332    ............
   222322797803    ......2222..
   333006674822    ......2222..
   410235775913    ......2222..
   426354786802    ......2222..
   045333776830    ......1111..
   302211787842    ......1111..
   344130859630    ......1111..
   234251999753    ......1111..
   231130223333    ............
   432153222132    ............
   332423044303    ............
   solda gri duzey, sagda ornek numarasi; bu karede 2 blok var

Dersin ilk sayısı taban satırındadır. Sınamadaki 17.280 pikselin 2.193’ü nesnedir; oran 0,1269. Hiçbir şey öğrenmeyen, her piksele “zemin” yazan yordam bu yüzden piksel doğruluğunda 0,8731 alır. Bu sayı bir başarı değil, sınıf oranının kendisidir: nesne pikselleri azınlıkta olduğu için onları tümüyle ıskalamanın bedeli düşüktür.

Aynı çıktının ikinci ölçütteki sayısı 0,0000’dır. Örtüşme oranı yalnız nesne sınıfını sayar; kesişim boş olduğu için oran sıfırdır. Tek bir çıktı, iki ölçütte 0,8731 ve 0,0000 veriyor. Ölçüt seçimi burada bir tercih değil, sayının anlamını belirleyen karardır.

Basılan kare kursun ikinci sorusunu da gösteriyor. Sağdaki örnek haritası altıncı ile dokuzuncu sütunlar arasında iki ayrı blok olduğunu söylüyor; soldaki gri düzeylerde ise tek bir parlak dikdörtgen var. İki bloğun bitiştiği yerde piksel değerleri arasında hiçbir sınır yok.

Aynı Model, İki Temsil

def pencere(g, i, j):
    return [g[min(BOY - 1, max(0, a))][min(BOY - 1, max(0, b))]
            for a in (i - 1, i, i + 1) for b in (j - 1, j, j + 1)]


def oznitelik(g, i, j, genis):
    return [1.0] + (pencere(g, i, j) if genis else [g[i][j]])


def coz(A, b):
    n, x = len(b), [0.0] * len(b)
    M = [A[i][:] + [b[i]] for i in range(n)]
    for k in range(n):
        p = max(range(k, n), key=lambda r: abs(M[r][k]))
        M[k], M[p] = M[p], M[k]
        for r in range(k + 1, n):
            f = M[r][k] / M[k][k]
            for c in range(k, n + 1):
                M[r][c] -= f * M[k][c]
    for k in range(n - 1, -1, -1):
        x[k] = (M[k][n] - sum(M[k][c] * x[c] for c in range(k + 1, n))) / M[k][k]
    return x


def egit(kume, genis):
    """Piksel basina dogrusal karar islevi; en kucuk karelerle uydurulur. MODELDIR."""
    d = 10 if genis else 2
    A, b = [[0.0] * d for _ in range(d)], [0.0] * d
    for g, m, _, _ in kume:
        for i in range(BOY):
            for j in range(BOY):
                x, y = oznitelik(g, i, j, genis), float(m[i][j])
                for p in range(d):
                    b[p] += x[p] * y
                    for q in range(p, d):
                        A[p][q] += x[p] * x[q]
    for p in range(d):
        for q in range(p):
            A[p][q] = A[q][p]
    return coz(A, b)


def kestir(w, g, genis):
    return [[1 if sum(a * c for a, c in zip(w, oznitelik(g, i, j, genis))) >= 0.5 else 0
             for j in range(BOY)] for i in range(BOY)]


def olc(kume, w, genis):
    dogru = kesisim = birlesim = 0
    for g, m, _, _ in kume:
        k = kestir(w, g, genis) if w else [[0] * BOY for _ in range(BOY)]
        for i in range(BOY):
            for j in range(BOY):
                dogru += k[i][j] == m[i][j]
                kesisim += k[i][j] and m[i][j]
                birlesim += k[i][j] or m[i][j]
    return dogru / (len(kume) * BOY * BOY), kesisim / max(1, birlesim)


W1, W9 = egit(EGT, False), egit(EGT, True)
print(f"{'temsil':<22}{'piksel dogrulugu':>18}{'ortusme orani':>16}")
for ad, w, genis in (("taban (hepsi zemin)", None, False),
                     ("tek piksel degeri", W1, False),
                     ("3x3 komsuluk penceresi", W9, True)):
    d, iou = olc(SIN, w, genis)
    print(f"{ad:<22}{d:>18.4f}{iou:>16.4f}")
temsil                  piksel dogrulugu   ortusme orani
taban (hepsi zemin)               0.8731          0.0000
tek piksel degeri                 0.9540          0.6412
3x3 komsuluk penceresi            0.9851          0.8843

İki satır arasındaki tek fark temsildir. Model ailesi aynı (doğrusal karar işlevi), uydurma yordamı aynı (en küçük kareler), eşik aynı (0,5), eğitim kümesi aynı. Değişen şey girdinin ne olduğudur: bir sayı mı, yoksa pikselin kendisiyle birlikte sekiz komşusu mu.

Fark iki ölçütte iki ayrı büyüklükte görünüyor. Piksel doğruluğu 0,9540’tan 0,9851’e çıkıyor, oynama 0,0311. Örtüşme oranı 0,6412’den 0,8843’e çıkıyor, oynama 0,2431. İkinci temsilin kattığı şey aynı şeydir; birinci ölçüt onun yedide birini gösteriyor, çünkü doğruluk paydasının yüzde 87’si zaten zemin pikselidir ve iki temsil de zemin pikselinde hemen hemen hiç yanılmıyor.

Tabana karşı okunduğunda 3x3 penceresinin piksel doğruluğundaki kazancı 0,1120’dir. Bu sayının yanına 0,8731 yazılmadığında “yüzde 98,5 doğruluk” cümlesi kurulabilir ve cümle, hiçbir şey öğrenmeyen yordamın 0,8731 aldığını gizler. Kursun kuralı burada bir kez daha ödenir: alanın tabanı yazılmayan sayı ölçülmemiş sayılır.

Komşuluk penceresinin katkısı nereden geliyor sorusunun yanıtı gürültüdedir. Tek piksel değeri, iki gri düzeyin dağılımı uçlarda örtüştüğü için tek başına yanılır; komşuların ortalaması aynı gürültüyü küçültür ve zemindeki yalnız parlak bir piksel çevresi tarafından bastırılır. Bu, evrişim katmanının M27/K05’te ölçülen ağırlık paylaşımından farklı bir şeydir: burada öğrenilen tek bir küçük ağırlık kümesi vardır ve kazanç girdinin kapsamından gelir.

Anlamsal Bölütleme Nerede Duruyor

def bagli_bilesenler(maske):
    gor, liste = [[0] * BOY for _ in range(BOY)], []
    for i in range(BOY):
        for j in range(BOY):
            if maske[i][j] and not gor[i][j]:
                gor[i][j], yigit, hucre = 1, [(i, j)], []
                while yigit:
                    a, b = yigit.pop()
                    hucre.append((a, b))
                    for da, db in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                        p, q = a + da, b + db
                        if 0 <= p < BOY and 0 <= q < BOY and maske[p][q] and not gor[p][q]:
                            gor[p][q] = 1
                            yigit.append((p, q))
                liste.append(hucre)
    return liste


def dikdortgen_say(hucre):
    """Nesneler dikdortgendir onbilgisiyle bir bilesen kac dikdortgene bolunur."""
    say = []
    for eksen in (0, 1):
        profil, parca, onceki = {}, 0, None
        for a, b in hucre:
            profil.setdefault(a if eksen == 0 else b, set()).add(b if eksen == 0 else a)
        for k in sorted(profil):
            if onceki is None or k != onceki + 1 or profil[k] != profil[onceki]:
                parca += 1
            onceki = k
        say.append(parca)
    return min(say)


def sayim(kume, w):
    bitisik = bilesen = dikdortgen = 0
    for g, m, _, k in kume:
        maske = kestir(w, g, True) if w else m
        b = bagli_bilesenler(maske)
        bitisik += len(bagli_bilesenler(m)) < k
        bilesen += len(b) != k
        dikdortgen += sum(dikdortgen_say(h) for h in b) != k
    return bitisik, bilesen, dikdortgen


for ad, w in (("gercek maske", None), ("3x3 kestirimi", W9)):
    bitisik, bilesen, dikdortgen = sayim(SIN, w)
    print(f"{ad:<14} bitisik blok tasiyan {bitisik:>3}/{len(SIN)} goruntu; "
          f"ornek sayisi yanlis: bilesen sayarak {bilesen:>3}, "
          f"dikdortgen ayristirarak {dikdortgen:>3}")
gercek maske   bitisik blok tasiyan  45/120 goruntu; ornek sayisi yanlis: bilesen sayarak  45, dikdortgen ayristirarak  21
3x3 kestirimi  bitisik blok tasiyan  45/120 goruntu; ornek sayisi yanlis: bilesen sayarak  46, dikdortgen ayristirarak  79

Birinci satır anlamsal bölütlemenin tavanıdır ve bu tavan kusursuz maskeyle ölçülmüştür. Yüz yirmi sınama görüntüsünün 45’i bitişik blok taşıyor; bağlı bileşenleri sayan yordam örnek sayısını tam olarak o 45 görüntüde yanlış veriyor, kalan 75’inde doğru. Maskede hiçbir hata yokken bile oran budur, çünkü hata maskede değil sorunun biçimindedir: anlamsal bölütleme her piksele bir sınıf yazar ve iki bitişik bloğun pikselleri aynı sınıftadır.

İkinci yordam nesne biçimi hakkında bir önbilgi ekliyor — bloklar dikdörtgendir — ve bileşeni en az kaç dikdörtgene bölmek gerektiğini sayıyor. Bu, kusursuz maskede 45 yanlışı 21’e indiriyor: 24 görüntüde bitişiklik, bileşenin dikdörtgen olmayan biçiminden okunabiliyor. Kalan 21 görüntüde iki bloğun birleşimi kendisi de bir dikdörtgendir; bir önceki bölümde basılan kare tam olarak budur ve orada hiçbir biçim önbilgisi iki bloğu ayıramaz.

Üçüncü sayı önbilginin bedelini gösteriyor. Kestirilen maskede bileşen sayan yordamın yanlışı 45’ten 46’ya çıkıyor, yani maske hatası neredeyse hiç zarar vermiyor. Dikdörtgen ayrıştırma ise 21’den 79’a fırlıyor: kestirimdeki tek bir eksik ya da fazla piksel bileşeni dikdörtgen olmaktan çıkarıyor ve yordam onu iki üç parçaya bölüyor. Önbilgi kusursuz girdide kazandırıyor, gürültülü girdide kaybettiriyor; ve bu, örtüşme oranı 0,8843 olan bir maskede oluyor.

Anlamsal ile örnek bölütlemenin ayrıştığı yer buradadır. Anlamsal bölütlemenin çıktısı piksel başına bir sınıftır ve iyi bir piksel doğruluğu bu ayrımı hiçbir zaman getirmez; örnek bölütlemenin çıktısı piksel kümeleridir ve bunun için ya nesne başına ayrı bir çıktı ya da biçim gibi bir dış bilgi gerekir. Ölçüt de ayrışır: piksel doğruluğu ve örtüşme oranı 45 görüntüde tavana yakın kalırken örnek sayısı yanlıştır.

Özet

  • Sınamadaki 17.280 pikselin 2.193’ü nesne olduğu için her pikseli baskın sınıfa atayan taban piksel doğruluğunda 0,8731 alıyor; aynı çıktının nesne örtüşme oranı 0,0000.
  • Aynı doğrusal model tek piksel değeriyle 0,9540 ve 0,6412, 3x3 komşuluk penceresiyle 0,9851 ve 0,8843 veriyor; fark model ailesinden değil temsilden geliyor ve iki ölçütte 0,0311 ile 0,2431 olarak görünüyor.
  • Yüz yirmi görüntünün 45’i bitişik blok taşıyor; kusursuz maskeyle bile bağlı bileşen sayarak örnek sayısı bu 45 görüntüde yanlış çıkıyor, çünkü sınır maskede değil sorunun biçimindedir.
  • Nesnelerin dikdörtgen olduğu önbilgisi kusursuz maskede yanlışı 21’e indiriyor, kestirilen maskede 79’a çıkarıyor; önbilgi gürültülü girdide bedel ödetiyor.

Sonraki Adım

Dört derste görüntü tek bir kareydi ve her karar o karenin kendisinden okundu. Bir kapsama ağı ise kareyi tek tek değil arka arkaya üretir: aynı bölgenin ardışık okumaları bir dizi oluşturur ve dizinin komşuluğu uzayda değil zamandadır. Bu derste komşuluk penceresi piksel doğruluğunu 0,0311, örtüşme oranını 0,2431 oynattı; pencere zamana açıldığında hangi sayı oynar. Sonraki ders kare başına verilen kararın zaman içindeki tutarsızlığını sayar ve o ölçütte hiçbir şey öğrenmeyen bir yordamın alabileceği en iyi sayının ne olduğunu gösterir.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat