---
title: 'Fonksiyon Yaklaşımı ve Deneyim Tekrarı'
source: 'https://academia.sh/tr/kurslar/pekistirmeli-ve-oneri/fonksiyon-yaklasimi-ve-deneyim-tekrari'
course: 'Pekiştirmeli Öğrenme ve Öneri Sistemleri'
language: tr
updated: '2026-08-17T18:10:18+00:00'
license: 'CC BY-SA 4.0'
---

# 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.

Ö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 $3^5 = 243$ 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.

```python
# 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.

```python
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ş.

```python
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.
