---
title: 'Yinelemeli Ağlar'
source: 'https://academia.sh/tr/kurslar/derin-ogrenme/yinelemeli-aglar'
course: 'Derin Öğrenme'
language: tr
updated: '2026-08-17T18:10:08+00:00'
license: 'CC BY-SA 4.0'
---

# Yinelemeli Ağlar

Gizli durumun dizi uzadıkça ne kadar bilgi taşıdığının sayılması: aynı dizinin yalnız ilk adımı değiştirildiğinde son gizli durumdaki fark uzunluk 2'de 0,92844 iken uzunluk 12'de 0,00913'e iniyor, adım başına çarpan 0,62. İlk adımdaki işaretin son durumdan geri okunma doğruluğu 1,0000'den 0,5300'e, yani rastlantı düzeyine düşüyor. Aynı 61 parametreli ağ uzunluk 2'de taban çizgisini 0,2300 ve 0,2800, uzunluk 8'de 0,2100 ve 0,1700, uzunluk 10'da 0,1850 ve 0,1850 geçerken uzunluk 12'de yalnız 0,0250 ve 0,0050 geçiyor: bağımlılık on adımda taşınıyor, on iki adımda taşınmıyor.

Üç derste girdi bir ızgaraydı ve ağa bir kerede verildi. Bir abonenin sayaç okumaları ise bir
**sıra** oluşturur: okumalar dönem dönem gelir, sıradaki yer anlamlıdır ve abone başına okuma
sayısı aynı olmak zorunda değildir. Sabit boyda bir pencereden bakan bir çekirdek bu veriye
uymaz — pencere dışında kalan geçmiş görünmez.

**Yinelemeli ağ** diziyi baştan sona adım adım okur ve o ana kadar gördüklerini bir **gizli
durumda** biriktirir. Her adımda aynı ağırlıklar kullanılır; bu, evrişimin uzamda yaptığı ağırlık
paylaşımının zaman eksenindeki karşılığıdır ve parametre sayısını dizi uzunluğundan bağımsız kılar.
Bu dersin ölçüsü şudur: dizinin **başındaki** bir bilgi, dizi uzadıkça gizli durumda ne kadar
kalıyor.

- **MI28. Okuma dizisi kurgudur.** Her abone için on iki dönemlik sayaç okuması üretilir; tohum
  20260218. Uzunluk **12'yi aşmaz** ve dizi bu payın ilk üç dersindeki ızgaradan bağımsız,
  ayrı bir kurgudur.
- **MI29. İşaret dizinin başındadır.** Abonelerin yaklaşık yarısında **ilk dönemin okuması
  sıfırdır** — sayaç değişimi. Sıfır okuma yalnız ilk dönemde görülür, böylece işaret tektir ve
  yeri bellidir.
- **MI30. Etiket iki koşulun birlikte sağlanmasıdır:** ilk dönem sıfır okuma **ve** son dönemin
  okuması tarife basamağı 25 m³'ün üstünde. Ağın son adımda karar verebilmesi için dizinin başındaki
  bilgiyi sonuna kadar taşıması gerekir.
- **MI31. Her adımın girdisi iki sayıdır:** okumanın 40 m³'e bölünmüş değeri ve sıfır okuma
  göstergesi.
- **MI32. Etiket dizi uzunluğuna bağlıdır**, çünkü "son dönem" uzunlukla değişir. Bu yüzden
  **her uzunluk için taban çizgisi ayrıca hesaplanır** ve karşılaştırmalar tabana göre farkla
  yapılır.
- **MI33. Ağ sabittir:** 6 birimlik gizli durum, hiperbolik tanjant, çıkış son gizli durumdan
  okunan sigmoit. Parametre sayısı **61**'dir ve dizi uzunluğu ne olursa olsun değişmez.
- **MI34. Bilgi ölçümü eğitimsiz ağda yapılır.** Aynı dizinin yalnız ilk adımı değiştirilir ve iki
  son gizli durumun farkı ölçülür. Sorulan şey yapının ne **taşıyabildiğidir**, eğitimin ne
  başardığı değil.
- **MI35. Kütüphane çağrılmaz;** ileri geçiş, zaman içinde geri yayılım ve eğitim döngüsü ders
  içinde yazılır ve **modeldir**.
- **MI36. Her ağ iki kez koşulur;** ikinci koşumda yalnız başlangıç değerleri değişir.

## Dizi ve Gizli Durum

```python
# dizi.py — MODELDIR. Okuma dizisi KURGUDUR: her abone icin on iki donemlik
# sayac okumasi uretilir. Ilk donemin okumasi bir kismi abonede SIFIRDIR
# (sayac degisimi); bu, dizinin basina konan ISARETTIR. Etiket, isaretin
# varligi ile son donemin tarife basamagini asmasinin BIRLIKTE saglanmasidir.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
UZUN, TARIFE, OLCEK, GIZLI = 12, 25.0, 40.0, 6


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 okuma_dizisi(no):
    r = uretec(TOHUM + 400000 + no)
    taban = 23.0 + 8.0 * r()
    d = [math.floor(taban * math.exp((r() + r() + r() - 1.5) * 0.62) * 100 + 0.5) / 100
         for _ in range(UZUN)]
    if r() < 0.5:
        d[0] = 0.0                           # isaret
    return d


def kes(d, T):
    """Ilk T donem; girdi adim basina iki sayi, etiket iki kosulun birlikte."""
    x = [[v / OLCEK, 1.0 if v == 0.0 else 0.0] for v in d[:T]]
    return x, 1 if (d[0] == 0.0 and d[T - 1] > TARIFE) 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


HAM = [okuma_dizisi(i) for i in range(500)]
DZ = [HAM[i] for i in karistir(500, TOHUM + 95000)]
EGT, SIN = DZ[:200], DZ[300:]


def taban_cizgisi(T):
    p = sum(kes(d, T)[1] for d in SIN)
    return max(p, len(SIN) - p) / len(SIN)


def kur(tohum, H=GIZLI):
    r = uretec(tohum)
    a1, a2 = (1 / 2) ** 0.5, (1 / H) ** 0.5
    return [[[(r() * 2 - 1) * a1 for _ in range(2)] for _ in range(H)],
            [[(r() * 2 - 1) * a2 for _ in range(H)] for _ in range(H)],
            [0.0] * H, [(r() * 2 - 1) * a2 for _ in range(H)], [0.0]]


def ileri(P, x):
    """h_t = tanh(Wx x_t + Wh h_(t-1) + b); cikis son gizli durumdan okunur."""
    Wx, Wh, b, v, c = P
    H = len(b)
    h, izler = [0.0] * H, []
    for t in range(len(x)):
        h = [math.tanh(b[k] + Wx[k][0] * x[t][0] + Wx[k][1] * x[t][1]
                       + sum(Wh[k][j] * h[j] for j in range(H))) for k in range(H)]
        izler.append(h)
    z = c[0] + sum(v[k] * h[k] for k in range(H))
    return 1 / (1 + math.exp(-max(-30, min(30, z)))), izler


ornek = next(d for d in DZ if d[0] == 0.0 and d[UZUN - 1] > TARIFE)
print("ornek dizi (m3):", " ".join(f"{v:.2f}" for v in ornek))
print(f"isaret orani {sum(1 for d in DZ if d[0] == 0.0) / len(DZ):.3f}; "
      f"bolme {len(EGT)}/100/{len(SIN)}; gizli durum {GIZLI} birim; "
      f"parametre {GIZLI * 2 + GIZLI * GIZLI + GIZLI + GIZLI + 1}")
print(f"{'T':>3}{'pozitif':>9}{'taban cizgisi':>15}")
for T in (2, 4, 6, 8, 10, 12):
    print(f"{T:>3}{sum(kes(d, T)[1] for d in SIN):>9}{taban_cizgisi(T):>15.4f}")
```

```
ornek dizi (m3): 0.00 26.80 37.98 20.95 35.18 49.78 24.15 22.38 47.64 35.14 26.95 25.18
isaret orani 0.514; bolme 200/100/200; gizli durum 6 birim; parametre 61
  T  pozitif  taban cizgisi
  2       56         0.7200
  4       56         0.7200
  6       63         0.6850
  8       51         0.7450
 10       60         0.7000
 12       58         0.7100
```

Örnek dizide ilk okuma sıfırdır ve son okuma 25,18 m³ ile tarife basamağının üstündedir; etiket
1'dir. Aradaki on dönem karar için hiçbir şey söylemez — ağın taşıması gereken tek bilgi baştaki
sıfırdır.

Parametre sayısı **61**'dir ve alt tablodaki altı uzunluğun hepsinde aynıdır. Aynı ağırlıklar her
adımda yeniden kullanılır; bir dizi ne kadar uzarsa uzasın yeni ağırlık gerekmez. Bu, evrişimin
uzamda yaptığının zaman eksenindeki karşılığıdır ve tam bağlı bir katmanın yapamayacağı şeydir:
tam bağlı katman girdinin uzunluğunu baştan bilmek zorundadır.

Taban çizgileri uzunluğa göre 0,6850 ile 0,7450 arasında geziniyor, çünkü etiketin ikinci koşulu
"son dönem" ile tanımlıdır ve son dönem uzunlukla değişir. Bu yüzden uzunluklar arasındaki
karşılaştırma ham doğrulukla değil, **tabana göre farkla** yapılır.

## Gizli Durum Neyi Taşıyor

```python
# iz.py — gizli durumun tasidigi bilgi. Ayni dizinin YALNIZ ilk adimi
# degistirilir (isaretli / isaretsiz) ve son gizli durumlarin farki olculur.
# Olcum EGITIMSIZ agda yapilir: sorulan sey yapinin ne tasiyabildigidir.
def ciftler(d, T):
    x, _ = kes(d, T)
    a = [s[:] for s in x]
    a[0] = [0.0, 1.0]
    b = [s[:] for s in x]
    b[0] = [d[1] / OLCEK, 0.0]
    return a, b


def geri_okuma(P, T):
    """En yakin merkez okuyucusu: h_T'den isaret geri okunabiliyor mu."""
    hs = [(ileri(P, kes(d, T)[0])[1][-1], 1 if d[0] == 0.0 else 0) for d in DZ]
    egt, sin = hs[:200], hs[300:]
    mer, say = [[0.0] * GIZLI, [0.0] * GIZLI], [0, 0]
    for h, s in egt:
        say[s] += 1
        for k in range(GIZLI):
            mer[s][k] += h[k]
    for s in (0, 1):
        mer[s] = [u / say[s] for u in mer[s]]
    ort = [(mer[0][k] * say[0] + mer[1][k] * say[1]) / len(egt) for k in range(GIZLI)]
    sd = [max(1e-9, (sum((h[k] - ort[k]) ** 2 for h, _ in egt) / len(egt)) ** 0.5)
          for k in range(GIZLI)]

    def uzak(h, s):
        return sum(((h[k] - mer[s][k]) / sd[k]) ** 2 for k in range(GIZLI))
    return sum(1 for h, s in sin if (uzak(h, 1) < uzak(h, 0)) == (s == 1)) / len(sin)


print(f"{'T':>3}{'h farki k1':>12}{'h farki k2':>12}{'adim basina k1':>16}"
      f"{'geri okuma k1':>15}{'geri okuma k2':>15}")
onceki = [None, None]
for T in (2, 4, 6, 8, 10, 12):
    sat = []
    for P in (kur(TOHUM + 11), kur(TOHUM + 12)):
        f = 0.0
        for d in DZ:
            a, b = ciftler(d, T)
            ia, ib = ileri(P, a)[1][-1], ileri(P, b)[1][-1]
            f += sum(abs(ia[k] - ib[k]) for k in range(GIZLI))
        sat.append((f / len(DZ), geri_okuma(P, T)))
    oran = "-" if onceki[0] is None else f"{(sat[0][0] / onceki[0]) ** 0.5:.3f}"
    onceki[0] = sat[0][0]
    print(f"{T:>3}{sat[0][0]:>12.5f}{sat[1][0]:>12.5f}{oran:>16}"
          f"{sat[0][1]:>15.4f}{sat[1][1]:>15.4f}")
```

```
  T  h farki k1  h farki k2  adim basina k1  geri okuma k1  geri okuma k2
  2     0.92844     1.39970               -         1.0000         0.9750
  4     0.34417     0.24972           0.609         0.7850         0.9350
  6     0.15338     0.06435           0.668         0.8000         0.6350
  8     0.05986     0.01560           0.625         0.5900         0.5500
 10     0.02362     0.00333           0.628         0.4600         0.4600
 12     0.00913     0.00067           0.622         0.5300         0.4750
```

İlk sütun dersin sayısıdır. Aynı dizinin yalnız ilk adımı değiştirildiğinde son gizli durumda
kalan fark uzunluk 2'de **0,92844**, uzunluk 12'de **0,00913**'tür — yüzde birinden az. Dördüncü
sütun küçülmenin biçimini veriyor: adım başına çarpan 0,609 ile 0,668 arasında, yani **sabit bir
çarpanla** üstel bir azalma. Gizli durum bilgiyi unutmaya karar vermiyor; her adımda aynı dizeyle
çarpılıyor ve çarpanın büyüklüğü birden küçük olduğu için iz kendiliğinden siliniyor.

İkinci koşum aynı biçimi farklı bir hızla gösteriyor: uzunluk 12'de fark 0,00067, birinci koşumun
on dörtte biri. Yalnız başlangıç değerleri değişti; unutma hızı bir mimari sabiti değil,
ilklendirmenin sonucudur.

Son iki sütun bunun ne anlama geldiğini yazıyor. Uzunluk 2'de işaret son gizli durumdan **1,0000**
doğrulukla geri okunuyor. Uzunluk 8'de 0,5900'e, uzunluk 10'da 0,4600'e iniyor — işaret oranı
0,514 olduğuna göre bu rastlantı düzeyidir. Uzunluk 12'deki 0,5300 bir toparlanma değil, aynı
düzeydeki ölçüm oynamasıdır. Bilgi gizli durumda **yoktur**; hiçbir okuyucu onu geri getiremez.

## Ne Kadar Geriye Taşınıyor

```python
# egit.py — MODELDIR: zaman icinde geri yayilim elle yazilir. Ayni ag, ayni
# tur butcesi, degisen tek sey dizi uzunlugudur.
def egit(P, veri, tur, gadim, tohum):
    Wx, Wh, b, v, c = P
    H, r, n = len(b), uretec(tohum), len(veri)
    for _ in range(tur):
        s = list(range(n))
        for i in range(n - 1, 0, -1):
            j = int(r() * (i + 1))
            s[i], s[j] = s[j], s[i]
        for idx in s:
            x, y = veri[idx]
            p, izler = ileri(P, x)
            d = p - y
            dh = [d * v[k] for k in range(H)]
            for k in range(H):
                v[k] -= gadim * d * izler[-1][k]
            c[0] -= gadim * d
            for t in range(len(x) - 1, -1, -1):
                onceki = izler[t - 1] if t > 0 else [0.0] * H
                yeni = [0.0] * H
                for k in range(H):
                    g = dh[k] * (1 - izler[t][k] ** 2)
                    b[k] -= gadim * g
                    Wx[k][0] -= gadim * g * x[t][0]
                    Wx[k][1] -= gadim * g * x[t][1]
                    for j in range(H):
                        yeni[j] += g * Wh[k][j]
                        Wh[k][j] -= gadim * g * onceki[j]
                dh = yeni
    return P


def dogruluk(P, veri):
    return sum(1 for x, y in veri if (ileri(P, x)[0] >= 0.5) == (y == 1)) / len(veri)


print(f"{'T':>3}{'taban':>8}{'kosum 1':>9}{'kosum 2':>9}{'fark 1':>9}{'fark 2':>9}"
      f"{'kosum araligi':>15}")
for T in (2, 4, 6, 8, 10, 12):
    eg = [kes(d, T) for d in EGT]
    sn = [kes(d, T) for d in SIN]
    tb, s = taban_cizgisi(T), []
    for tohum in (TOHUM + 11, TOHUM + 12):
        P = kur(tohum)
        egit(P, eg, 30, 0.05, tohum + 500)
        s.append(dogruluk(P, sn))
    print(f"{T:>3}{tb:>8.4f}{s[0]:>9.4f}{s[1]:>9.4f}{s[0] - tb:>+9.4f}"
          f"{s[1] - tb:>+9.4f}{abs(s[0] - s[1]):>15.4f}")
```

```
  T   taban  kosum 1  kosum 2   fark 1   fark 2  kosum araligi
  2  0.7200   0.9500   1.0000  +0.2300  +0.2800         0.0500
  4  0.7200   0.9550   0.9550  +0.2350  +0.2350         0.0000
  6  0.6850   0.9350   0.9550  +0.2500  +0.2700         0.0200
  8  0.7450   0.9550   0.9150  +0.2100  +0.1700         0.0400
 10  0.7000   0.8850   0.8850  +0.1850  +0.1850         0.0000
 12  0.7100   0.7350   0.7150  +0.0250  +0.0050         0.0200
```

Eğitim, ölçümün söylediğini doğruluyor ama tam olarak aynı yerde değil. Uzunluk 2'den 10'a kadar
ağ taban çizgisini 0,1700 ile 0,2700 arasında geçiyor. Uzunluk 12'de fark **0,0250** ve
**0,0050**'ye düşüyor: ağ artık taban çizgisiyle aynı şeyi söylüyor, yani baştaki işareti hiç
kullanmıyor ve yalnız son dönemin okumasına bakan bir kurala dönüşüyor.

Eğitimsiz ölçüm işaretin uzunluk 10'da zaten geri okunamadığını söylemişti; eğitilen ağ ise
uzunluk 10'da hâlâ 0,1850 fark üretiyor. Çelişki değildir: eğitim, ağırlıkları başlangıç
değerlerinden uzaklaştırır ve yinelemeli dizeyi izin verdiği kadar bilgi taşıyacak biçimde
ayarlar. Kazanılan iki adımdır. On ikide o iki adım da yetmez, çünkü sorun ağırlıkların
ayarlanmasıyla çözülecek türden değildir: taşıma **çarpımla** yapılır ve çarpanı biraz büyütmek
uzun dizide patlamaya, biraz küçültmek sönmeye götürür.

**Koşum aralığı** sütunu tabloya kendi uyarısını yazıyor. Uzunluk 8'de iki koşum 0,0400 ayrılıyor;
bu, uzunluk 8 ile uzunluk 10 arasındaki farkın (0,0250) üstündedir. Uzunluğun kattığı fark ile
başlangıç değerlerinin kattığı fark aynı büyüklük sırasındadır ve tek koşumla ölçülen bir "kaç
adıma kadar çalışıyor" yanıtı bu yüzden güvenilir değildir.

## Özet

- Okuma dizisi kurgudur: on iki dönemlik okuma, işaret olarak ilk dönemin sıfır okuması, etiket
  işaret ile son dönemin tarife basamağını aşmasının birlikte sağlanması.
- Yinelemeli ağ her adımda aynı ağırlıkları kullanır; parametre sayısı 61'dir ve dizi uzunluğundan
  bağımsızdır.
- İlk adımdaki işaretin son gizli durumda bıraktığı fark uzunluk 2'de 0,92844, uzunluk 12'de
  0,00913'tür; adım başına çarpan 0,609 ile 0,668 arasında sabittir.
- İşaretin son durumdan geri okunma doğruluğu 1,0000'den uzunluk 10'da 0,4600'e, yani rastlantı
  düzeyine iner; ikinci koşumda unutma daha da hızlıdır (uzunluk 12'de fark 0,00067).
- Eğitilen ağ taban çizgisini uzunluk 10'a kadar 0,1700–0,2700 geçer, uzunluk 12'de yalnız 0,0250
  ve 0,0050 geçer.
- Uzunluk 8'deki koşum aralığı 0,0400, uzunluk 8 ile 10 arasındaki farktan büyüktür; "kaç adıma
  kadar" sorusu tek koşumla yanıtlanamaz.

## Sonraki Adım

Gizli durum bilgiyi tutmayı **seçmiyor**; her adımda aynı dizeyle çarpılıyor ve çarpanın
büyüklüğü neyin kalacağını belirliyor. Aynı çarpan hem yeni okumayı hem de baştaki işareti eşit
biçimde etkiliyor, oysa bu iki bilginin ömrü aynı olmamalı: okuma bir adım sonra gereksizdir,
işaret dizinin sonuna kadar gereklidir. Sonraki ders duruma iki karar ekler — neyin **silineceği**
ve neyin **yazılacağı** — ve bu kararları girdiye bakarak veren birimler kurar. Ölçü aynı kalır ve
doğrudan karşılaştırılır: yalın yinelemeli ağ ile kapı birimli ağ aynı görevde, aynı uzunluklarda,
her biri iki koşumla yan yana konur ve bağımlılığın kaç adım geriye taşınabildiği sayılır.
