Sınıflandırma, çapraz entropi ve kendini kandırmamanın yolları
Bölüm 2’nin loss’u ve Bölüm 3’ün descent’ıyla lojistik classifier kur; %98 accuracy’nin nasıl hiçbir şey bulmayan model olabileceğini gör.
Bu sayfada
Banttan çıkan her parça için bu parça iyi diye yanıt veren bir model, zamanın %98.15’inde haklıdır. Aynı zamanda tamamen değersizdir: test setindeki 74 hatalı parçanın hiçbirini yakalayamaz.
İki cümle de aynı modeli anlatıyor. Aralarındaki mesafe bu bölüm.
İlk yarı classifier’ı kuruyor. Neredeyse hiçbir yeni şeye ihtiyaç yok: Bölüm 2, verinin nasıl üretildiğine dair bir varsayımı loss function’a dönüştürmenin tarifini vermişti; Bölüm 3 ise bu tarifin verdiği herhangi bir loss üzerinde yokuş aşağı yürümenin mekanizmasını. İkisini bir evet/hayır sorusuna uygula; logistic regression ortaya çıkar, ayrıca yeni bir fikir gelir — bir logit — ve bunun hesabı Bölüm 17’de tekrar sorulacak.
İkinci yarı daha zor olan kısım. Kursun bundan sonraki her şeyi, birilerinin ölçtüğü bir sayıyla değerlendirilecek; gerçek bir iyileşmeyi ölçüm artefact’ından ayıramıyorsan, sonraki her bölüm sadece süs olur. O yüzden: confusion matrix, precision ve recall, üç split, leakage ve neredeyse kimsenin dürüstçe yanıtlamadığı soru — aslında kaç test örneğine ihtiyacım var?
Buradaki aritmetik 20.000 satır üzerinde çalışıyor, bu yüzden baştan sona vectorised — NumPy işi Bölüm 2’den beri yapıyor ve buradan sonra bunu ayrıca belirtmeye değmez.
Bant, daha nadir bir soruyla
Bölüme bağlantı: Bant, daha nadir bir soruylaBölüm 1’deki aynı fabrika, daha zor soru. Kabul mü ret mi yerine soru şu: bu parça hatalı mı — ve hatalar nadir, bu da bu bölümün ölçme yarısını zor, modelleme yarısını ise aldatıcı biçimde kolay yapıyor.
import numpy as np
rng = np.random.default_rng(4)
N = 20_000
width = rng.normal(22.0, 0.9, N) # millimetres
weight = rng.normal(57.0, 3.0, N) # grams
z_true = -5.90 + 1.90 * (width - 22.0) + 0.42 * (weight - 57.0)
y = (rng.random(N) < 1 / (1 + np.exp(-z_true))).astype(float)
perm = rng.permutation(N)
train, val, test = perm[:12_000], perm[12_000:16_000], perm[16_000:]N = 20000 defects = 337 base rate = 0.0169
defects per split = 203 60 74İki değil, üç split. Nedeni kendi bölümünü hak ediyor ve aşağıda alıyor; şimdilik ilkinde train et, ikincisinde tune et, üçüncüsüne bakma.
Feature’lar standardize ediliyor — ortalama çıkarılıyor, standart sapmaya bölünüyor — ve bunu yalnızca training istatistikleriyle yapıyoruz. Nedeni, Bölüm 1’in perceptron’ın convergence bound’u ile gösterdiği şey: merkezlenmemiş veri geometriyi düşmanca yapar. Bu ortalamayı hangi satırlardan hesaplamaya izinli olduğun ise bu bölümün ilerleyen kısmında canlı bir soruya dönüşecek.
Bir karardan olasılığa
Bölüme bağlantı: Bir karardan olasılığaPerceptron bir işaret döndürüyordu. Bir işaret, ret ile ret, ama kıl payı arasındaki farkı ayırt edemez; oysa fabrikanın bir insanın hangi parçaları önce yeniden incelemesi gerektiğine karar vermek için tam da bu farka ihtiyacı vardır.
O yüzden Bölüm 2’nin tarifini kelimesi kelimesine izle. Bir label’ın nasıl üretildiğine dair iddianı yaz, likelihood’u al, log’unu al, negatifini al ve bir loss elde et. Evet/hayır çıktısı için iddia bir Bernoulli dağılımıdır: parçanın hatalı olma olasılığı vardır ve
bu da “ ise , ise ” yazmanın kompakt yoludur. Bunun log’unu alıp negatifini aldığında, tek örnek için loss şudur:
Bu binary cross-entropy’dir. Kullanışlı olduğu için seçilmedi; bir yazı-tura sonucunun sahip olabileceği tek dağılımın negative log-likelihood’udur. Başka seçenek yoktu.
Hâlâ eksik olan şey, ’nin nereden geldiği. Model ağırlıklı bir toplam hesaplar; bu gerçek bir sayıdır ve tüm doğru üzerinde gezinir, oysa bir olasılığın içinde yaşaması gerekir. İkisi arasında hareket eden fonksiyon logistic sigmoid’dir:
logit -4.0 -> p = 0.0180 loss when y=1 and p=0.9 : 0.1054
logit -1.0 -> p = 0.2689 loss when y=1 and p=0.5 : 0.6931
logit 0.0 -> p = 0.5000 loss when y=1 and p=0.01 : 4.6052
logit 4.0 -> p = 0.9820Sağ sütunu bir fiyat listesi gibi oku. %90 confidence ile haklı olmak 0.105’e mal olur. Karar vermeyi reddetmek 0.693’e mal olur — bu , yani omuz silkme bedelidir. Kendinden emin biçimde yanılmak 4.6’ya, kırk dört kat fazlasına mal olur ve model bir hata konusunda daha emin oldukça fiyat sınırsız yükselir. Cross-entropy yalnızca hataları saymaz: kibre fatura keser.
Gradient, tahmin eksi gerçektir
Bölüme bağlantı: Gradient, tahmin eksi gerçektirBölüm 3 şöyle demişti: herhangi bir şeyi train etmek için loss’un her parametreye göre türevini al. Bunu tek örnek için yap. ve ile:
Ayrıntıları göster
Dağınıklığı sadeleştiren iki satır. Sigmoid’in alışılmadık derecede hoş bir türevi vardır, . Ve loss’un türevi şuna dönüşür:
Zincir kuralıyla ikisini çarpınca bir kez üstte, bir kez altta belirir. Tam olarak sadeleşir ve geriye kalır. Bu sadeleşme tesadüf değildir — loss bir dağılımın negative log-likelihood’u ve output function da o dağılımın doğal olarak kullandığı fonksiyon olduğunda her zaman olan şeydir. Bu eşleşmenin bir adı vardır — generalised linear model — ve düzenli gradient onun parmak izidir.1
Yani update şudur: tahmin eksi gerçek, input ile çarpılır. Başka hiçbir şey yok. İşte trainer’ın tamamı; Bölüm 3’ün descent’ı, yalnızca bir satırı değişmiş halde:
def sigmoid(z):
return np.where(z >= 0, 1.0 / (1.0 + np.exp(-z)),
np.exp(np.minimum(z, 0)) / (1.0 + np.exp(np.minimum(z, 0))))
def fit_logistic(X, y, lr=0.5, epochs=4000):
w, b = np.zeros(X.shape[1]), 0.0
for _ in range(epochs):
p = sigmoid(X @ w + b)
g = p - y
w -= lr * (X.T @ g) / len(y)
b -= lr * g.sum() / len(y)
return w, bsigmoid içindeki np.where kozmetik değildir. ’yi doğrudan hesaplamak büyük negatif değerlerinde overflow yapar; branch, cebirsel olarak aynı formlardan üssü negatif tutanı seçer. Bu, Bölüm 2’nin floating-point kutusunun ilk borcunu tahsil etmesidir; iki bölüm sonra daha büyüğünü tahsil edecek.
Neden squared error değil, ve neden cevap gradient hakkında
Bölüme bağlantı: Neden squared error değil, ve neden cevap gradient hakkındaCross-entropy’nin squared error’a tercih edilmesinin standart açıklaması yukarıdaki likelihood argümanıdır: squared error, Gaussian noise varsayımından çıkar; label’lar Gaussian değildir, o halde yapma. Doğrudur ama kimseyi ikna etmez, çünkü sigmoid’in üzerine yazabilirsin ve train olur.
İşe yarayan argüman gradient hakkındadır. Sigmoid’in üstüne squared error koyarsan zincir kuralı şunu verir:
O fazladan , az önce sadeleşen şeydir. Şimdi sadeleşmez ve model ne zaman kendinden emin olsa sıfıra gider — model kendinden emin biçimde yanlış olduğunda bile. Gerçek label’ı 1 olan bir örnek için ikisini birkaç score’da değerlendir:
| score | cross-entropy | squared error | oran | |
|---|---|---|---|---|
| 0.000335 | 1.491 | |||
| 0.017986 | 28.3 | |||
| 0.119203 | 4.8 | |||
| 0.500000 | 2.0 | |||
| 0.880797 | 4.8 |
’de model olabileceği kadar yanlıştır ve squared error, cross-entropy’nin gradient’ından 1.491 kat daha küçük bir gradient ile yanıt verir. Hata ne kadar kötüyse, model ondan o kadar az öğrenir. Cross-entropy’nin gradient’ı ise ’da doygunluğa ulaşır: maksimum yanlışlık maksimum büyüklükte bir sinyal üretir, daha fazlasını değil.
Yarışı çalıştır. İki bin dengeli nokta, kendinden emin biçimde yanlış olacak şekilde seçilmiş aynı başlangıç ağırlıkları (), aynı learning rate, yalnızca loss farklı. Sütunlar karşılaştırılabilir olsun diye iki koşu da cross-entropy ile score’lanıyor.
| epoch | cross-entropy loss | accuracy | squared-error loss | accuracy |
|---|---|---|---|---|
| 1 | 5.4865 | 0.2300 | 5.9499 | 0.2290 |
| 10 | 1.5525 | 0.2460 | 5.9042 | 0.2290 |
| 50 | 0.4642 | 0.7780 | 5.6913 | 0.2320 |
| 100 | 0.4639 | 0.7770 | 5.3955 | 0.2410 |
| 200 | 0.4639 | 0.7770 | 4.6311 | 0.2745 |
| 500 | 0.4639 | 0.7770 | 0.5291 | 0.7660 |
| 1.000 | 0.4639 | 0.7770 | 0.4640 | 0.7765 |
Cross-entropy epoch 50’de bitmiştir. Squared error epoch 100’de hâlâ %24 accuracy’dedir — epoch 10’da %23’ten hiç hareket etmemiştir — tahminden bile kötü, çünkü kendinden emin biçimde yanlış başlamış ve onu kurtaracak gradient 0.0007 ile çarpılmıştır. Yaklaşık epoch 500’de kaçar ve aynı yere iner. Yani dürüst özet şu: sigmoid üzerinde squared error yanlış değildir; hızın en önemli olduğu yerde tam olarak yavaştır. İki parametreli bir modelde 450 epoch kaybedersin. Yüz katmanlı bir ağda, bir yerlerde bir unit her zaman kendinden emin biçimde yanlışken, tüm training run’ı kaybedersin.
Entropy, cross-entropy ve KL, tek sayfada
Bölüme bağlantı: Entropy, cross-entropy ve KL, tek sayfadaÜç nicelik; Bölüm 8’de perplexity için, Bölüm 11’de ise fine-tuned bir policy’yi referansına yakın tutan ceza için düzgün şekilde gerekecek. Ünlerinden daha kolaylar.2
Entropy, bir dağılımdan çekilen bir örneği iletmek için, onun için mümkün olan en iyi kodu kullanırsan harcaman gereken ortalama bit sayısıdır:
Cross-entropy, aslında ’den gelen veri üzerinde için kurulmuş bir kod kullandığında harcadığın şeydir:
KL divergence, fazlalıktır — gerçek iken ’e inanmanın bit cinsinden yarattığı israf:
Üçünü de bant üzerinde kontrol et:
test defect rate = 0.0185
entropy of that coin = 0.1329 bits
cross-entropy of the constant predictor on test = 0.1330 bits
KL(test coin || fair coin) = 0.8671 bits
H + KL = 1.0000 bits
cross-entropy of the p=0.5 predictor on test = 1.0000 bitsOrada iki şey görünür. Birincisi, yalnızca training base rate’i, %1.69’u bildiren bir model, 0.1330 bit cross-entropy elde eder; bu, test label’larının entropy’siyle neredeyse aynıdır — olması gerektiği gibi, çünkü doğru dağılıma sahiptir ve başka bilgisi yoktur. Entropy, bireyden habersizliğin sana satın aldığı tabandır. İkincisi, omuz silkerek 0.5 diyen bir model tam 1 bit öder ve ikisi arasındaki fark, 0.8671 bit, tam olarak KL divergence’dır. ezberlenecek bir özdeşlik değildir; eklenişini izleyebileceğin bir faturadır.
Training’e geri bağlantı da şu: label tek bir bilinen sınıf olduğunda, “true” dağılım one-hot’tır, entropy’si sıfırdır ve cross-entropy KL divergence’a eşittir. Cross-entropy’yi minimize etmek ile modelin dağılımını gerçeğe doğru çekmek aynı eylemdir.
İkiden fazla cevap: softmax ve hiçbir maliyeti olmayan shift
Bölüme bağlantı: İkiden fazla cevap: softmax ve hiçbir maliyeti olmayan shiftHatalı olmak tek bir şey değildir. Kalıplamada bir parça short shot (yetersiz malzeme), flash (fazla malzeme, kalıptan taşmış) veya burn olarak çıkabilir. Dört sonuç, dolayısıyla dört logits; bunların toplamı bir olan dört olasılığa dönüşmesi gerekir. Bu softmax’tır:
Kazara gibi görünen ama aslında tüm implementation olan bir özelliği vardır:
herhangi bir sabit için, çünkü ve üstte ve altta sadeleşir. Yalnızca logits arasındaki farklar bir anlam taşır. Mutlak seviye bilgi değildir.
Neyse ki öyle, çünkü bilgisayarı bozan şey mutlak seviyedir:
logits = [800. 801. 799.]
naive softmax = [nan nan nan]
shifted by -max = [0.2447 0.6652 0.09 ]
same softmax after adding 1000 to every logit: True, 64-bit float’ta overflow yapar, toplam sonsuz olur ve sonsuzun sonsuza bölümü nan’dır — hata değil, crash değil, yalnızca üç olasılığın olması gereken yerde sessiz bir delik. Maksimum logit’i çıkarmak matematiksel olarak hiçbir şeyi değiştirmez, sayısal olarak her şeyi değiştirir; çünkü en büyük üs tam olarak olur. Bu, Bölüm 2’nin logsumexp numarasının iş kıyafetlerini giymiş halidir ve her ciddi implementation bunu yapar:
def softmax(Z):
Z = Z - Z.max(axis=1, keepdims=True)
E = np.exp(Z)
return E / E.sum(axis=1, keepdims=True)
def fit_softmax(X, Y, lr=1.0, epochs=6000):
W, b = np.zeros((X.shape[1], Y.shape[1])), np.zeros(Y.shape[1])
for _ in range(epochs):
G = (softmax(X @ W + b) - Y) / len(X)
W -= lr * (X.T @ G)
b -= lr * G.sum(0)
return W, bGradient yine tahmin eksi gerçektir; bu kez one-hot. Binary case başından beri özel bir durumdu.
3.000 parça üzerinde train edilip 1.000 parça üzerinde test edildiğinde, her parça için üç ölçümle (genişlik, ağırlık, erime sıcaklığı), %94.00 accuracy’ye ulaşır. Bu sayının ne sakladığı burada:
| gerçek ↓ / tahmin → | ok | short shot | flash | burn | recall |
|---|---|---|---|---|---|
| ok | 850 | 5 | 9 | 0 | 0.984 |
| short shot | 22 | 21 | 0 | 0 | 0.488 |
| flash | 20 | 0 | 30 | 1 | 0.588 |
| burn | 3 | 0 | 0 | 39 | 0.929 |
| precision | 0.950 | 0.808 | 0.769 | 0.975 |
Model short shot’ların yarısından azını buluyor. Accuracy bunu göremez, çünkü parçaların %86’sı iyidir ve bunları doğru yapmak ortalamayı taşımaya yeter. Macro F1 — nadir bir sınıfa yaygın bir sınıfla aynı ağırlığı veren, sınıf başına F1 score’larının ortalaması — 0.7983’tür, tanımı gereği accuracy ile aynı olan micro F1 0.9400’a karşı. Birisi tek bir F1 sayısı raporladığında hangisi olduğunu sor.
Modellemenin sonu bu. Bölümün geri kalanı sayılar hakkında.
Üç model, tek accuracy
Bölüme bağlantı: Üç model, tek accuracyTrain edilmiş binary modeli al ve her logit’i bir sabitle çarparak iki varyant yap: çekingen bir versiyon için 0.35, aşırı kendinden emin bir versiyon için 4. Pozitif bir sayıyla çarpmak hiçbir işareti değiştiremez, bu yüzden üç model de 4.000 test parçasının tamamı için tam olarak aynı label’ı tahmin eder. Accuracy onları ayırt edemez. Cross-entropy hiç zorlanmaz:
| model | accuracy | cross-entropy | doğruyken ortalama loss | yanlışken ortalama loss | en kötü tekil loss |
|---|---|---|---|---|---|
| çekingen (logits × 0.35) | 0.9830 | 0.1549 | 0.1369 | 1.1990 | 2.80 |
| train edildiği gibi | 0.9830 | 0.0564 | 0.0147 | 2.4689 | 7.82 |
| aşırı kendinden emin (logits × 4) | 0.9830 | 0.1563 | 0.0009 | 9.1427 | 27.63 |
Çekingen model, doğru yaptığı binlerce parça dahil her parçada küçük bir vergi öder. Aşırı kendinden emin olan doğruyken neredeyse bedavadır, yanlışken felakettir — o test setindeki tek bir parça tek başına 27.63 nat’a mal olur. İkisi zıt yollardan neredeyse aynı toplama iner; olasılıkları veriye calibrated olan train edilmiş model ise ikisinin de üç kat altında durur.
Bu, loss ile metric arasındaki farkı söylemenin en keskin yoludur. Loss optimize ettiğin şeydir: differentiable olmalıdır ve modelin söylediği her şeyi, ne kadar emin olduğunu da, görür. Metric yargılandığın şeydir: bir step function, bir iş kuralı, kaçırılan hata sayısı olabilir. Aynı nesne değillerdir ve her zaman anlaşmazlar — bu yüzden ikisini de başlamadan önce tanımlarsın ve sırf ekranda duruyor diye loss’un metric’in yerine geçmesine asla izin vermezsin.
Aptal baseline önce gelir
Bölüme bağlantı: Aptal baseline önce gelirHerhangi bir modelden önce gereksinim: mümkün olan en tembel cevap kaç puan alır? Bu bantta, her zaman iyi de:
always-say-fine baseline: accuracy = 0.9815
confusion (tn, fp, fn, tp) = (3926, 0, 74, 0)%98.15. Şimdi train edilmiş logistic model, default threshold 0.5 ile:
logistic @0.5: accuracy=0.9830 precision=0.8000 recall=0.1081 F1=0.1905
confusion (tn, fp, fn, tp) = (3924, 2, 66, 8)%98.30. Baseline’ı 0.15 yüzde puanı geçti ve accuracy’de duran herhangi bir rapor buna zafer diyecek. Confusion matrix gerçekte ne olduğunu söyler:
| tahmin edilen iyi | tahmin edilen hatalı | |
|---|---|---|
| gerçekte iyi | 3.924 | 2 |
| gerçekte hatalı | 66 | 8 |
74 hatalı parçanın 8’ini buldu ve 66’sının geçmesine izin verdi. Üç sayı bu tabloyu okumanın üç yolunu adlandırır:
- Precision . Flag’lediği parçaların kaçı gerçekten hatalıydı. Bu, boşa giden incelemelerin maliyetidir.
- Recall . Hatalı parçaların kaçını yakaladı. Bu, müşteriye kötü parça göndermenin maliyetidir.
- F1 , ikisinin harmonic mean’i; küçüğe yakın kalır ve bu yüzden tek başına birinin kendisini pohpohlamasını reddeder.
Hangisinin önemli olduğu matematiğe değil fabrikaya bağlıdır: bir inceleme birkaç saniyeye mal olur, gönderilmiş bir hata recall notice’e; bu yüzden burada recall baskındır ve 0.108 başarısızlıktır.
Ama sorun model değildir. Sorun threshold’dur, ve threshold modelin parçası değildir — bir olasılığa sonradan uygulanan iş kararıdır. Süpür:
| threshold | TP | FP | FN | accuracy | precision | recall | F1 |
|---|---|---|---|---|---|---|---|
| 0.500 | 8 | 2 | 66 | 0.9830 | 0.800 | 0.108 | 0.190 |
| 0.200 | 27 | 28 | 47 | 0.9812 | 0.491 | 0.365 | 0.419 |
| 0.100 | 42 | 118 | 32 | 0.9625 | 0.263 | 0.568 | 0.359 |
| 0.050 | 54 | 236 | 20 | 0.9360 | 0.186 | 0.730 | 0.297 |
| 0.020 | 67 | 570 | 7 | 0.8558 | 0.105 | 0.905 | 0.188 |
| 0.005 | 71 | 1.360 | 3 | 0.6593 | 0.050 | 0.959 | 0.094 |
Accuracy sütununu aşağı doğru oku. Baştan sona düşer — %98.30’dan %65.93’e — model ise 8 hata yakalamaktan 74’ün 71’ini yakalamaya gider. Bu modelin yapabileceği her faydalı şey accuracy’sini kötüleştirir. Başlık sayısını optimize eden bir ekip hiçbir şey bulmayan versiyonu ship ederdi.
Ayrıntıları göster
Class weighting sinyal yaratmaz, operating point’i taşır. Imbalanced classes karşısındaki olağan ilk refleks, rare class’a loss içinde ağırlık vermektir. Pozitiflerde 1, 10 ve 60 ağırlıklarıyla bunu yapınca:
| pozitiflere verilen ağırlık | accuracy | precision | recall | F1 | AUC |
|---|---|---|---|---|---|
| 1 | 0.9830 | 0.800 | 0.108 | 0.190 | 0.9363 |
| 10 | 0.9605 | 0.253 | 0.581 | 0.352 | 0.9361 |
| 60 | 0.8290 | 0.091 | 0.919 | 0.166 | 0.9361 |
Precision ve recall çok oynar. AUC — modelin rastgele bir hatalı parçayı rastgele bir iyi parçanın üstünde sıralama olasılığı, threshold’u tamamen yok sayar — 0.0002 oynar; bu hiçbir şeydir. Reweighting aynı modeli aynı trade-off eğrisi boyunca kaydırdı. Çoğu zaman istediğin şey budur ve asla yeni bilgi değildir: ranking kötüyse hiçbir weighting scheme onu kurtarmaz.
Üç split ve bulmak üzere olduğun leak
Bölüme bağlantı: Üç split ve bulmak üzere olduğun leakNeden iki değil üç split? Çünkü bir örnek setini herhangi bir şeyi seçmek için kullandığın anda — threshold, learning rate, altı modelden hangisinin ship edileceği — o set fitting için kullanılmış olur ve score’u unbiased olmayı bırakır.3 Bu bant üzerinde ölçüldü: validation set üzerinde threshold süpürmek 0.196’yı seçer ve model daha sonra dokunulmamış test setinde F1 = 0.4122 alır. Süpürme doğrudan test set üzerinde yapılsaydı, orada ulaşılabilen en iyi değer 0.4186 olurdu — kimsenin raporlamaya hakkı olmayan bir sayı.
Fark burada küçük, 0.006; çünkü 4.000 validation örneğine karşı bir hyperparameter bir kez süpürüldü. Her ekstra kararla ve validation set’in her küçülmesiyle büyür. Şunu da not et: tek bir koşuda yön garanti değildir; seçilen threshold validation’da 0.3902, test’te 0.4122 aldı, yani validation bu kez onu eksik gösterdi. Bias birçok karar genelinde sistematiktir, tek bir koşuda görünür değildir.4
Şimdi egzersiz. Bant log’u üçüncü bir sütunla geliyor, station_seconds: her parçanın inspection station’da ne kadar kaldığı. Bunu eklemek preprocessing’e tek satırlık bir değişikliktir. Yaptığı şey şu:
| model | accuracy | precision | recall | F1 | cross-entropy | AUC |
|---|---|---|---|---|---|---|
| genişlik + ağırlık | 0.9830 | 0.800 | 0.108 | 0.190 | 0.0564 | 0.9363 |
| + station_seconds | 0.9920 | 0.792 | 0.770 | 0.781 | 0.0236 | 0.9970 |
Recall %10.8’den %77.0’ye çıkar. F1 dört kattan fazla artar. Accuracy’nin ne yaptığına da dikkat et: %98.30 → %99.20, dokuz onda puanlık bir kazanç; özet slaytta “her iki türlü de yaklaşık %99” diye yuvarlanan türden bir sayı. Accuracy az önceki başarısızlığı göremedi; şimdi de hileyi göremiyor.
Devam etmeden önce: model hile yapıyor. Nasıl yaptığını bul.
Bir leak’i en hızlı bulacak sırayla nasıl avlarsın.
-
Train ve test’i karşılaştır. Overfitting büyük bir fark olarak görünür. Burada: dürüst model 0.9838 train / 0.9830 test; leaky model 0.9936 train / 0.9920 test. İki fark da 0.2 puanın altında. Leak overfitting gibi görünmez — leaky feature test time’da da aynı derecede erişilebilirdir, bu yüzden model var olmayan bir dünyaya harika generalise eder.
-
Her feature için tek başına bir model train et. Cevabı taşıyan herhangi bir şey kendini duyurur:
tek başına feature accuracy recall F1 AUC genişlik 0.9815 0.014 0.026 0.8691 ağırlık 0.9815 0.000 0.000 0.7914 station_seconds0.9850 0.405 0.500 0.9960 Tek bir sütun, kendi başına, hataları AUC 0.9960 ile sıralar. Kumpas ve teraziyle alınan iki ölçüm 0.87 ve 0.79’a ulaşır. Bu asimetri alarmdır.
-
Her sayının ne zaman yazıldığını sor. Ortalama bekleme süresi: geçen parçalar için 2.23 saniye, kalan parçalar için 15.56 saniye. Elbette. Bir parça istasyonda bekler, çünkü bir inspector onu banttan almıştır — bu da birisi onun hatalı olduğuna karar verdikten sonra ve yalnızca bu yüzden olur. Sütun parçanın ölçümü değildir. Kararın ölçümüdür.
station = 1.8 + rng.exponential(0.35, N) # a part just passing through
audited = rng.random(N) < 0.006 # random spot checks
station[audited] += rng.uniform(6.0, 26.0, audited.sum())
station[y == 1] = 9.0 + rng.exponential(7.0, (y == 1).sum()) Vurgulanan satır leak’tir: hatalı bir parçanın dwell time’ı farklı bir dağılımdan çekilir, çünkü bir insan onu banttan almıştır. Bu, applied machine learning’deki en yaygın ciddi bug’dır ve bir adı vardır: target leakage — prediction’ın yapılması gereken anda mevcut olmayacak bilginin training feature’larında bulunması.5 Exception fırlatmaz. Daha iyi bir sayı üretir. Bir projedeki her incentive onu tutmaya işaret eder.
Savunma, her sütuna sorulan tek sorudur: bu prediction’a ihtiyaç duyduğum anda bu değer henüz var mı? Canlı bir bantta station_seconds, parça incelenene kadar bilinmez — modelin yerine geçmesi gereken şey tam da buydu.
Kaç test örneğine ihtiyacım var?
Bölüme bağlantı: Kaç test örneğine ihtiyacım var?Bir modeli 20 örnek üzerinde score’ladığını ve 17’sini doğru yaptığını varsay. %85 raporlarsın.
17 correct out of 20 -> accuracy 0.8500
Wilson 95% CI : [0.6396, 0.9476]
bootstrap 95% CI : [0.7000, 1.0000]
P(a 65% model scores 17 or more out of 20) = 0.0444
P(an 85% model scores 17 or more out of 20) = 0.647717/20’nin dürüst okuması şudur: %64 ile %95 arasında bir yer. Gerçekten %65’lik bir model bu sonucu zamanın %4.4’ünde üretir — yirmi üçte bir koşu — ve bir avuç prompt deneyip en iyisini raporladıysan, o koşuyu kendin üretmiş oldun. Yirmide on yedi, %85’lik bir modeli %65’lik olandan ayıramaz.
Bir oran üzerine interval koymanın iki yolu var ve ikisi de araç çantanda olmalı:
def wilson(k, n, z=1.959963985):
"""95% interval for k successes in n trials. Correct at small n; no simulation."""
ph, d = k / n, 1 + z * z / n
centre = (ph + z * z / (2 * n)) / d
half = z * (ph * (1 - ph) / n + z * z / (4 * n * n)) ** 0.5 / d
return centre - half, centre + half
def bootstrap_ci(correct, n_resamples=10_000, alpha=0.05, seed=0):
"""95% interval for the mean of any per-example score array. Works on F1 too."""
rng = np.random.default_rng(seed)
correct = np.asarray(correct, dtype=float)
draws = correct[rng.integers(0, len(correct), size=(n_resamples, len(correct)))]
lo, hi = np.quantile(draws.mean(axis=1), [alpha / 2, 1 - alpha / 2])
return float(correct.mean()), float(lo), float(hi)Düz bir success rate için Wilson6 kullan; her değerinde düzgün davranır ve randomness gerektirmez. Yukarıda iken bootstrap’ın üst ucunun 1.0000 olduğuna dikkat et — 20 noktayı resample etmek kolayca 20 doğru çekebilir, dolayısıyla kendi granularity’sinden daha dar bir interval temsil edemez. Formül olmayan yerde bootstrap7 kullan; ilginç vakaların çoğu böyledir: F1, macro-averages, BLEU, pass@1, rubric-based judge score’u. Bu bantta, tuned modelin 0.4122’lik F1 değeri [0.3009, 0.5156] bootstrap interval’ı taşır — raporda görünmesi gereken sayı budur, çünkü point estimate tek başına destekleyemeyeceği bir karşılaştırmaya davetiye çıkarır.
Bir ölçüm daha, çünkü iki modeli nasıl karşılaştırman gerektiğini değiştirir. Aynı 500 örnek üzerinde score’lanan iki model:
model A: 0.8580 95% CI [0.8260, 0.8880]
model B: 0.8120 95% CI [0.7780, 0.8460]
the two intervals overlap: True
paired difference A-B: 0.0460 95% CI [0.0260, 0.0680]
they disagree on 31 of 500 examples (A right 27, B right 4)Interval’ları çakışıyor ve halk kuralı — çakışan error bar’lar anlamlı fark yok demektir — karşılaştırmayı inconclusive sayardı. Öyle değil. İki model aynı örnekler üzerinde koştu, bu yüzden doğru nicelik örnek başına farktır; onun interval’ı [0.0260, 0.0680], rahatça sıfırın üstündedir. 500 item’ın yalnızca 31’inde anlaşmazlar ve A bu anlaşmazlıkların 27’sini kazanır; kolay ve zor ortak örnekler noise eklemek yerine birbirini götürür. Modelleri paired karşılaştır, aynı sonuca verinin bir kesriyle ulaşırsın.
Bundan sonra nereye gidiyor
Bölüme bağlantı: Bundan sonra nereye gidiyorArtık calibrated probabilities üreten bir modelin, kolaylık için seçilmek yerine veri hakkındaki bir iddiadan türetilmiş bir loss’un, kelimenin tam anlamıyla tahmin eksi gerçek olan bir gradient’ın ve — daha önemlisi — bunların herhangi birinin çalışıp çalışmadığını öğrenme mekanizmasının var. Yukarıdaki on satırlık Wilson interval aynen yeniden kullanılır: Bölüm 15’teki prompt varyantlarını, Bölüm 19’daki retrieval tablolarını ve Bölüm 29’daki golden set’i taşır. Formül olmadığında başvuracağın şey bootstrap’tır.
Ama model hâlâ tek katman. Bir çizgi çizer ve Bölüm 1, dört satırlık XOR ile bir çizginin yetmediğini kanıtlamıştı. Çözüm stack etmektir: space’i büken bir ilk katman, bükülmüş space’te çizgiyi çizen ikinci katman.
Bu bölümün düzenli gradient’ı burada tükenir. Yukarıdaki her şey çalıştı çünkü , input ile loss arasında tek katmanlı bir model için bir kez elde, yazılabiliyordu. Ortaya ikinci bir katman koyunca soru şekil değiştirir: output’a hiç dokunmayan bir weight’e göre loss’un türevi nedir — etkisi yalnızca başka bir katman üzerinden, belki aynı anda birkaç yol boyunca gelen bir weight?
O türev vardır. Onu elle hesaplamak oyuncaktan büyük herhangi bir şey için umutsuzdur ve her parametre için tek tek hesaplamak başka bir ölçekte umutsuzdur. Gereken şey, forward pass’in az önce yürüdüğü aynı graph üzerinde tek bir backward pass ile ağdaki her türevi çıkaran bir prosedürdür.
Bu Bölüm 5’tir ve kursun geri kalanının üzerinde çalıştığı motordur.
Kaynaklar ve yöntem
Bölüme bağlantı: Kaynaklar ve yöntemBu bölümle birlikte okumaya değer diğer kaynaklar: Bishop, Pattern Recognition and Machine Learning §1.2, §1.5, §1.6 ve §4.3; probability, decision theory, information theory ve linear classification’ı bu bölümün izlediği sırayla kapsar. Murphy, Probabilistic Machine Learning: An Introduction, bölüm 6 ve 10; Prince, Understanding Deep Learning §5.4–5.7; ve Saito ve Rehmsmeier, The Precision-Recall Plot Is More Informative than the ROC Plot When Evaluating Binary Classifiers on Imbalanced Datasets (PLOS ONE, 2015) — parçaların %1.7’si hatalıyken yukarıda alıntılanan AUC’nin bakacağın tek threshold-free sayı olmaması gerektiğinin nedeni.
Referanslar
Bölüme bağlantı: Referanslar-
Ma, T. ve Ng, A. CS229 Lecture Notes, Stanford University, bölüm 2 ve 3. ’yi üreten sadeleşmenin şans gibi görünmeyi bıraktığı yer: output’una uyan exponential-family dağılımını seç, onun canonical link’ini kullan ve gradient her zaman tahmin eksi gerçek olur. ↩
-
Olah, C. Visual Information Theory (2015),
colah.github.io/posts/2015-09-Visual-Information. Entropy, cross-entropy ve KL divergence’ı formül yerine bit cinsinden maliyetler olarak anlatan en net kaynak. ↩ -
Abu-Mostafa, Y. S., Magdon-Ismail, M. ve Lin, H.-T. Learning From Data (AMLBook, 2012), Caltech kursunun 13. ve 17. dersleri. 13. ders validation’dır; üç öğrenme ilkesine dair 17. derste data snooping adlandırılır. İkisi birlikte bu bölümdeki disiplinin kaynağıdır: bir data set’e her bakış, optimiser çalıştırmış olsan da olmasan da bir fitting kararıdır. ↩
-
James, G., Witten, D., Hastie, T. ve Tibshirani, R. An Introduction to Statistical Learning, 2. baskı (Springer, 2021), bölüm 2 ve 5; bias–variance decomposition ve resampling için. Selection trap’in doğrudan ifade edildiği eşlik eden cilt: Hastie, Tibshirani ve Friedman, The Elements of Statistical Learning, 2. baskı, §7.10.2, The Wrong and Right Way to Do Cross-validation. ↩
-
Kaufman, S., Rosset, S., Perlich, C. ve Stitelman, O. Leakage in Data Mining: Formulation, Detection, and Avoidance. ACM Transactions on Knowledge Discovery from Data 6(4), 2012. Yukarıda gösterilen hatanın, verinin nasıl bir araya getirildiğine dair bir artefact öğrenmiş modelin kazandığı yarışmalardan case study’lerle birlikte formal treatment’ı. ↩
-
Wilson, E. B. Probable Inference, the Law of Succession, and Statistical Inference. Journal of the American Statistical Association 22(158), s. 209–212 (1927). Yukarıdaki
wilson()içinde kullanılan score interval; bir proportion için hâlâ doğru default. Kaçınılması gereken textbook interval ’tir: 0 ve 1 yakınında saçmalık üretir, küçük değerlerinde ciddi undercoverage yapar. ↩ -
Efron, B. Bootstrap Methods: Another Look at the Jackknife. The Annals of Statistics 7(1), s. 1–26 (1979). Sampling theory’si olmayanlar dahil, hesaplayabildiğin herhangi bir statistic üzerine interval koymanı sağlayan fikir. ↩