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.