---
title: 'Hesap Çizgesi ve Otomatik Türev'
source: 'https://academia.sh/tr/kurslar/derin-ogrenme/hesap-cizgesi-ve-otomatik-turev'
course: 'Derin Öğrenme'
language: tr
updated: '2026-08-17T18:10:10+00:00'
license: 'CC BY-SA 4.0'
---

# Hesap Çizgesi ve Otomatik Türev

Eğim hesabını mimariden ayıran soyutlamanın ders içinde yazılması ve elle yazılan geri yayılımla karşılaştırılması: otuz iki satırlık dört işlemli bir düzenek, seksen bir parametrenin eğimini elle yazılan on sekiz satırlık geri yayılımdan 2,78e-17 farkla veriyor ve otuz örnekli bir toplu için 6.622 düğüm kuruyor. Kursun üç sayısı burada kurulur: taban çizgisi 0,7579, ağın sayısı 0,8095 ve yalnız başlangıç değerleri değişen ikinci koşum 0,7937. On ilklendirmenin aralığı 0,7857 ile 0,8095 arasındadır ve M27/K03'ün karar ağacı (0,7857) ile doğrusal modelinin (0,8016) sayıları bu aralığın içine düşer.

Önceki on derste mimari seçildi: evrişim, havuzlama, atlamalı bağlantı, yinelemeli durum, kapı
birimi, dikkat, gömme, aktarım, otokodlayıcı. Her birinde ağın yapısı değişti ve eğim hesabı
**yeniden türetilip yeniden yazıldı**; hepsi elle yazılmış küçük bir eğitim döngüsünde koştu.
Gerçek eğitimin **düzeneği** hiç ele alınmadı.

Bu konu o düzeneği ele alır ve ilk parçası eğim hesabını mimariden ayıran soyutlamadır. Katalogda
bu ders derin öğrenme kütüphanelerini anar; burada anlatılan **kütüphaneler değil, kütüphanelerin
sattığı soyutlamadır** — hesap çizgesi (computation graph) ve otomatik türev (automatic
differentiation) — ve soyutlama ders içinde yazılır. Ölçü iki sayıdır: elle yazılan geri yayılım
ile otomatik türevin verdiği eğim arasındaki **fark**, ve iki yolun **kaç satır** tuttuğu.

- **EP1.** Küme M27/K01–K04'ün **kurgu** abone tablosudur, tohum 20260218, 1.260 abone; etiket
  kaçak ya da arıza şüphesidir ve kurgudur. Taban çizgisi **en sık sınıfı söylemektir**: sınamada
  0,7579, M27/K01–K03'ten devralınır.
- **EP2.** Eğitim kümesi bu konuda **756 yerine 300 satırdır**; bir ölçek kararıdır ve konunun
  bütün blokları birkaç saniyede koşar. Sınama kümesi 252 satırdır ve bir abone 0,0040 eder.
- **EP3.** Ağ bu konu boyunca sabittir: sekiz öznitelik, sekiz birimli tek gizli katman
  (doğrultulmuş doğrusal birim), tek çıkış; kayıp **çapraz düzensizliktir**. Katmanın sabit terimi
  **yanma** diye anılır ve istatistikteki **yanlılık**tan ayrıdır. Ölçekleme yalnız **eğitim
  kümesinden** öğrenilir (M27/K02, boru hattı).
- **EP4.** Kursun üçüncü sayısı **ikinci koşumdur**: aynı ağ, aynı veri, aynı örnek sırası, yalnız
  **başlangıç değerleri** değişir. Ölçü ham süre değildir: çizgenin bedeli **düğüm**, kodun bedeli
  **satır** sayısıyla ölçülür.
- **EP5.** Kayıp düğümü **kaynaşıktır**: sigmoit ile çapraz düzensizlik tek düğümde tutulur, çünkü
  ayrı tutulduğunda büyük çıkışlarda taşma olur. Yerel türevi iki yolda da aynıdır. Düzenek
  **modeldir** ve hiçbir çerçeve, kitaplık ya da satıcı adı anılmaz.

## Küme, Ölçek ve Taban Çizgisi

```python
# ORTAK — KURGUDUR. M27/K01-K04'un abone tablosu ayni tohumla (20260218) uretilir;
# etiket kacak/ariza suphesidir. Egitim kumesi bu konuda 756'dan 300 satira
# KUCULTULMUSTUR: konunun butun bloklari birkac saniyede kosar.
import math

TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF
BOLGE = [("kuzey", 0.28, 21, 0.00), ("guney", 0.22, 17, -0.10),
         ("dogu", 0.18, 26, 0.30), ("bati", 0.14, 14, -0.05),
         ("merkez", 0.18, 23, 0.05)]
ALAN = ["b_guney", "b_dogu", "b_bati", "b_merkez",
        "hane", "memnuniyet", "donem", "ortalama"]


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 ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


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


VERI = []
for i in range(HAM):
    r = uretec(TOHUM + i)
    b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])]
    hane = 1 + ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05])
    memnun = 1 + ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17])
    if r() < 0.046:
        continue
    no = 10001 + i
    r, v = uretec(TOHUM + 7000 + no), []
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        v.append(0.0 if r() < 0.038 else math.floor(
            b[2] * math.exp((r() + r() + r() - 1.5) * 0.62)
            * (1 - d * 0.05) * 100 + 0.5) / 100)
        r()
    if not v:
        continue
    ort, oyn, r = sum(v) / len(v), max(v) - min(v), uretec(TOHUM + 51000 + no)
    z = (0.052 * (ort - 20) + 0.85 * (min(v) == 0.0) + 0.026 * oyn
         + 0.24 * (hane >= 5) - 0.20 * (memnun >= 4) + b[3]
         + 0.9 * (no - 10001) / 1399 + (r() + r() + r() - 1.5) * 1.30)
    x = {"hane": hane, "memnuniyet": memnun, "donem": len(v),
         "ortalama": round(ort, 2), "supheli": int(z > 1.35)}
    for q in BOLGE[1:]:
        x["b_" + q[0]] = int(b[0] == q[0])
    VERI.append(x)

K = karistir(VERI, TOHUM + 90000)
EGT, SIN = K[:300], K[1008:]


def tablo(satirlar, ist=None):
    X = [[float(s[a]) for a in ALAN] for s in satirlar]
    if ist is None:                       # olcek yalniz egitim kumesinden ogrenilir
        ist = []
        for j in range(4, 8):
            m = sum(v[j] for v in X) / len(X)
            ist.append((j, m, math.sqrt(sum((v[j] - m) ** 2 for v in X) / len(X))))
    for v in X:
        for j, m, sd in ist:
            v[j] = (v[j] - m) / sd
    return X, [s["supheli"] for s in satirlar], ist


XE, yE, IST = tablo(EGT)
XS, yS, _ = tablo(SIN, IST)
TABAN = sum(v == 0 for v in yS) / len(yS)
print(f"kurgu abone {len(VERI)}; egitim {len(XE)} (756'dan kucultuldu), sinama "
      f"{len(XS)}, oznitelik {len(ALAN)}, egitimde supheli pay "
      f"{sum(yE) / len(yE):.4f}")
print(f"taban cizgisi (en sik sinifi soylemek, sinamada) {TABAN:.4f}")
```

```
kurgu abone 1260; egitim 300 (756'dan kucultuldu), sinama 252, oznitelik 8, egitimde supheli pay 0.2200
taban cizgisi (en sik sinifi soylemek, sinamada) 0.7579
```

## Çizge Bir Veri Yapısıdır

Elle türetmenin sıkıntısı hesabın zorluğu değil, **yapıya bağlı olmasıdır**: katman eklendiğinde
türev yeniden yazılır. Hesap çizgesi bu bağı koparır. Her ara değer bir **düğüm** olarak tutulur ve
düğüm kendi değerini, **atalarını** ve **atalarına göre yerel türevini** saklar; geri geçiş çizgeyi
tersten gezip her düğümün eğimini atalarına dağıtır. Zincir kuralı bu dağıtımdır ve yalnız bir kez
yazılır.

```python
# Hesap cizgesi duzenegi — MODELDIR. Dort islem: toplama, carpma, dogrultma ve
# kaynasik kayip. Her dugum degerini, egimini, atalarini ve ATALARINA GORE YEREL
# TUREVINI tutar; geri adim yalnizca bunlari kullanir.
import inspect


class Deger:
    __slots__ = ("v", "e", "ata", "yerel")

    def __init__(self, v, ata=(), yerel=()):
        self.v, self.e, self.ata, self.yerel = float(v), 0.0, ata, yerel

    def __add__(self, o):
        o = o if isinstance(o, Deger) else Deger(o)
        return Deger(self.v + o.v, (self, o), (1.0, 1.0))

    def __mul__(self, o):
        o = o if isinstance(o, Deger) else Deger(o)
        return Deger(self.v * o.v, (self, o), (o.v, self.v))

    def dogrult(self):
        return Deger(self.v if self.v > 0 else 0.0, (self,),
                     (1.0 if self.v > 0 else 0.0,))

    def kayip(self, y):                  # capraz duzensizlik, dogrudan cikisa
        p = 1.0 / (1.0 + math.exp(-self.v)) if self.v > -30 else 0.0
        k = max(0.0, self.v) + math.log(1.0 + math.exp(-abs(self.v))) - self.v * y
        return Deger(k, (self,), (p - y,))


def geriye(kok):
    sira, gorulen = [], set()

    def gez(d):
        if id(d) in gorulen:
            return
        gorulen.add(id(d))
        for a in d.ata:
            gez(a)
        sira.append(d)

    gez(kok)
    kok.e = 1.0
    for d in reversed(sira):
        for a, y in zip(d.ata, d.yerel):
            a.e += d.e * y
    return len(sira)


SATIR = sum(len([s for s in inspect.getsource(o).splitlines() if s.strip()])
            for o in (Deger, geriye))
print(f"duzenek {SATIR} satir, 4 islem;  L = 5 * dogrult(a*b + c)")
for bd in (3.0, -3.0):
    a, b, c = Deger(2.0), Deger(bd), Deger(4.0)
    L = (a * b + c).dogrult() * Deger(5.0)
    n = geriye(L)
    print(f"  a=2 b={bd:+.0f} c=4 -> L={L.v:5.1f}, {n} dugum;  dL/da {a.e:>6.1f}"
          f"   dL/db {b.e:>6.1f}   dL/dc {c.e:>6.1f}")
```

```
duzenek 32 satir, 4 islem;  L = 5 * dogrult(a*b + c)
  a=2 b=+3 c=4 -> L= 50.0, 8 dugum;  dL/da   15.0   dL/db   10.0   dL/dc    5.0
  a=2 b=-3 c=4 -> L=  0.0, 8 dugum;  dL/da    0.0   dL/db    0.0   dL/dc    0.0
```

Otuz iki satır ve dört işlem. Türevler elle denetlenebilir: $L = 5\,(ab+c)$ pozitif bölgede
$\partial L/\partial a = 5b = 15$, $\partial L/\partial b = 5a = 10$ ve $\partial L/\partial c = 5$
verir; çıktı bunu söylüyor. İkinci çağrıda yalnız $b$ eksi üç oldu: toplam eksiye düştü, doğrultma
kapısı kapandı, **üç türev de sıfır** oldu. Çizge aynı, kod aynı; değişen yalnız verinin çizgede
açtığı yol.

## Aynı Eğim, İki Yol

```python
# Ayni agin egimi iki yoldan: cizgeyi gezerek ve zincir kuralini ELLE yazarak.
# Parametreler tek duz liste: p[j*G+i] agirlik, p[H*G+j] yanma, p[H*G+H+j] ve
# p[-1] cikis katmani.
G, H = len(ALAN), 8


def ilklendir(tohum):                        # kazanc olcekli ilklendirme
    r = uretec(tohum)
    return [(r() * 2 - 1) * math.sqrt(2.0 / G) for _ in range(H * G)] + [0.0] * H \
        + [(r() * 2 - 1) * math.sqrt(2.0 / H) for _ in range(H)] + [0.0]


def cizgeyle(p, X, y, par):
    d, top = [Deger(v) for v in p], None
    for k in par:
        x, o = X[k], d[-1]
        for j in range(H):
            z = d[H * G + j]
            for i in range(G):
                z = z + d[j * G + i] * x[i]
            o = o + d[H * G + H + j] * z.dogrult()
        L = o.kayip(y[k])
        top = L if top is None else top + L
    kok = top * (1.0 / len(par))
    return kok, geriye(kok), [u.e for u in d]


def elle(p, X, y, par):
    g, kayip = [0.0] * len(p), 0.0
    for k in par:
        x, hh = X[k], [0.0] * H
        for j in range(H):
            s = p[H * G + j] + sum(p[j * G + i] * x[i] for i in range(G))
            hh[j] = s if s > 0 else 0.0
        o = p[-1] + sum(p[H * G + H + j] * hh[j] for j in range(H))
        kayip += max(0.0, o) + math.log(1.0 + math.exp(-abs(o))) - o * y[k]
        d = 1.0 / (1.0 + math.exp(-o)) - y[k]    # kayip dugumunun yerel turevi
        g[-1] += d
        for j in range(H):
            g[H * G + H + j] += d * hh[j]
            if hh[j] > 0:                        # dogrultma kapisi kapaliysa gecmez
                g[H * G + j] += d * p[H * G + H + j]
                for i in range(G):
                    g[j * G + i] += d * p[H * G + H + j] * x[i]
    return kayip / len(par), [v / len(par) for v in g]


P0, TOPLU = ilklendir(TOHUM + 1), list(range(30))
kok, DUGUM, oto = cizgeyle(P0, XE, yE, TOPLU)
kayip, el = elle(P0, XE, yE, TOPLU)
print(f"parametre {len(P0)}; 30 ornekli toplu icin cizge {DUGUM} dugum, "
      f"ornek basina {DUGUM / 30:.1f}")
print(f"kayip  cizge {kok.v:.10f}   elle {kayip:.10f}")
print(f"egimlerin en buyuk mutlak farki {max(abs(u - v) for u, v in zip(oto, el)):.2e}"
      f"  (en buyuk egim {max(abs(v) for v in oto):.4f})")
print(f"elle yazilan yol {len(inspect.getsource(elle).splitlines())} satir "
      f"ve yalniz bu aga ait; duzenek {SATIR} satir ve agi hic bilmiyor")
```

```
parametre 81; 30 ornekli toplu icin cizge 6622 dugum, ornek basina 220.7
kayip  cizge 0.7366651135   elle 0.7366651135
egimlerin en buyuk mutlak farki 2.78e-17  (en buyuk egim 0.3097)
elle yazilan yol 18 satir ve yalniz bu aga ait; duzenek 32 satir ve agi hic bilmiyor
```

Dersin birinci sayısı burada. Seksen bir parametrenin eğimi iki yoldan hesaplandı ve en büyük
mutlak fark **2,78e-17** çıktı: kayan noktalı toplama sırasının ürettiği fark. En büyük eğim
0,3097 olduğuna göre iki yol **on beş basamak boyunca** aynı sayıyı veriyor; eşitlik `==` ile
değil, farkın en büyük eğime oranıyla denetlenir.

İkinci sayı tersini söyler. Elle yazılan yol on sekiz satır tuttu ve bu satırlar **yalnız bu ağa**
aittir; katman eklenirse yeniden yazılır. Otuz iki satırlık düzenek ağın yapısını hiç bilmez,
ileri geçişi yazan kim olursa olsun eğimi aynı `geriye` çağrısı verir. Bedeli üçüncü sayıdadır:
otuz örneklik toplu için çizge **6.622 düğüm** kurdu, örnek başına 220,7. Elle yazılan yol düğüm
tutmaz, ara değerleri yerinde toplar.

## Kursun Üç Sayısı

```python
# Egitim ELLE yazilan geri yayilimla koser; cizge dogrulama icin kuruldu. Iki
# kosum yalnizca BASLANGIC DEGERLERINDE ayrilir: ornek sirasi ikisinde de ayni.
ADIM, TUR, TOPLU_BOY, SIRA_TOHUMU = 0.30, 40, 30, TOHUM + 700


def egit(tohum):
    p = ilklendir(tohum)
    for t in range(TUR):
        dizin = karistir(range(len(XE)), SIRA_TOHUMU + t)
        for bas in range(0, len(dizin), TOPLU_BOY):
            _, g = elle(p, XE, yE, dizin[bas:bas + TOPLU_BOY])
            p = [a - ADIM * b for a, b in zip(p, g)]
    return p


def dogruluk(p, X, y):
    n = 0
    for k in range(len(X)):
        x = X[k]
        o = p[-1] + sum(p[H * G + H + j] * max(0.0, p[H * G + j]
                        + sum(p[j * G + i] * x[i] for i in range(G)))
                        for j in range(H))
        n += (o >= 0.0) == (y[k] == 1)
    return n / len(X)


S = [dogruluk(egit(TOHUM + t), XS, yS) for t in range(1, 11)]
print(f"ag {G}-{H}-1, {len(P0)} parametre, {TUR} tur, toplu boy {TOPLU_BOY}, "
      f"ogrenme adimi {ADIM}, {TUR * (len(XE) // TOPLU_BOY)} guncelleme")
print(f"  taban cizgisi   {TABAN:.4f}")
print(f"  agin sayisi     {S[0]:.4f}   (fark {S[0] - TABAN:+.4f})")
print(f"  ikinci kosum    {S[1]:.4f}   (fark {S[1] - TABAN:+.4f})")
print(f"on ilklendirmede aralik {min(S):.4f} - {max(S):.4f}, genislik "
      f"{max(S) - min(S):.4f} ({round((max(S) - min(S)) * len(XS))} abone)")
AGAC, DOGRUSAL = 198, 202       # M27/K03'un sayilari, ayni 252 satirlik sinamada
en_az, en_cok = round(min(S) * len(XS)), round(max(S) * len(XS))
print(f"karsilastirma cizgileri (756 satirlik egitim kumesiyle): karar agaci {AGAC / len(XS):.4f}, "
      f"dogrusal model {DOGRUSAL / len(XS):.4f}; agin araligi {en_az}-{en_cok} abone"
      f" -> {sum(en_az <= v <= en_cok for v in (AGAC, DOGRUSAL))}/2 iceride")
print(f"ayni egitim cizge uzerinden kossaydi "
      f"{TUR * (len(XE) // TOPLU_BOY) * DUGUM:,} dugum kurulurdu")
```

```
ag 8-8-1, 81 parametre, 40 tur, toplu boy 30, ogrenme adimi 0.3, 400 guncelleme
  taban cizgisi   0.7579
  agin sayisi     0.8095   (fark +0.0516)
  ikinci kosum    0.7937   (fark +0.0357)
on ilklendirmede aralik 0.7857 - 0.8095, genislik 0.0238 (6 abone)
karsilastirma cizgileri (756 satirlik egitim kumesiyle): karar agaci 0.7857, dogrusal model 0.8016; agin araligi 198-204 abone -> 2/2 iceride
ayni egitim cizge uzerinden kossaydi 2,648,800 dugum kurulurdu
```

Üç sayı yan yana: taban çizgisi 0,7579, ağın sayısı 0,8095, ikinci koşum 0,7937. Aradaki fark
0,0158, yani dört abone; iki koşum arasındaki bu fark, tabanın üstündeki kazancın (+0,0516) üçte
birine yakındır. On ilklendirmede aralık **0,7857 ile 0,8095** arasına yayılıyor, altı abone
genişliğinde. Kapasitede, veride, öğrenme adımında ve tur sayısında **hiçbir şey değişmeden** ağın
sayısı bu aralıkta herhangi bir yere düşebilir.

M27/K03'ün karar ağacı sınama kümesinde 198, doğrusal modeli 202 aboneyi doğru ayırdı; ağın on
koşumdaki aralığı 198–204 ve **ikisi de içeride**. Karşılaştırma birebir değildir, o sayılar 756
satırlık eğitim kümesinden geldi; ama yön nettir: ağın tek koşumda ürettiği sayıyla iki eski
aileyi geçtiğini söylemek, koşum değişkenliğini bulgu diye okumaktır. Kursun kuralı bu yüzden
vardır — **aynı kapasitenin iki koşumda iki ayrı sayı verdiği yazılmayan sonuç ölçülmemiş
sayılır.**

## Özet

- Hesap çizgesi bir veri yapısıdır: her düğüm değerini, atalarını ve yerel türevini tutar; geri
  geçiş çizgeyi tersten gezer ve zincir kuralı yalnız bir kez yazılır.
- Otuz iki satırlık dört işlemli düzenek, seksen bir parametrenin eğimini elle yazılan on sekiz
  satırlık geri yayılımdan **2,78e-17** farkla veriyor; en büyük eğim 0,3097.
- Otuz iki satır ağın yapısını bilmez, on sekiz satır yalnız bu ağa aittir; bedel otuz örneklik
  toplu için 6.622 düğüm, örnek başına 220,7.
- Kursun üç sayısı: taban çizgisi 0,7579, ağın sayısı 0,8095, ikinci koşum 0,7937; aradaki fark
  0,0158, tabanın üstündeki kazancın üçte birine yakın.
- On ilklendirmenin aralığı 0,7857–0,8095 ve M27/K03'ün karar ağacı (0,7857) ile doğrusal modelinin
  (0,8016) sayıları bu aralığın içine düşüyor; tek koşumla okunan üstünlük koşum değişkenliğinden
  ayrılamaz.

## Sonraki Adım

Eğim doğru hesaplandı, ama ağa hangi örneklerin hangi sırayla verildiği tek bir satırda geçti:
eğitim kümesi her turda karıştırıldı ve otuzarlık topluya bölündü. O satır bir karardır. Sonraki
ders veri yükleme hattını ele alır: toplu üretim sırasının sayıyı ne kadar oynattığı, veri
artırmanın ne kattığı ve artırmanın hangi durumda ayrılmış kümeye sızıntı ürettiği ölçülür.
