İçeriğe geç
academia.sh

Ders 09 / 14

Görüntü Verisi ve Ön İşleme

Pikselin sayıya çevrilme biçiminin ne kadarını taşıdığının ölçülmesi: aynı iki yordam üç temsilde okunduğunda küme geneli ölçekleme hiçbir sayıyı oynatmıyor (0,5500 ve 0,6937 aynen kalıyor), görüntü başına normalleştirme eşik kuralını 0,6937'den 0,9250'ye çıkarıyor, ortalama görüntü tabanını 0,5500'den 0,4875'e düşürüyor. Beş artırma dönüşümünden çeyrek dönüş 160 örneğin 160'ında etiketi ters çeviriyor, kaydırma 1'inde bozuyor. Kırk etiketle en yakın komşu artırmasız 0,5938 ve 0,6250 okurken iki çevirme 0,6875 ve 0,6250, çeyrek dönüş etiketi korunarak eklendiğinde 0,5188 ve 0,5000 okuyor: en sık sınıfın 0,5312'sinin altı.

İçindekiler

Sekiz derste girdi bir dizi idi. Belirteçler soldan sağa sıralanıyordu, bir belirtecin komşusu önündeki ve ardındakiydi, ve sıranın kendisi bilgi taşıyordu. Görüntüde tek bir sıra yoktur: bir pikselin komşusu sağında, solunda, üstünde, altında ve dört köşesindedir, hiçbiri ötekinden önce gelmez. Aranan şey de tek bir hücrede değil, bitişik hücrelerin oluşturduğu bir düzendedir ve o düzen ızgaranın herhangi bir yerinde bulunabilir.

İkinci fark daha sessizdir. Metinde bir belirteç bir simgedir; iki ayrı belgede aynı belirteç tıpatıp aynı şeydir. Piksel ise bir ölçümdür: aynı nesne, ölçüm koşulları değiştiğinde başka sayılarla yazılır. Bu yüzden görüntüde normalleştirme piksel değerlerinin dönüştürülmesi demektir ve M26/K03’ün bir dizgiyi kanonik biçime getiren metin normalleştirmesiyle ilgisi yoktur. Dersin ölçüsü budur — pikselin sayıya çevrilme kararı, hiçbir model değişmeden, aynı yordamın sayısını ne kadar oynatıyor.

  • BG1. Görüntü kurgudur. M26/K06’nın 12x12’lik kapsama ızgarası burada tek kanallı, gri düzeyli küçük bir görüntü yerine geçer. Her hücre bir piksel, değeri 0 ile 255 arasında bir gri düzeydir. Tohum 20260218.
  • BG2. Zemin ve karşıtlık görüntüden görüntüye değişir; bu, kurgunun bilerek konmuş güçlüğüdür.
  • BG3. Nesne kurgudur. Izgaraya tek bir dikdörtgen blok ekilir; kenarları 2 ile 6 arasında ve birbirinden farklıdır.
  • BG4. Etiket bloğun yönüdür. Genişlik yükseklikten büyükse 1, değilse 0. Etiket bloğun nerede olduğuna değil, biçimine bağlıdır.
  • BG5. Blok ızgaranın ortasına doğru toplanır. Konum üç bağımsız çekimin ortalamasıyla seçilir; bu, gerçek görüntü kümelerindeki merkez yanlılığının karşılığıdır ve üçüncü derste bir bedeli olacaktır.
  • BG6. Bölme 400 görüntü üzerinde 160/80/160’tır ve konu boyunca sabittir.
  • BG7. Alanın tabanı iki yordamdır: en sık sınıfı söylemek ve ortalama görüntü — sınıf ortalamaları hesaplanır, görüntü hangisine yakınsa o sınıfa yazılır.
  • BG8. Eşik ve ayar kararları doğrulama kümesinden okunur; süpürme dokuz adayı aşmaz. Kütüphane çağrılmaz, yordamlar ders içinde yazılır.

Görüntü, Piksel ve Kanal

# goruntu.py — MODELDIR. Goruntu kurgusu: M26/K06'nin 12x12 kapsama izgarasi
# burada tek kanalli, gri duzeyli kucuk bir goruntu yerine gecer. Her hucre bir
# pikseldir ve degeri 0-255 arasinda bir gri duzeydir.
import statistics

TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
EN_KUCUK, EN_BUYUK = 2, 6
RAMPA = " .:-=+*#%@"


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 goruntu(no):
    """Bir kapsama goruntusu: zemin, tek bir dikdortgen blok ve gurultu."""
    r = uretec(TOHUM + 700000 + no)
    zemin = 30 + int(r() * 70)
    karsitlik = 20 + int(r() * 36)
    yuk = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    while gen == yuk:
        gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    i = int((r() + r() + r()) / 3 * (BOY - yuk + 1))    # merkeze toplanan konum
    j = int((r() + r() + r()) / 3 * (BOY - gen + 1))
    g = [[0] * BOY for _ in range(BOY)]
    for a in range(BOY):
        for b in range(BOY):
            v = zemin + (karsitlik if i <= a < i + yuk and j <= b < j + gen else 0)
            v += int(r() * 61) - 30
            g[a][b] = 0 if v < 0 else (255 if v > 255 else v)
    return g, (i, j, yuk, gen), (1 if gen > yuk else 0)


def karistir(n, tohum):
    r, s = uretec(tohum), list(range(n))
    for i in range(n - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return s


def ciz(g):
    for satir in g:
        print("   " + "".join(RAMPA[v * len(RAMPA) // 256] for v in satir))


HAM = [goruntu(i) for i in range(400)]
VERI = [HAM[i] for i in karistir(400, TOHUM + 40000)]
EGT, DOG, SIN = VERI[:160], VERI[160:240], VERI[240:]
ortalamalar = [statistics.mean(v for s in g for v in s) for g, _, _ in VERI]

g0, k0, e0 = EGT[0]
print(f"ornek goruntu: blok satir {k0[0]}, sutun {k0[1]}, {k0[2]}x{k0[3]}, etiket {e0}")
ciz(g0)
print(f"{BOY}x{BOY} piksel = {BOY * BOY}, tek kanal; ayni goruntu uc kanalli olsaydi "
      f"{BOY * BOY * 3} sayi")
print(f"goruntu ortalamalari {min(ortalamalar):.1f} ile {max(ortalamalar):.1f} arasinda")
print(f"bolme {len(EGT)}/{len(DOG)}/{len(SIN)}")

ENSIK = max(sum(e for _, _, e in SIN), len(SIN) - sum(e for _, _, e in SIN)) / len(SIN)
print(f"alanin tabani, en sik sinif: {ENSIK:.4f}")
ornek goruntu: blok satir 4, sutun 2, 4x6, etiket 1
   :-:..::::::.
   ....:.::.:::
   :.::-.::.-:-
   ...-.:.::.:.
   ..=+==++:.-.
   --=---=--..:
   :.====---.-:
   :.=-==+=:..:
   .-::.:.-.:-:
   ::.:-:....::
   ::..:-::-:::
   .:-.:--:.-.:
12x12 piksel = 144, tek kanal; ayni goruntu uc kanalli olsaydi 432 sayi
goruntu ortalamalari 32.9 ile 108.0 arasinda
bolme 160/80/160
alanin tabani, en sik sinif: 0.5312

Örnek görüntüde blok dördüncü satırdan başlıyor, dört satır yüksekliğinde ve altı sütun genişliğinde. Çizimde güçlükle seçiliyor: rampa 0-255 aralığına yayıldığı için hem zemin hem blok aynı iki üç imgeye düşüyor. Sayı da bunu söylüyor — görüntü ortalamaları 32,9 ile 108,0 arasında geziniyor, yani bir görüntüde bloğun içi, başka bir görüntüde zeminin kendisi kadar parlaktır.

Bir görüntü 12x12 piksel ve tek kanal, yani 144 sayıdır; üç kanallı olsaydı 432 tutardı. Kanal her piksel için ayrı ölçülen bir büyüklüktür ve sayıyı kendi adedince katlar. Sınamada en sık sınıfı söylemek 0,5312 verir: alanın en ucuz tabanı budur.

Normalleştirme

# onisleme.py — uc temsil ve iki yordam. Yordamlar ayni kalir, yalniz
# pikselin sayiya cevrilme bicimi degisir.
def ham_t(g):
    return g


def olcek_t(g):                                  # kume geneli olcekleme
    return [[v / 255 for v in s] for s in g]


def norm_t(g):                                   # goruntu basina normallestirme
    x = [v for s in g for v in s]
    m = sum(x) / len(x)
    sd = (sum((v - m) ** 2 for v in x) / len(x)) ** 0.5
    return [[(v - m) / sd for v in s] for s in g]


def parlak_kutu(x, esik):
    """Esik ustu piksellerin sinirlayici kutusu."""
    ak = [(a, b) for a in range(BOY) for b in range(BOY) if x[a][b] >= esik]
    if not ak:
        return None
    return (min(a for a, _ in ak), min(b for _, b in ak),
            max(a for a, _ in ak) - min(a for a, _ in ak) + 1,
            max(b for _, b in ak) - min(b for _, b in ak) + 1)


def esik_kurali(x, esik):
    k = parlak_kutu(x, esik)
    return 0 if k is None else (1 if k[3] > k[2] else 0)


def ortalama_goruntu(egt, don):
    """Alanin tabani: sinif ortalamalari, karar en yakin ortalamadir."""
    top = {0: [0.0] * (BOY * BOY), 1: [0.0] * (BOY * BOY)}
    say = {0: 0, 1: 0}
    for g, _, e in egt:
        x = [v for s in don(g) for v in s]
        for i in range(BOY * BOY):
            top[e][i] += x[i]
        say[e] += 1
    M = {e: [v / say[e] for v in top[e]] for e in (0, 1)}

    def karar(g):
        x = [v for s in don(g) for v in s]
        u0 = sum((x[i] - M[0][i]) ** 2 for i in range(BOY * BOY))
        u1 = sum((x[i] - M[1][i]) ** 2 for i in range(BOY * BOY))
        return 1 if u1 < u0 else 0
    return karar


def olc(veri, karar):
    return sum(1 for g, _, e in veri if karar(g) == e) / len(veri)


print("ayni goruntu, goruntu basina normallestirilmis; ayni rampa:")
ciz([[max(0, min(255, int((v + 2) * 51))) for v in s] for s in norm_t(g0)])

TEMSIL = (("ham piksel", ham_t, [100 + 10 * k for k in range(9)]),
          ("kume geneli olcekleme", olcek_t, [(100 + 10 * k) / 255 for k in range(9)]),
          ("goruntu basina normal.", norm_t, [0.6 + 0.15 * k for k in range(9)]))
print(f"\n{'temsil':<24}{'esik':>7}{'ort goruntu':>13}{'esik kurali':>13}")
for ad, don, adaylar in TEMSIL:
    en_iyi = max(adaylar, key=lambda t: olc(DOG, lambda g: esik_kurali(don(g), t)))
    print(f"{ad:<24}{en_iyi:>7.2f}{olc(SIN, ortalama_goruntu(EGT, don)):>13.4f}"
          f"{olc(SIN, lambda g: esik_kurali(don(g), en_iyi)):>13.4f}")
ayni goruntu, goruntu basina normallestirilmis; ayni rampa:
   ===..--:-:-.
   ..:.-::=:-==
   -.===:==:+-+
   ...=::.-=.=.
   :.#%##@%:.+:
   =+%+++%*+:.=
   -:%*%%+++.+:
   =.**%*%%=..:
   .=-:.-:+.=+=
   -=:-==:..::-
   ==..=+-=+-==
   :-+.==+=.+.=

temsil                     esik  ort goruntu  esik kurali
ham piksel               130.00       0.5500       0.6937
kume geneli olcekleme      0.51       0.5500       0.6937
goruntu basina normal.     1.65       0.4875       0.9250

Çizim tek başına yeterince şey söylüyor: her pikselden kendi görüntüsünün ortalaması çıkarılıp kendi standart sapmasına bölündüğünde blok görünür oluyor. Izgara, blok ve gürültü aynıdır; değişen yalnız sayıların ölçeğidir.

Tablonun ikinci satırı sıfır sonuç veriyor. Bütün pikselleri 255’e bölmek her iki yordamın da her iki sayısını olduğu gibi bırakıyor: 0,5500 ve 0,6937. Her görüntüye aynı çarpanı uygulamak ne en yakın ortalamayı ne eşik sıralamasını değiştirir; bu adım bir birim değişikliğidir.

Görüntü başına normalleştirme eşik kuralını 0,6937’den 0,9250’ye taşıyor: fark 0,2313. Sabit bir eşik, zemini 33 olan bir görüntüde bloğu bulur, zemini 108 olan bir görüntüde zeminin yarısını da bloğa katar; normalleştirmeden sonra “ortalamanın 1,65 standart sapma üstü” her görüntüde aynı anlama gelir. Model değişmedi, veri değişmedi, yalnız temsil değişti.

Aynı temsil ortalama görüntü tabanını 0,5500’den 0,4875’e düşürüyor. Bu bir çelişki değildir: ortalama görüntü yordamı iki temsilde de tabanın çevresinde durur, çünkü blok her görüntüde başka bir yerdedir ve ortalama alındığında yön silinir. Ham temsildeki 0,5500, en sık sınıfın 0,5312’sinin yalnız 0,0188 üstüdür. Alanın tabanı burada bir alt sınır çizer, bir hedef değil.

Artırma ve Etiketi Bozan Dönüşüm

# artirma.py — Artirma yalniz ogrenen bir yordamda olculebilir; esik kurali
# ogrenmez. Olcu araci en yakin komsudur ve burada yalnizca bir aractir.
def kaydir(g, di, dj):
    d = statistics.median(v for s in g for v in s)
    return [[g[a - di][b - dj] if 0 <= a - di < BOY and 0 <= b - dj < BOY else d
             for b in range(BOY)] for a in range(BOY)]


DONUSUM = (("kaydirma (1,1)", lambda g: kaydir(g, 1, 1)),
           ("yatay cevirme", lambda g: [s[::-1] for s in g]),
           ("dikey cevirme", lambda g: g[::-1]),
           ("ceyrek donus", lambda g: [[g[BOY - 1 - b][a] for b in range(BOY)]
                                       for a in range(BOY)]),
           ("parlaklik +25", lambda g: [[min(255, v + 25) for v in s] for s in g]))


def kutu_donusumu(k, ad):
    i, j, h, w = k
    if ad.startswith("kaydirma"):
        i, j = i + 1, j + 1
        h, w = min(h, BOY - i), min(w, BOY - j)
    elif ad == "yatay cevirme":
        j = BOY - j - w
    elif ad == "dikey cevirme":
        i = BOY - i - h
    elif ad == "ceyrek donus":
        i, j, h, w = j, BOY - i - h, w, h
    return (i, j, h, w)


print(f"{'donusum':<17}{'etiketi bozulan':>16}")
for ad, _ in DONUSUM:
    boz = sum(1 for _, k, e in EGT
              if (1 if kutu_donusumu(k, ad)[3] > kutu_donusumu(k, ad)[2] else 0) != e)
    print(f"{ad:<17}{f'{boz}/{len(EGT)}':>16}")


def ozet(g):                                 # normallestir, 2x2 ortalama havuzla
    x = [v for s in norm_t(g) for v in s]
    return [sum(x[(2 * a + p) * BOY + 2 * b + q] for p in (0, 1) for q in (0, 1)) / 4
            for a in range(6) for b in range(6)]


def en_yakin(depo, veri):
    d = 0
    for x, y in veri:
        t = min(depo, key=lambda u: sum((u[0][i] - x[i]) ** 2 for i in range(len(x))))
        d += 1 if t[1] == y else 0
    return d / len(veri)


SIN_O = [(ozet(g), e) for g, _, e in SIN]
print(f"\nkirk etiketle, iki ayri kirklik dilim (en sik sinif {ENSIK:.4f})")
print(f"{'kurulum':<36}{'ornek':>7}{'dilim 1':>9}{'dilim 2':>9}")
for ad, secim in (("artirmasiz", ()),
                  ("+ kaydirma", ("kaydirma (1,1)",)),
                  ("+ iki cevirme", ("yatay cevirme", "dikey cevirme")),
                  ("+ ceyrek donus, etiket korunmus", ("ceyrek donus",)),
                  ("+ ceyrek donus, etiket duzeltilmis", ("ceyrek donus*",))):
    say, sonuc = 0, []
    for bas in (0, 40):
        AZ = EGT[bas:bas + 40]
        depo = [(ozet(g), e) for g, _, e in AZ]
        for s in secim:
            f = dict(DONUSUM)[s.rstrip("*")]
            depo += [(ozet(f(g)), (1 - e) if s.endswith("*") else e) for g, _, e in AZ]
        say = len(depo)
        sonuc.append(en_yakin(depo, SIN_O))
    print(f"{ad:<36}{say:>7}{sonuc[0]:>9.4f}{sonuc[1]:>9.4f}")
donusum           etiketi bozulan
kaydirma (1,1)              1/160
yatay cevirme               0/160
dikey cevirme               0/160
ceyrek donus              160/160
parlaklik +25               0/160

kirk etiketle, iki ayri kirklik dilim (en sik sinif 0.5312)
kurulum                               ornek  dilim 1  dilim 2
artirmasiz                               40   0.5938   0.6250
+ kaydirma                               80   0.6625   0.6687
+ iki cevirme                           120   0.6875   0.6250
+ ceyrek donus, etiket korunmus          80   0.5188   0.5000
+ ceyrek donus, etiket duzeltilmis       80   0.6312   0.7063

Üst tablo bu dersin görüntüye özgü sayısıdır. Beş dönüşümün dördü etiketi olduğu gibi bırakıyor: çevirmeler bloğu aynalar, boyutlarını değiştirmez; parlaklık geometriye dokunmaz; kaydırma yalnız 1 örnekte, bloğun kenardan taşıp kırpıldığı örnekte bozuyor. Çeyrek dönüş ise 160 örneğin 160’ında etiketi ters çeviriyor, çünkü yükseklikle genişliği yer değiştiriyor ve etiket tam olarak bu ikisinin karşılaştırmasıdır.

Artırmanın görevden bağımsız bir listesi yoktur: aynı dönüşüm, etiketi bloğun konumu olan bir görevde zararsız, etiketi bloğun yönü olan bir görevde yıkıcıdır. Alt tablo bedeli sayıyor. Kırk etiketle en yakın komşu artırmasız 0,5938 ve 0,6250 okuyor. İki çevirme eklendiğinde birinci dilimde 0,6875, ikincisinde 0,6250; kaydırma eklendiğinde 0,6625 ve 0,6687. Katkı birinci dilimde 0,0937’ye çıkıyor, ikincisinde 0,0437’de kalıyor: iki dilim arasındaki fark, artırmanın kattığı farkla aynı büyüklüktedir. M27/K05’in eğitim pratiği dersinde aynı katkı +0,0026, +0,0013 ve −0,0079 ölçülmüştü; ölçek büyüdükçe küçülür.

Etiketi bozan dönüşüm eklendiğinde sayı 0,5188 ve 0,5000 oluyor: artırmasız durumun altında, en sık sınıfın 0,5312’sinin de altında. Aynı görüntüler etiketleri düzeltilerek eklendiğinde 0,6312 ve 0,7063 okunuyor; iki satır arasındaki tek fark etiketin ne yazıldığıdır. Dönüşümlerin nereye uygulandığı da kritiktir ve burada yalnız eğitim dilimine uygulanır. M27/K05 artırmanın bölmeden önce yapılmasının ayrılmış küme sayısını +0,0203 kaydırdığını ölçmüştü; o sızıntı burada tekrarlanmıyor.

Özet

  • Görüntü 12x12 piksel ve tek kanaldır, yani 144 sayı; üç kanallı olsaydı 432 tutardı. Görüntü ortalamaları 32,9 ile 108,0 arasında gezinir.
  • Alanın tabanı iki yordamdır: en sık sınıf 0,5312, ortalama görüntü 0,5500. Ortalama görüntü yönü okuyamaz, çünkü konum ortalandığında yön silinir.
  • Küme geneli ölçekleme hiçbir sayıyı oynatmaz (0,5500 ve 0,6937 aynen kalır); bu adım bir ön işleme değil, bir birim değişikliğidir.
  • Görüntü başına normalleştirme eşik kuralını 0,6937’den 0,9250’ye çıkarır; fark 0,2313’tür ve tümüyle temsilden gelir. Aynı temsil ortalama görüntüyü 0,5500’den 0,4875’e düşürür.
  • Çeyrek dönüş 160 örneğin 160’ında etiketi ters çevirir, kaydırma 1’inde bozar, çevirmeler ve parlaklık hiçbirinde bozmaz.
  • Kırk etiketle artırmasız 0,5938 ve 0,6250 okunur; iki çevirme 0,6875 ve 0,6250, etiketi korunmuş çeyrek dönüş 0,5188 ve 0,5000 verir — tabanın altı.

Sonraki Adım

Bu derste karar veren yordamlar ya hiç öğrenmiyordu (eşik kuralı) ya da eğitim kümesini olduğu gibi saklıyordu (en yakın komşu). Eşik kuralının normalleştirilmiş temsilde okuduğu 0,9250, görevin geometrisini bilen bir insanın yazdığı üç satırın sayısıdır. Sonraki ders o üç satırı kaldırıp yerine öğrenen bir model koyar ve iki şey ölçer: modelin alanın tabanını ne kadar geçtiği, ve etiket sayısı yirmiye indiğinde başka bir görevden taşınan bir temsilin kaç örneğe bedel olduğu.

İ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