Ders 05 / 14
Fonksiyon Yaklaşımı ve Deneyim Tekrarı
Çizelgenin yerini alan küçük bir ağın ve deneyim tekrarının sayıyla ölçülmesi: 243 durum ile 6 eylemin kurduğu 1.458 hücrenin 9.000 geçiş sonunda yalnız 780'i güncelleniyor, 37 durum hiç görülmüyor ve yalnız 60 durumda altı eylem de deneniyor. Ardışık altılı toplu iş ortalama 1,16 ayrı bölümden, tampondan çekilen altılı 5,50 ayrı bölümden geliyor. Taban çizgileri 0,000 ve 10,432, kural politikası 20,621, çizelge 24,495. 126 parametreli ağ çevrimiçi tek geçişle 23,211 ve 23,071, ardışık altılıyla 22,259 ve 20,146, tekrar tamponuyla 26,233 ve 25,302 veriyor; koşum bandı 2,113'ten 0,930'a iniyor.
İçindekiler
Önceki ders eylem değerini bir çizelgede öğrendi ve çizelgenin kaç hücresinin hiç güncellenmediğini
saydı. Bu ders o sayıyı bir sınır olarak ele alır. Çizelgenin sorunu bellek değildir; her hücrenin
yalnız o hücreye uğrandığında öğrenilmesi ve iki komşu durum arasında hiçbir bilgi
paylaşılmamasıdır. (1,0,2,0,1) durumunda öğrenilen şey (1,0,2,0,0) durumuna geçmez.
Çizelgenin yerine bir fonksiyon yaklaşımı konur: durumu girdi alan, her eyleme bir sayı döndüren küçük bir ağ. Ağ hiç görülmemiş bir durumda da cevap üretir, çünkü benzer durumlardan öğrendiğini oraya taşır. Bedeli, öğrenmenin artık kararlı olmamasıdır — ve bu dersin ölçtüğü şey kararsızlığın nereden geldiği ile deneyim tekrarının onu ne kadar düzelttiğidir.
- PO41. Ortam
01’de kurulan kurgudur ve burada olduğu gibi sürer: beş abone, dönem başına tek ekip, ufuk 30, indirim katsayısı 0,9. Ajanın gördüğü durum gecikme sınıfıdır; arıza derecesi gizlidir. - PO42. Durum beş gecikme sınıfının beşlisidir, yani durum; eylem altıdır — beş aboneden birine gitmek ya da ekip çıkarmamak. Durum–eylem çifti 1.458’dir.
- PO43. Ölçüm
01’deki aynı 300 bölümde yapılır, böylece bu dersin sayıları önceki derslerin sayılarıyla doğrudan karşılaştırılabilir. Getiri indirimli ödül toplamıdır. - PO44. Taban çizgisi iki tanedir: hiç ekip çıkarmamak ve rastgele eylem. Birincisi
tanım gereği sıfırdır ve eylemsizliğin karşılığını verir, ikincisi sıralamasız çabanınkini.
Yanlarına
01’in kural politikası da yazılır, çünkü öğrenen yöntemin geçmesi gereken sayı odur. - PO45. Çizelge, zaman farkı güncellemesiyle 300 bölüm boyunca öğrenilir; keşif oranı 0,60’tan 0,05’e doğrusal iner. Sabit ve düşük bir keşifle ilk denenen eylem kalıcı biçimde öne geçtiği için oran düşürülerek uygulanır.
- PO46. Ağ M27/K05’ten girdi olarak gelir ve yordamı burada tekrarlanmaz: beş girdi, on gizli birim, altı çıktı; gizli katman hiperbolik tanjant, çıkış katmanı doğrusaldır.
- PO47. Ağın hedefi ödülün ona bölünmüş biçimidir. Eylem en büyük çıktı seçilerek belirlendiği için bu ölçek politikayı değiştirmez; yalnız hedefleri ağın çıkış aralığına yaklaştırır.
- PO48. Ağ kullanan her ölçü iki koşumla basılır ve koşumlar arasında yalnız başlangıç değerleri değişir.
Çizelgenin Dolduramadığı Yer
İlk blok ortamı yeniden kurar, üç karşılaştırma sayısını basar ve çizelgenin doluluğunu sayar.
# cizelge.py — Ortam 01'de kurulan KURGUDUR: bes abone, her donem tek ekip. import math import statistics TOHUM, M32 = 20260218, 0xFFFFFFFF ABONE, KAZANC, MALIYET = 5, (0, 3, 9), 2 KOTULESME = (0.30, 0.05, 0.60, 0.15, 0.45) EYLEM, UFUK, INDIRIM = ABONE + 1, 30, 0.9 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 class Ortam: """Ariza derecesi d gizlidir; ajanin gordugu durum gecikme sinifidir.""" def __init__(self, tohum): self.r = uretec(tohum) self.d, self.g = [0] * ABONE, [0] * ABONE for i in range(ABONE): self.g[i] = int(self.r() * 6) for _ in range(self.g[i]): if self.d[i] < 2 and self.r() < KOTULESME[i]: self.d[i] += 1 def durum(self): return tuple(min(2, x // 3) for x in self.g) def adim(self, a): odul = 0.0 if a < ABONE: odul = KAZANC[self.d[a]] - MALIYET self.d[a] = 0 self.g[a] = 0 for i in range(ABONE): if i != a: self.g[i] += 1 if self.d[i] < 2 and self.r() < KOTULESME[i]: self.d[i] += 1 return self.durum(), odul def olc(politika, n=300): # 01'deki ayni 300 bolum, ayni ufuk g = [] for k in range(n): o = Ortam(TOHUM + 1000 * k) s, G, c = o.durum(), 0.0, 1.0 for _ in range(UFUK): s2, od = o.adim(politika(s)) G, c, s = G + c * od, c * INDIRIM, s2 g.append(G) return statistics.mean(g) def cizelge_egit(tohum, B=300, ogrenme=0.20): Q, sayac, r = {}, {}, uretec(tohum) for b in range(B): kesif = 0.60 - 0.55 * b / (B - 1) o = Ortam(tohum + 100 * b) s = o.durum() for _ in range(UFUK): a = (int(r() * EYLEM) if r() < kesif else max(range(EYLEM), key=lambda e: Q.get((s, e), 0.0))) s2, od = o.adim(a) eski = Q.get((s, a), 0.0) Q[(s, a)] = eski + ogrenme * (od + INDIRIM * max(Q.get((s2, e), 0.0) for e in range(EYLEM)) - eski) sayac[(s, a)] = sayac.get((s, a), 0) + 1 s = s2 return Q, sayac Q, SAYAC = cizelge_egit(TOHUM + 900) DURUM, CIFT = 3 ** ABONE, 3 ** ABONE * EYLEM gorulen = {s for s, _ in SAYAC} tam = sum(all((s, e) in SAYAC for e in range(EYLEM)) for s in gorulen) print(f"durum {DURUM}, eylem {EYLEM}, durum-eylem cifti {CIFT}") print(f"300 bolum x {UFUK} adim = {300 * UFUK} gecis; guncellenen cift {len(SAYAC)}" f" ({CIFT - len(SAYAC)} hic guncellenmedi), gorulen durum {len(gorulen)}") print(f"alti eylemi de denenmis durum {tam}, hic gorulmemis durum {DURUM - len(gorulen)}") print(f"{'taban: hic ekip cikarmamak':<28}{olc(lambda s: ABONE):8.3f}") rp = uretec(TOHUM + 7) print(f"{'taban: rastgele eylem':<28}{olc(lambda s: int(rp() * EYLEM)):8.3f}") print(f"{'kural: gecikmesi en buyuge':<28}" f"{olc(lambda s: ABONE if max(s) == 0 else s.index(max(s))):8.3f}") print(f"{'cizelge':<28}{olc(lambda s: max(range(EYLEM), key=lambda e: Q.get((s, e), 0.0))):8.3f}")
durum 243, eylem 6, durum-eylem cifti 1458 300 bolum x 30 adim = 9000 gecis; guncellenen cift 780 (678 hic guncellenmedi), gorulen durum 206 alti eylemi de denenmis durum 60, hic gorulmemis durum 37 taban: hic ekip cikarmamak 0.000 taban: rastgele eylem 10.432 kural: gecikmesi en buyuge 20.621 cizelge 24.495
Toplanan veri şudur: 9.000 geçiş yapıldı, 1.458 hücrenin 780’i güncellendi ve 678’i hiç dokunulmadan kaldı. Bu sayı keşif takvimine bağlıdır ve başka bir takvimle başka çıkar; burada bağlayıcı olan büyüklük mertebesidir. Politika kendi verisini topladığı için 243 durumun 37’si hiç görülmedi ve yalnız 60 durumda altı eylemin hepsi denendi. O 37 durumda çizelgenin altı girdisi de sıfırdır; en büyüğünü seçme kuralı orada ilk eylemi seçer ve bu seçimin öğrenilmiş bir yanı yoktur.
Çizelge yine de kazanıyor: 24,495, kural politikasının 20,621’inin üstünde. Sorun bu ölçekte sonucun kötü olması değil, ölçeğin kendisidir. Beş abone 243 durum verdi; yedi abone 2.187 durum ve 17.496 çift verir. Geçiş sayısı aynı kaldığında boş hücre oranı büyür, çünkü çizelge komşu durumlar arasında hiçbir şey paylaşmaz.
Çizelge Yerine Fonksiyon
Ağ bu paylaşımı kurar. Girdisi beş gecikme sınıfıdır, çıktısı altı eylem değeridir; hedef, önceki dersteki zaman farkı hedefinin aynısıdır — alınan ödül artı indirimli en iyi bir sonraki eylem değeri. Fark, güncellemenin tek bir hücreye değil bütün ağırlıklara yayılmasıdır. Kararsızlık da buradan gelir: bir durumda yapılan düzeltme başka durumların çıktısını da oynatır.
İkinci sorun verinin geliş sırasıdır. Ajan geçişleri ardışık üretir; bir bölümün altı ardışık adımı birbirinin devamıdır. Aşağıdaki blok ağı tanımlar ve bu ilişkiyi iki sayıyla ölçer.
OLCEK = 10.0 # ag hedefi odul/10 olceginde tutulur def ilklendir(tohum, gizli=10): # kucuk ag: 5 -> 10 -> 6; yordami M27/K05'te r, ag = uretec(tohum), [] for a, b in zip((ABONE, gizli, EYLEM), (gizli, EYLEM)): o = math.sqrt(2.0 / a) ag.append(([[(r() * 2 - 1) * o for _ in range(a)] for _ in range(b)], [0.0] * b)) return ag def ileri(ag, x): (W1, y1), (W2, y2) = ag h = [math.tanh(sum(w * v for w, v in zip(s, x)) + b) for s, b in zip(W1, y1)] return h, [sum(w * v for w, v in zip(s, h)) + b for s, b in zip(W2, y2)] def giris(s): return [x / 2.0 for x in s] def guncelle(ag, toplu, ogrenme): # yalniz secilen eylemin cikisi duzeltilir (W1, y1), (W2, y2) = ag n, g = len(toplu), len(y1) gW1, gy1 = [[0.0] * ABONE for _ in range(g)], [0.0] * g gW2, gy2 = [[0.0] * g for _ in range(EYLEM)], [0.0] * EYLEM for x, a, hedef in toplu: h, q = ileri(ag, x) e = q[a] - hedef for p in range(g): gW2[a][p] += e * h[p] dh = e * W2[a][p] * (1 - h[p] * h[p]) gy1[p] += dh for j in range(ABONE): gW1[p][j] += dh * x[j] gy2[a] += e for j in range(EYLEM): for p in range(g): W2[j][p] -= ogrenme * gW2[j][p] / n y2[j] -= ogrenme * gy2[j] / n for p in range(g): for j in range(ABONE): W1[p][j] -= ogrenme * gW1[p][j] / n y1[p] -= ogrenme * gy1[p] / n def ag_egit(tohum, tampon_boy, toplu, B=120, ogrenme=0.10): ag, r, tmp = ilklendir(tohum), uretec(tohum + 77), [] for b in range(B): kesif = 0.60 - 0.55 * b / (B - 1) o = Ortam(tohum + 100 * b) s = o.durum() for _ in range(UFUK): a = (int(r() * EYLEM) if r() < kesif else max(range(EYLEM), key=lambda e: ileri(ag, giris(s))[1][e])) s2, od = o.adim(a) tmp.append((s, a, od / OLCEK, s2)) if len(tmp) > tampon_boy: tmp.pop(0) ornek = (tmp[-toplu:] if tampon_boy == toplu # ardisik pencere else [tmp[int(r() * len(tmp))] for _ in range(toplu)]) guncelle(ag, [(giris(ss), sa, so + INDIRIM * max(ileri(ag, giris(sy))[1])) for ss, sa, so, sy in ornek], ogrenme) s = s2 return ag def ag_politika(ag): return lambda s: max(range(EYLEM), key=lambda e: ileri(ag, giris(s))[1][e]) r = uretec(TOHUM + 3) # 30 bolumluk bir iz, cizelge politikasiyla IZ = [] for b in range(30): o = Ortam(TOHUM + 100000 + b) s = o.durum() for _ in range(UFUK): a = (int(r() * EYLEM) if r() < 0.15 else max(range(EYLEM), key=lambda e: Q.get((s, e), 0.0))) IZ.append((s, a, b)) s = o.adim(a)[0] def dagilim(g): # toplu isteki durumlar arasi ortalama sinif farki c = [abs(x - y) for i in range(len(g)) for j in range(i + 1, len(g)) for x, y in zip(g[i][0], g[j][0])] return sum(c) / (len(g) * (len(g) - 1) / 2) N = len(IZ) - 6 ard = [sum(dagilim(IZ[i:i + 6]) for i in range(N)) / N, sum(len({t[2] for t in IZ[i:i + 6]}) for i in range(N)) / N] tam2 = [0.0, 0.0] for _ in range(N): g = [IZ[int(r() * len(IZ))] for _ in range(6)] tam2[0] += dagilim(g) / N tam2[1] += len({t[2] for t in g}) / N print(f"{'altili toplu is':<26}{'ardisik':>10}{'tampondan':>12}") print(f"{'ortalama sinif farki':<26}{ard[0]:>10.2f}{tam2[0]:>12.2f}") print(f"{'ayri bolum sayisi':<26}{ard[1]:>10.2f}{tam2[1]:>12.2f}")
altili toplu is ardisik tampondan ortalama sinif farki 2.71 2.93 ayri bolum sayisi 1.16 5.50
İkinci satır ilişkiyi doğrudan söylüyor: ardışık bir altılı ortalama 1,16 ayrı bölümden geliyor, yani neredeyse tamamı tek bir bölümün art arda gelen adımlarıdır. Tampondan çekilen altılı 5,50 ayrı bölümden geliyor. Durum tarafındaki fark daha ölçülüdür — ardışık altılıda iki durum arasındaki ortalama gecikme sınıfı farkı 2,71, tampondan çekilende 2,93. Ağ ardışık kurulumda her adımda birbirine yakın altı örneğe bakar ve ağırlıklarını o dar bölgeye göre kaydırır; birkaç adım sonra başka bir bölgeye geçtiğinde kaymayı geri alır.
Tekrar Tamponunun Kattığı Fark
Deneyim tekrarı tek satırlık bir değişikliktir: geçişler bir tampona yazılır ve güncelleme tampondan rastgele çekilen bir altılıyla yapılır. Farkın toplu iş boyundan mı yoksa örneğin nereden geldiğinden mi doğduğunu ayırmak için üçüncü bir kurulum eklenir — toplu iş kullanmayan, yalnız son geçişle güncelleyen çevrimiçi biçim. Üçünün de bütçesi aynıdır: 120 bölüm, 3.600 geçiş.
SONUC = {} print(f"{'kurulum':<22}{'kosum 1':>9}{'kosum 2':>9}{'band':>7}") for ad, tampon, toplu in (("cevrimici tek gecis", 1, 1), ("ardisik altili", 6, 6), ("tekrar tamponu", 900, 6)): SONUC[ad] = [olc(ag_politika(ag_egit(TOHUM + k, tampon, toplu))) for k in (1, 2)] g = SONUC[ad] print(f"{ad:<22}{g[0]:>9.3f}{g[1]:>9.3f}{max(g) - min(g):>7.3f}") A, T = SONUC["ardisik altili"], SONUC["tekrar tamponu"] par = ABONE * 10 + 10 + 10 * EYLEM + EYLEM print(f"\nayni toplu is boyu, ardisik yerine tampondan: " f"{max(A):.3f} -> {max(T):.3f} ve {min(A):.3f} -> {min(T):.3f}") print(f"kosum bandi {max(A) - min(A):.3f} -> {max(T) - min(T):.3f}") print(f"ag {par} parametre; cizelge {CIFT} hucre, {CIFT - len(SAYAC)} tanesi bos")
kurulum kosum 1 kosum 2 band cevrimici tek gecis 23.211 23.071 0.139 ardisik altili 22.259 20.146 2.113 tekrar tamponu 26.233 25.302 0.930 ayni toplu is boyu, ardisik yerine tampondan: 22.259 -> 26.233 ve 20.146 -> 25.302 kosum bandi 2.113 -> 0.930 ag 126 parametre; cizelge 1458 hucre, 678 tanesi bos
Üç satır sırayla okunur. Toplu iş kullanmak tek başına bir kazanç değildir: çevrimiçi tek geçiş 23,211 ve 23,071 verirken ardışık altılı 22,259 ve 20,146 veriyor, yani altı örneği ortalamak sayıyı düşürüyor. İkinci koşum 20,146 ile kural politikasının 20,621’inin de altına iniyor. Aynı toplu iş boyu tampondan çekildiğinde 26,233 ve 25,302 çıkıyor. Kazanç toplu iştan değil, örneğin nereden geldiğinden doğuyor.
İkinci sayı kararlılıktır. Ardışık kurulumun koşum bandı 2,113; tekrar tamponununki 0,930. Ardışık kurulumda tek bir koşuma bakarak karar vermek, yalnız başlangıç değerleri değişerek iki birimden fazla oynayan bir sayıya bakmaktır. Bu kursun iki koşum kuralı bu yüzden vardır.
Son satır ölçeği kapatır. Ağ 126 parametre taşıyor ve 243 durumun tamamı için altı eylem değeri üretiyor; çizelge 1.458 hücre taşıyordu ve 678’i boştu. Ağın hiç görülmemiş 37 durumda verdiği cevap doğru olmak zorunda değildir, ama keyfi de değildir: komşu durumlardan taşınmış bir tahmindir.
Özet
- Çizelge komşu durumlar arasında hiçbir şey paylaşmaz. 9.000 geçiş sonunda 1.458 hücrenin 678’i hiç güncellenmedi, 243 durumun 37’si hiç görülmedi ve yalnız 60 durumda altı eylem de denendi.
- Fonksiyon yaklaşımı çizelgenin yerine durumu girdi alan bir ağ koyar: 126 parametre, 1.458 hücreye karşılık, ve hiç görülmemiş durumda da bir cevap.
- Ardışık geçişler ilişkilidir ve sayısı yazılır: ardışık altılı ortalama 1,16 ayrı bölümden, tampondan çekilen altılı 5,50 ayrı bölümden geliyor.
- Aynı bütçede çevrimiçi tek geçiş 23,211 ve 23,071, ardışık altılı 22,259 ve 20,146, tekrar tamponu 26,233 ve 25,302 veriyor. Kazanç toplu iştan değil örneğin nereden geldiğinden gelir.
- Deneyim tekrarı düzeyi yükseltmenin yanında kararlılık da katar: koşum bandı 2,113’ten 0,930’a iniyor, ve ardışık kurulumun kötü koşumu kural politikasının altına düşüyor.
Sonraki Adım
Beş derste ajan hep aynı yoldan karar verdi: her eylem için bir değer kestirildi ve en büyüğü seçildi. Politika, değerin bir yan ürünüydü. Bu, değer kestirimindeki küçük bir kaymanın politikayı tümüyle değiştirebileceği anlamına gelir — iki eylemin değeri birbirine yakınsa, kestirimin oynaması seçimi de oynatır. Sonraki ders politikayı doğrudan parametreleştirir ve değeri aradan çıkarır: her eyleme bir olasılık atanır ve olasılıklar getiriyi artıracak yönde güncellenir. Ölçülecek olan bu yolun bedelidir — güncelleme yönü artık örneklenmiş bölümlerden kestirilir, ve aynı politikayla aynı bütçede kaç bölümün kaç ayrı yön verdiği sayılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.