Ders 16 / 22
Otomatik İstem Eniyileme
İstem elle yazılmak yerine bir ölçütle aranıyor: dört parçadan mekanik olarak on aday üretiliyor, kurgu destek talepleri 40 kayıtlık doğrulama ve 80 kayıtlık sınama kümesine ayrılıyor. Arama bütçesi bir adaydan on adaya çıkarken doğrulamadaki en iyi puan 0,7750'den 0,9000'e yükseliyor, aynı adayın sınama puanı 0,6750'den 0,6500'e iniyor: doğrulama kazancı +0,1250, sınama kazancı -0,0250 ve seçilen adayın iyimserlik payı 0,2500. Arama 40 çağrıdan 400 çağrıya çıkıyor, sınamada gerçekten en iyi olan aday (0,8000) hiç seçilmiyor ve ikinci koşumda arama başka bir adayı seçiyor.
İçindekiler
Önceki derste üç istem elle yazıldı, üçü de aynı kümede ölçüldü ve en iyisi gözle seçildi. O seçimin dayanağı tek bir koşumdu ve ikinci koşumda sıralama tersine döndü. Bu işin elle yapılan kısmı aslında dardır: adayları üretmek bir birleştirme işi, puanlamak bir döngü, seçmek bir karşılaştırma. Üçü de yazılabilir. Yazıldığında ortaya otomatik istem eniyileme çıkar — istemin bir ölçütle aranması.
Aramanın kendisi bu dersin konusu değildir. Bir aday kümesi üzerinde en iyiyi seçmenin yordamı, ve ayar bütçesi büyüdükçe doğrulama kümesindeki en iyi puanın iyimserleşmesi, Denetimli Öğrenme kursunun hiperparametre arama dersinde ölçüldü ve tekrarlanmaz. Burada aranan şey bir ayar değeri değil bir metindir, ve puanı veren şey belirsiz bir bileşendir. Dersin tek sorusu şudur: arama bütçesi büyüdükçe doğrulamada kazanılan sayı, hiç görülmemiş bir sınama kümesine taşınıyor mu.
- AY69. Kod gerçek bir model uç noktası çağırmaz; standart kitaplıkla yazılmış bir benzetici çağırır. Destek talepleri ve konular kurgudur.
- AY70. Aday sayısı 10’u aşmaz. Adaylar dört parçadan mekanik olarak üretilir: rol cümlesi, önek cümlesi, etiket listesinin sırası ve biçim cümlesi.
- AY71. Küme ikiye ayrılır: doğrulama 40 kayıt, sınama 80 kayıt. Sınama kümesi arama boyunca hiç görülmez ve hiçbir seçim ona bakılarak yapılmaz.
- AY72. Ölçüt etiket isabetidir; yanıttan etiket okunamazsa kayıt yanlış sayılır.
- AY73. Arama kuralı: bütçe iken ilk aday içinde doğrulaması en yüksek olan seçilir. Beraberlikte listede önce gelen kazanır.
- AY74. Arama bedeli çağrı sayısıyla yazılır. Her aday doğrulama kümesinin tamamında koşturulur; bütçe için bedel çağrıdır.
- AY75. İyimserlik payı, seçilen adayın doğrulama puanı ile sınama puanı arasındaki farktır.
- AY76. İki koşum basılır. Tohum 20260219 ile arama baştan tekrarlanır; seçilen adayın değişip değişmediği ve aynı adayın sınama puanının ne kadar oynadığı yazılır.
On Aday, İki Küme
# BENZETICI -- KURGUDUR. Bu kod gercek bir model uc noktasi cagirmaz; standart # kitaplikla yazilmis bir dil modeli benzeticisini cagirir. Talepler de kurgudur. import math TOHUM, M32 = 20260218, 0xFFFFFFFF PENCERE, EN_UZUN = 240, 24 # baglam penceresi ve en buyuk cikti, belirtec 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): # KURGU belirtecleyici: parca en cok bes damga 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): # istemin icerigine bagli, kosumdan bagimsiz iz h = 2166136261 for c in m: h = ((h ^ ord(c)) * 16777619) & M32 return h KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"] 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}) 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"} # yaniltici baglar SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor", "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi", "kaydiniz alindi , konuyu inceleyip donus yapacagiz"] SAYAC = [0] def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN): SAYAC[0] += 1 bel = belirtecle(istem) if len(bel) > PENCERE: return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""} if SAYAC[0] % 37 == 0: return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""} r = uretec(tohum ^ izno(istem)) if len(bel) > 90 and r() < 0.04: return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""} aday = [k for k in KAVRAM if k[:5] in bel] # istemde adi gecen kavramlar if len(aday) < 3: aday = KAVRAM 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 if sicaklik <= 0.0: k = max(sorted(p), key=lambda a: p[a]) # en olasi secim else: e = [math.exp(p[a] / sicaklik) for a in sorted(p)] k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])] y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k) cb = belirtecle(y) if len(cb) > en_uzun: # durdurma kosulu cb = cb[:en_uzun] y = " ".join(cb) return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y} def oku(y): # yanittan etiket cikarma for s in y.lower().split(): if s in KONU: return s return None ROL = ["", "Sen destek masasi gorevlisisin . ", "Kayit gorevlisi olarak yanitla . "] ONEK = ["", "Once talebin hangi islem alanina girdigini belirle , sonra ", "Ornek: endeks tutmuyor -> sayac . "] LISTE = ["fatura , ariza , sayac , tarife , kesinti", "kesinti , tarife , sayac , ariza , fatura", "ariza , kesinti , fatura , sayac , tarife"] BICIM = ["Yanit olarak tek etiket yaz .", "Tek etiket yaz , aciklama ekleme .", "Cevabin tek sozcuk olsun , listedeki etiketlerden biri ."] ADAY, PARCA = [], [] r = uretec(TOHUM + 777) while len(ADAY) < 10: # adaylar mekanik uretilir, tohum sabittir d = [int(r() * 3) for _ in range(4)] y = (ROL[d[0]] + ONEK[d[1]] + "Talebi su etiketlerden birine ata: " + LISTE[d[2]] + " . " + BICIM[d[3]] + " Talep: ") if y not in ADAY: ADAY.append(y) PARCA.append("".join(str(x) for x in d)) DOG, SIN = TALEP[:40], TALEP[40:] def puan(yonerge, kume, tohum=TOHUM): d = 0 for x in kume: d += oku(cagir(yonerge + x["metin"], tohum=tohum)["yanit"]) == x["konu"] return d / len(kume) SAYAC[0] = 0 PD = [puan(y, DOG) for y in ADAY] CAGRI_ARAMA = SAYAC[0] PS = [puan(y, SIN) for y in ADAY] print(f"{'aday':>4} {'parca':>6} {'belirtec':>8} {'dogrulama':>10} {'sinama':>8} " f"{'fark':>8}") for i, y in enumerate(ADAY): print(f"{i + 1:>4d} {PARCA[i]:>6} {len(belirtecle(y)):>8d} {PD[i]:>10.4f} " f"{PS[i]:>8.4f} {PS[i] - PD[i]:>+8.4f}") print(f"\ndogrulama kumesi {len(DOG)} kayit, sinama kumesi {len(SIN)} kayit") print(f"arama cagrisi {CAGRI_ARAMA}, dogrulama ortalamasi {sum(PD) / 10:.4f}, " f"sinama ortalamasi {sum(PS) / 10:.4f}")
aday parca belirtec dogrulama sinama fark 1 2110 53 0.7750 0.6750 -0.1000 2 2201 51 0.7250 0.7250 +0.0000 3 1210 50 0.7500 0.6500 -0.1000 4 1000 41 0.6500 0.8000 +0.1500 5 0212 47 0.4250 0.4625 +0.0375 6 1101 56 0.9000 0.6500 -0.2500 7 0121 47 0.6000 0.6750 +0.0750 8 0202 47 0.5250 0.6000 +0.0750 9 1020 41 0.7750 0.7375 -0.0375 10 0100 45 0.7750 0.6875 -0.0875 dogrulama kumesi 40 kayit, sinama kumesi 80 kayit arama cagrisi 400, dogrulama ortalamasi 0.6900, sinama ortalamasi 0.6663
Son satır bir yanlış açıklamayı baştan kapatıyor. İki kümenin ortalamaları 0,6900 ve
0,6663; aralarında sistematik bir uçurum yok. Yani sınama kümesi daha zor değil, dağılımı
farklı değil. Buna rağmen fark sütunu iki yöne birden gidiyor ve 0,2500 büyüklüğüne ulaşıyor.
Ayrışma kümelerin arasında değil, aday başınadır.
Altıncı aday doğrulamada 0,9000 ile açık ara birinci, sınamada 0,6500 ile sondan ikinci. Dördüncü aday tam tersi: doğrulamada 0,6500 ile alt sıralarda, sınamada 0,8000 ile birinci. Kırk kayıtlık bir kümede tek kayıt 0,0250 eder; altıncı adayı birinciden ayıran 0,1250 farkı beş kaydın nereye düştüğünden ibarettir.
parca sütunu adayın dört hanesini verir: rol cümlesi, önek cümlesi, etiket listesinin sırası,
biçim cümlesi. Dördüncü aday 1000, dokuzuncu aday 1020; yalnız üçüncü hanede ayrılıyorlar.
Aynı rol cümlesi, aynı önek yokluğu, aynı biçim cümlesi, aynı beş etiket — tek fark etiketlerin
yazılma sırasıdır, ve sınama puanları 0,8000 ile 0,7375. İstemin taşıdığı bilgi
değişmeden puanın 0,0625 oynaması, bu aramanın neyi ölçtüğü sorusunu şimdiden açıyor.
Arama Bütçesi Büyüdükçe
def secim(pd): # butce b: ilk b aday icinde dogrulamasi en yuksek olan return [max(range(b), key=lambda i: pd[i]) for b in range(1, len(pd) + 1)] S = secim(PD) print(f"{'butce':>5} {'secilen':>7} {'dogrulama':>10} {'sinama':>8} {'arama cagrisi':>14}") for b, i in enumerate(S, 1): print(f"{b:>5d} {i + 1:>7d} {PD[i]:>10.4f} {PS[i]:>8.4f} {b * len(DOG):>14d}") ilk, son = S[0], S[-1] print(f"\nbutce 1 -> 10: dogrulama {PD[son] - PD[ilk]:+.4f}, sinama {PS[son] - PS[ilk]:+.4f}") print(f"secilen adayin iyimserlik payi {PD[son] - PS[son]:+.4f}") en = max(range(10), key=lambda i: PS[i]) print(f"sinamada en iyi aday {en + 1} ({PS[en]:.4f}); dogrulamasi {PD[en]:.4f}, " f"arama onu hic secmedi") SAYAC[0] = 0 PD2 = [puan(y, DOG, TOHUM + 1) for y in ADAY] PS2 = [puan(y, SIN, TOHUM + 1) for y in ADAY] son2 = secim(PD2)[-1] print(f"\nikinci kosum (tohum {TOHUM + 1}): secilen aday {son2 + 1}, dogrulama " f"{PD2[son2]:.4f}, sinama {PS2[son2]:.4f}") print(f"aday {son + 1} sinamasi iki kosumda {PS[son]:.4f} -> {PS2[son]:.4f} " f"({PS2[son] - PS[son]:+.4f})") print(f"on adayin sinama sirasi iki kosumda ayni mi: " f"{sorted(range(10), key=lambda i: -PS[i]) == sorted(range(10), key=lambda i: -PS2[i])}")
butce secilen dogrulama sinama arama cagrisi
1 1 0.7750 0.6750 40
2 1 0.7750 0.6750 80
3 1 0.7750 0.6750 120
4 1 0.7750 0.6750 160
5 1 0.7750 0.6750 200
6 6 0.9000 0.6500 240
7 6 0.9000 0.6500 280
8 6 0.9000 0.6500 320
9 6 0.9000 0.6500 360
10 6 0.9000 0.6500 400
butce 1 -> 10: dogrulama +0.1250, sinama -0.0250
secilen adayin iyimserlik payi +0.2500
sinamada en iyi aday 4 (0.8000); dogrulamasi 0.6500, arama onu hic secmedi
ikinci kosum (tohum 20260219): secilen aday 9, dogrulama 0.7500, sinama 0.7875
aday 6 sinamasi iki kosumda 0.6500 -> 0.8500 (+0.2000)
on adayin sinama sirasi iki kosumda ayni mi: False
Tablonun iki sütunu ters yönde ilerliyor. Bütçe birden ona çıkarken doğrulama sütunu 0,7750’den 0,9000’e yükseliyor — arama çalışıyor, işini yapıyor, her yeni adayla daha yüksek bir sayı buluyor. Aynı satırlarda sınama sütunu 0,6750’den 0,6500’e iniyor. Doğrulama kazancı +0,1250, sınama kazancı −0,0250. Arama bütçesinin dokuz katına çıkması, hiç görülmemiş veride hiçbir şey kazandırmadı; küçük bir kayıp getirdi.
Bedel aynı tabloda ve tartışmasız: 40 çağrıdan 400 çağrıya. Fazladan 360 çağrı harcandı ve karşılığında elde edilen tek şey rapor edilecek sayının 0,1250 yükselmesi oldu. Seçilen adayın iyimserlik payı 0,2500: doğrulamada 0,9000 yazan istem, hiç görülmemiş kayıtlarda 0,6500 veriyor. Bu istemi “0,9000’lik istem” diye teslim etmek, ölçünün dörtte birini uydurmak demektir.
Üçüncü satır aramanın körlüğünü gösteriyor. Sınamada gerçekten en iyi olan aday dördüncüdür (0,8000), ve arama onu hiçbir bütçede seçmedi; doğrulamada 0,6500 aldığı için daha ilk karşılaştırmada elendi. Arama iyi istemi bulamadı, doğrulama kümesine en iyi uyan istemi buldu.
İki Koşum ve Aramanın Ölçtüğü Şey
Son üç satır bütün alıştırmanın zeminini yokluyor. Tohum değiştirilip arama baştan koşturulunca seçilen aday altıncıdan dokuzuncuya kayıyor: aynı adaylar, aynı kümeler, aynı kural, başka bir kazanan. Dokuzuncu aday, sınamada birinci olan dördüncüden yalnız etiket sırasıyla ayrılıyordu. Dahası, altıncı adayın sınama puanı 0,6500’den 0,8500’e, yani +0,2000 oynuyor. Aramanın on aday üzerinde kazandığı doğrulama farkı 0,1250 idi; tek bir adayın koşumdan koşuma oynaması bunun üstünde. Son satır bunu tamamlıyor: on adayın sınama sıralaması iki koşumda aynı değil.
Buradan çıkan sonuç aramayı yasaklamaz, ölçüsünü düzeltir. Doğrulama kümesindeki en iyi puan bir istemin niteliği değil, bir arama bütçesinin artığıdır; bütçe büyüdükçe iyimserleşir ve bu iyimserlik ayrı bir sayıyla, hiç dokunulmamış bir kümede ölçülmedikçe görünmez. Aynı şey belirsiz bir bileşenin ikinci koşumu için de geçerlidir. Bu kursun kuralı burada son biçimini alıyor: ölçülmeden değiştirilen istem bir iyileştirme değil bir tahmindir — ve tek bir kümede, tek bir koşumda ölçülen istem de öyledir.
Özet
- On aday dört parçadan mekanik olarak üretiliyor; doğrulama kümesi 40, sınama kümesi 80 kayıt. İki kümenin ortalamaları 0,6900 ve 0,6663, yani ayrışma kümeler arasında değil aday başınadır.
- Arama bütçesi birden ona çıkarken doğrulama 0,7750’den 0,9000’e yükseliyor, aynı adayın sınaması 0,6750’den 0,6500’e iniyor: +0,1250 karşılığında −0,0250.
- Bedel çağrı sayısıyla yazılır: arama 40 çağrıdan 400 çağrıya çıkıyor.
- Seçilen adayın iyimserlik payı 0,2500. Sınamada gerçekten en iyi olan aday (0,8000) doğrulamada 0,6500 aldığı için hiçbir bütçede seçilmiyor.
- İkinci koşumda arama başka bir adayı seçiyor ve altıncı adayın sınaması +0,2000 oynuyor — tek bir adayın koşum farkı, aramanın on adayda kazandığı farktan büyük.
Sonraki Adım
On altı derste isteme ne söyleneceği düzenlendi ve modelden nasıl düşüneceği istendi: yönerge, rol, biçim, örnek, yasak bildirimi, adım adım çözüm, çoklu örnek, dallanma, geri adım, eylem alanı, topluluk ve şimdi arama. Hepsinin altında sessiz duran bir şey vardı — modelden gelen yanıt serbest metindi. Etiket her derste yanıtın içinden bir okuma yordamıyla çıkarıldı; okunamayan yanıt yanlış sayıldı ve o pay ayrıca sayıldı. İstem tarafında yapılan her iyileştirme, çıktının biçimini rica etmekten ibaretti. Sonraki konu bu tarafa geçer: yanıtın üretilme ayarları, yanıtın nerede durduğu, biçimin dayatılması, gelen çıktının şemaya ve iş kuralına karşı doğrulanması, ve doğrulamaya takılan yanıtın ne kadarının yeniden denemeyle kurtarıldığı.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.