İçeriğe geç
academia.sh

Ders 14 / 22

Akıl Yürüten Modeller

Yanıt yazmadan önce görünmeyen ara adımlar üreten model sınıfının ölçüsü: aynı 120 kurgu destek talebinde tek alanlı görevde iki sınıfın isabet farkı −0,0333 ve +0,1167 kalıyor, iki koşum farkı 0,1167 olduğu için ölçülmemiş sayılıyor ve belirteç 1,75 kata çıkıyor. İki alanlı görevde fark +0,1000 ve +0,1667 ile bandın üzerine çıkıyor; tek geçişli sınıf kendi yazdığı etiketle kod alanını yanıtların 0,2333 payında çelişiyor. Doğru yanıt başına bedel 52,0'den 95,1'e ve 83,9'dan 110,1 belirtece yükseliyor.

İçindekiler

Önceki derste modelin attığı her ek adım görünürdü: düşünce alanı yanıtın içindeydi, belirteci sayıldı, kesildiğinde ne olduğu okundu ve düşünceyi kısaltma kararı ancak bu yüzden verilebildi. Bu derste ölçülen sınıfın ayırt edici özelliği tam da bunun yokluğudur. Sınıf, yanıtı yazmadan önce ara adımlar üretir; bu adımların metni çağırana hiç dönmez, uzunluğu istemle kısıtlanamaz ve durdurma koşulu onlara değmez — ama çıkış belirteci olarak ödenir. Ölçülecek şey budur: görünmeyen belirtecin bedeli.

Bu bir ürün karşılaştırması değildir. Hiçbir model, sürüm ya da sağlayıcı anılmaz; iki sınıf yalnız yapısal farkla tanımlanır. Tek geçişli sınıf istemi okur ve yanıtı yazar; akıl yürüten sınıf araya kendi görmediğimiz adımları koyar. Öz tutarlılıkta olduğu gibi çağrı sayısı artmaz — iki sınıf da kayıt başına bir çağrı yapar, ve orada ödenen şey görünen örnekler değil, görünmeyen belirteçlerdir.

  • AY49. Kod gerçek bir model uç noktası çağırmaz; standart kitaplıkla yazılmış bir dil modeli benzeticisini çağırır. Destek talepleri ve belge kodları kurgudur.
  • AY50. Tohum 20260218, ikinci koşum 20260219. Aynı istem aynı tohumda aynı yanıtı verir.
  • AY51. Akıl yürüten sınıf alan başına bir ara adım üretir. Tek alanlı görevde ikinci adım bir denetim geçişidir: aynı aday kümesi ikinci kez puanlanır ve yanıt son adımın sonucundan yazılır.
  • AY52. Ara adımların belirteci çıkış belirtecine eklenir ama yanıt metnine girmez. Durdurma koşulu yalnız görünen yanıtı keser; görünmeyen adımlar kısıtlanamaz.
  • AY53. Tek geçişli sınıf iki alanı iki ayrı çekilişle doldurur: ikinci alan birinci alanın sonucuna bağlanmaz. Akıl yürüten sınıfta ikinci ara adım birinci adımın sonucundan eşleştirme yapar.
  • AY54. İki görev de aynı 120 kurgu talebi kullanır. A görevi tek alan ister (etiket), B görevi iki alan ister (etiket ve belge kodu).
  • AY55. Belge kodları kurgu belge dağarcığından gelir ve her konunun tek bir kodu vardır; doğru yanıt için iki alanın da doğru olması gerekir.
  • AY56. Yanıt biçimi iki sınıfta da aynıdır ve dayatılmıştır. Ölçülen tek fark sınıfın kendisidir.

İki Sınıfın Yapısal Farkı

İlk blok benzeticiyi kurar ve iki sınıfı iki işlevle ayırır. cagir istemi okur ve yanıtı yazar. cagir_akil araya ara adımlar koyar, adımların belirtecini gizli alanında biriktirir ve yanıt metnine yalnız sonucu yazar.

# BENZETICI. Gercek bir model uc noktasi cagrilmaz; standart kitaplikla yazilmis bir dil
# modeli benzeticisidir. Destek talepleri ve belge kodlari KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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 belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KOD = {"fatura": "FT", "ariza": "AR", "sayac": "SY", "tarife": "TR", "kesinti": "KS"}
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k, "kod": KOD[k]})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}
ARA = ["ara adim : metinde {k} izleri var , konu buna gore belirlendi",
       "ara adim : {k} konusunun belge kodu {d} olarak eslendi"]
SAYAC = [0]


def puanla(bel, kume):
    aday = [k for k in kume if k[:5] in bel]
    if len(aday) < 3:
        aday = list(kume)
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    return p


def sec(p, r, sicaklik):
    if sicaklik <= 0.0:
        return max(sorted(p), key=lambda a: p[a])
    e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    return sorted(p)[ayrik(r(), [v / sum(e) for v in e])]


def sinir(bel, r):
    if len(bel) > PENCERE:
        return "baglam_asimi"
    if SAYAC[0] % 37 == 0:
        return "hiz_siniri"
    if len(bel) > 90 and r() < 0.04:
        return "zaman_asimi"
    return "tamam"


def don(durum, bel, y, gizli=0):
    if durum != "tamam":
        return {"durum": durum, "giris": len(bel), "cikis": 0, "gizli": 0, "yanit": ""}
    cb = belirtecle(y)
    if len(cb) > EN_UZUN:                    # durdurma kosulu yalniz goruneni keser
        cb, y = cb[:EN_UZUN], " ".join(cb[:EN_UZUN])
    return {"durum": durum, "giris": len(bel), "cikis": len(cb) + gizli,
            "gizli": gizli, "yanit": y}


def govde(istem):                       # istemin yonergeden sonraki kismi
    return istem.split("Talep: ")[-1]


def cagir(istem, tohum=TOHUM, sicaklik=0.6):
    """STANDART SINIF: tek gecis, ara adim yok."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    r = uretec(tohum ^ izno(istem))
    d = sinir(bel, r)
    if d != "tamam":
        return don(d, bel, "")
    k = sec(puanla(bel, KAVRAM), r, sicaklik)
    if "kod" not in bel:
        return don(d, bel, f"etiket : {k}")
    k2 = sec(puanla(bel, KAVRAM), r, sicaklik)      # ikinci alan icin ayri cekilis
    return don(d, bel, f"etiket : {k} | kod : {KOD.get(k2, 'XX')}")


def cagir_akil(istem, tohum=TOHUM, sicaklik=0.6):
    """AKIL YURUTEN SINIF: yaniti yazmadan once gorunmeyen ara adimlar uretir.
    Ara adimlarin metni cagirana donmez ama cikis belirteci olarak sayilir."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    r = uretec(tohum ^ izno(istem))
    d = sinir(bel, r)
    if d != "tamam":
        return don(d, bel, "")
    g = belirtecle(govde(istem))
    k = sec(puanla(g, KONU), r, sicaklik)                       # 1. ara adim
    gizli = len(belirtecle(ARA[0].format(k=k)))
    if "kod" not in bel:
        k = sec(puanla(g, KONU), r, sicaklik)                   # 2. ara adim: denetim
        gizli += len(belirtecle(ARA[0].format(k=k)))
        return don(d, bel, f"etiket : {k}", gizli)
    kod = KOD[k]                                                # 2. ara adim: eslestirme
    gizli += len(belirtecle(ARA[1].format(k=k, d=kod)))
    return don(d, bel, f"etiket : {k} | kod : {kod}", gizli)


def oku(y):
    e = kd = None
    p = y.split()
    for i, s in enumerate(p):
        if s == "etiket" and i + 2 < len(p) and p[i + 2] in KONU:
            e = p[i + 2]
        if s == "kod" and i + 2 < len(p):
            kd = p[i + 2]
    return e, kd


A = "Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , kesinti . Talep: "
B = ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , kesinti . "
     "Ayrica etiketin belge kodunu kod alanina yaz . Talep: ")

t = TALEP[9]
print(f"KURGU talep {t['no']}: {t['metin']}  (konu {t['konu']}, kod {t['kod']})")
for ad, f in (("standart sinif", cagir), ("akil yuruten sinif", cagir_akil)):
    for gad, o in (("A tek alan", A), ("B iki alan", B)):
        s = f(o + t["metin"])
        print(f"{ad:<19}{gad:<12} cikis {s['cikis']:>3} bel "
              f"(gorunmeyen {s['gizli']:>2}) | {s['yanit']}")
KURGU talep 4010: hangi tarife basamagindayim ogrenmek istiyorum kayit numaram elimde yok  (konu tarife, kod TR)
standart sinif     A tek alan   cikis   4 bel (gorunmeyen  0) | etiket : sayac
standart sinif     B iki alan   cikis   9 bel (gorunmeyen  0) | etiket : tarife | kod : TR
akil yuruten sinif A tek alan   cikis  36 bel (gorunmeyen 31) | etiket : tarife
akil yuruten sinif B iki alan   cikis  39 bel (gorunmeyen 30) | etiket : tarife | kod : TR

Tek kayıtta dört satır ve tek bir gözlem: yanıtlar aynı biçimde, çıkışlar aynı büyüklükte değil. Akıl yürüten sınıfın görünen yanıtı dört belirteç, çıkış belirteci otuz altı. Aradaki otuz bir belirteç okunamıyor, kısaltılamıyor, denetlenemiyor. Bir önceki dersin kaldıracı burada elde yok, çünkü kısaltılacak metin yanıtın içinde değil.

Aynı Görevde İki Sınıf

Ölçüm iki görevde yapılır. A görevi tek alan ister ve istem beş etiketi zaten sayar. B görevi ikinci bir alan daha ister: etiketin belge kodu. İkisi de aynı 120 kurgu talebi kullanır ve her kayıt için tek çağrı yapılır.

def olc(sinif, onek, iki_alan, tohum=TOHUM):
    SAYAC[0] = 0
    g = c = gz = d = uyum = 0
    for x in TALEP:
        s = sinif(onek + x["metin"], tohum=tohum)
        g, c, gz = g + s["giris"], c + s["cikis"], gz + s["gizli"]
        e, kd = oku(s["yanit"])
        if iki_alan:
            d += e == x["konu"] and kd == x["kod"]
            uyum += kd is not None and e is not None and kd == KOD[e]
        else:
            d += e == x["konu"]
    n = len(TALEP)
    return {"isabet": d / n, "uyum": uyum / n if iki_alan else None, "giris": g,
            "gorunen": c - gz, "gizli": gz, "toplam": g + c, "dogru": d}


IS = [("A standart", cagir, A, False), ("A akil", cagir_akil, A, False),
      ("B standart", cagir, B, True), ("B akil", cagir_akil, B, True)]
S1 = [olc(f, o, i) for _, f, o, i in IS]
S2 = [olc(f, o, i, tohum=TOHUM + 1) for _, f, o, i in IS]
print(f"{'olcu (tohum 20260218)':<24}" + "".join(f"{a[0]:>12}" for a in IS))
for ad, k, b in (("isabet", "isabet", "{:.4f}"), ("iki alan uyumu", "uyum", "{:.4f}"),
                 ("giris belirteci", "giris", "{:d}"),
                 ("gorunen cikis belirteci", "gorunen", "{:d}"),
                 ("gorunmeyen cikis bel.", "gizli", "{:d}"),
                 ("toplam belirtec", "toplam", "{:d}")):
    print(f"{ad:<24}" + "".join(("-" if x[k] is None else b.format(x[k])).rjust(12)
                                for x in S1))
print(f"{'dogru yanit basina':<24}" + "".join(
    f"{x['toplam'] / x['dogru']:.1f}".rjust(12) for x in S1))
print(f"\n{'ikinci kosum isabeti':<24}" + "".join(f"{x['isabet']:.4f}".rjust(12)
                                                  for x in S2))
for ad, i in (("A gorevi", 0), ("B gorevi", 2)):
    f1 = S1[i + 1]["isabet"] - S1[i]["isabet"]
    f2 = S2[i + 1]["isabet"] - S2[i]["isabet"]
    kf = max(abs(S1[i]["isabet"] - S2[i]["isabet"]),
             abs(S1[i + 1]["isabet"] - S2[i + 1]["isabet"]))
    o = "olculdu" if min(abs(f1), abs(f2)) > kf else "olculmedi"
    kat = (S1[i + 1]["toplam"] / S1[i]["toplam"])
    print(f"{ad}: sinif farki {f1:+.4f} / {f2:+.4f}, iki kosum farki {kf:.4f} -> {o}"
          f"   belirtec {kat:.2f} kat")
olcu (tohum 20260218)     A standart      A akil  B standart      B akil
isabet                        0.7833      0.7500      0.6750      0.7750
iki alan uyumu                     -           -      0.7667      0.9750
giris belirteci                 4340        4340        5780        5780
gorunen cikis belirteci          550         547        1017        1017
gorunmeyen cikis bel.              0        3671           0        3438
toplam belirtec                 4890        8558        6797       10235
dogru yanit basina              52.0        95.1        83.9       110.1

ikinci kosum isabeti          0.6667      0.7833      0.6333      0.8000
A gorevi: sinif farki -0.0333 / +0.1167, iki kosum farki 0.1167 -> olculmedi   belirtec 1.75 kat
B gorevi: sinif farki +0.1000 / +0.1667, iki kosum farki 0.0417 -> olculdu   belirtec 1.51 kat

A görevinde fark ölçülemedi. Sınıf farkı birinci koşumda −0,0333, ikincisinde +0,1167; işareti bile sabit değil ve büyüklüğü iki koşum farkının (0,1167) üzerine çıkmıyor. Nedeni tablodan okunur: istem beş etiketi zaten sayıyor, yani aday kümesini daraltma işi istem metninde yapılmış. Ara adım aynı daraltmayı bir kez daha yapıyor ve yeni bilgi eklemiyor. Buna karşılık görünmeyen çıkış belirteci 0’dan 3671’e çıkıyor ve toplam 1,75 kata geliyor. Bu, kursun ikinci iddiasının en yalın hâlidir: teknik belirteci katladı, sayıyı oynatmadı.

B görevinde durum tersine döner. Sınıf farkı iki koşumda da olumlu ve büyük — +0,1000 ve +0,1667 — iki koşum farkı ise 0,0417. Nedeni iki alan uyumu satırında duruyor: tek geçişli sınıfın yanıtlarının yalnız 0,7667 payında kod alanı kendi yazdığı etiketle uyumlu. Yani model çoğu zaman etiketi doğru bulup kodu başka bir konudan yazıyor; iki alan birbirine bağlanmıyor. Akıl yürüten sınıfta bu oran 0,9750 — kalan pay, hız sınırına takılıp hiç yanıt üretmeyen üç çağrıdır. İkinci alanı birinci alanın sonucundan üretmek, kaybın tamamını kapatıyor.

Görünmeyen Belirtecin Bedeli

Son satır bu dersin faturasıdır. Doğru yanıt başına 52,0 belirteçten 95,1’e (A) ve 83,9’dan 110,1’e (B). B görevinde akıl yürüten sınıf isabeti gerçekten yükseltti ve yine de doğru yanıt başına daha pahalı kaldı, çünkü isabet 1,15 kat artarken toplam belirteç 1,51 kat arttı. Çağrı sayısı iki sınıfta da 120’dir; artışın tamamı çıkış belirtecindedir ve o belirtecin büyük bölümü hiç okunmadı.

Bedelin biçimi de önemlidir. Görünen çıkış belirteci iki sınıfta neredeyse aynı — A görevinde 550 ve 547. Fark tamamen görünmeyen kısımdadır: 3671 ve 3438 belirteç. Bu, istem tasarımcısının elini kısıtlar: uzunluk kısıtı yazılabilir ama görünmeyen adıma işlemez, biçim dayatılabilir ama görünmeyen adım biçimsizdir, kesilen yanıt sayılabilir ama görünmeyen adım kesilmez. Elde kalan tek kaldıraç görevin kendisidir: ara adımın daraltacağı bir karar var mı, yoksa istem o daraltmayı zaten yapmış mı. Görünmeyen ara adım, ancak istemin yapamadığı bir işi yaptığında kazandırır; yaptığı işi istem zaten yapmışsa geriye yalnız belirteç kalır.

Özet

  • Akıl yürüten model sınıfı bir ürünle değil yapısal farkla tanımlanır: yanıttan önce ara adımlar üretir, adımlar çağırana dönmez ve çıkış belirteci olarak ödenir.
  • Çağrı sayısı artmaz. Öz tutarlılıkta bedel çağrıdaydı ve örnekler görülebiliyordu; burada bedel tek çağrının içindedir ve görülemez.
  • Tek alanlı görevde iki sınıfın farkı −0,0333 ve +0,1167, iki koşum farkı 0,1167: fark ölçülmemiş sayılır, ama belirteç 1,75 kat arttı.
  • İki alanlı görevde fark +0,1000 ve +0,1667 ile bandın (0,0417) üzerinde. Kaynağı iki alan uyumudur: tek geçişli sınıf kod alanını kendi etiketiyle yalnız 0,7667 payında tutturuyor, akıl yürüten sınıf 0,9750.
  • Doğru yanıt başına bedel 52,0 → 95,1 ve 83,9 → 110,1 belirteç. Kazandığı görevde bile birim maliyet arttı.

Sonraki Adım

Altı derste tek bir istem elden geçirildi: adımları zincirlendi, çoğaltıldı, dallandırıldı, soyutlandı, içine bir eylem alanı kondu ve sonunda adımların görünmediği bir sınıfa devredildi. Hepsinde ortak bir varsayım vardı — soruya bakan tek bir metin var ve iyi sonuç o metnin daha da uzatılmasından çıkacak. Aynı soruya birbirinden bağımsız birkaç ayrı istemin bakması, her birinin kendi yanıtını üretmesi ve bunların birleştirilmesi hiç denenmedi. Sonraki ders bunu ölçer ve asıl soruyu sorar: farklı istemler aynı örneklerde mi yanılıyor. Hatalar örtüşüyorsa birleştirmenin kazancı yoktur ve bu, birleştirmeden önce sayılabilir.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat