सामग्री पर जाएँ
4/30अध्याय 4 / 30

Classification, Cross-Entropy और खुद को धोखा देने से कैसे बचें

logistic classifier बनाएं और जानें कि 98 % accuracy वाला model भी कुछ नहीं पकड़ सकता।

इस पेज पर

एक model जो बेल्ट से निकलने वाले हर पुर्जे के बारे में यह हिस्सा ठीक है जवाब देता है, 98.15 % बार सही होता है। वह बेकार भी है: test set में 74 खराब पुर्जों में से वह एक भी नहीं पकड़ता।

दोनों वाक्य उसी model का वर्णन करते हैं। उनके बीच की दूरी ही यह अध्याय है।

पहला आधा हिस्सा classifier बनाता है। इसमें लगभग कुछ नया नहीं चाहिए: अध्याय 2 ने यह recipe दी थी कि data कैसे बनता है, इस assumption को loss function में कैसे बदला जाए, और अध्याय 3 ने उस loss पर नीचे उतरने की machinery दी थी जो recipe आपको देती है। दोनों को yes/no सवाल पर लगाइए और logistic regression निकल आता है, साथ में एक नया विचार — एक logit — जिसकी कीमत अध्याय 17 में फिर चुकानी पड़ेगी।

दूसरा आधा हिस्सा कठिन है। इस point के बाद course में हर चीज किसी मापी हुई संख्या से judge होगी, और अगर आप वास्तविक सुधार को measurement artefact से अलग नहीं कर सकते, तो आगे का हर अध्याय सिर्फ सजावट है। इसलिए: confusion matrix, precision और recall, तीन splits, leakage, और वह सवाल जिसका ईमानदार जवाब लगभग कोई नहीं देता — मुझे वास्तव में कितने test examples चाहिए?

यहां arithmetic 20,000 rows पर चलती है, इसलिए पूरी तरह vectorised है — NumPy अध्याय 2 से काम कर रहा है, और यहां से इस बात को अलग से बताना worthwhile नहीं रहता।

अध्याय 1 वाली वही factory, लेकिन सवाल कठिन। accept या reject की जगह सवाल है क्या यह पुर्जा defective है — और defects दुर्लभ हैं, जिससे इस अध्याय का measuring half कठिन और modelling half धोखे से आसान हो जाता है।

belt.pyPYTHON
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:]
TEXT
N = 20000  defects = 337  base rate = 0.0169
defects per split = 203 60 74

तीन splits, दो नहीं। इसकी वजह अपनी अलग section की हकदार है और नीचे मिलेगी; फिलहाल, पहले पर train करें, दूसरे पर tune करें, और तीसरे को न देखें।

Features standardised हैं — mean घटाया गया, standard deviation से divide किया गया — और इसके लिए सिर्फ training statistics इस्तेमाल किए गए हैं, उसी वजह से जिसे अध्याय 1 ने perceptron के convergence bound से दिखाया था: uncentred data geometry को hostile बना देता है। आपको वह mean किन rows से compute करने की अनुमति है, यह आगे इस अध्याय में live question बन जाता है।

Perceptron ने sign लौटाया था। Sign reject और reject, लेकिन बस थोड़ा सा में फर्क नहीं कर सकता, और यही फर्क factory को चाहिए ताकि वह तय कर सके कि कौन से parts human को पहले re-inspect करने चाहिए।

तो अध्याय 2 की recipe को literally follow करें। लिखें कि label कैसे produced होता है, इसके बारे में आपका दावा क्या है; likelihood लें, log लें, उसे negate करें, और आपके पास loss है। yes/no outcome के लिए दावा एक Bernoulli distribution है: probability pp है कि part defective है, और

P(yp)=py(1p)1yP(y \mid p) = p^{\,y}\,(1-p)^{\,1-y}

जो बस यह लिखने का compact तरीका है: “pp if y=1y = 1, and 1p1-p if y=0y = 0”. इसका log लेकर negate करें, और एक example का loss है

L=[ylogp+(1y)log(1p)]L = -\big[\,y \log p + (1 - y)\log(1 - p)\,\big]

यह binary cross-entropy है। इसे इसलिए नहीं चुना गया कि यह convenient है; यह उस अकेली distribution की negative log-likelihood है जो coin flip में हो सकती है। कोई और विकल्प था ही नहीं।

अब भी missing है कि pp कहां से आता है। Model weighted sum s=wx+bs = \mathbf{w}\cdot\mathbf{x} + b compute करता है, जो एक real number है और पूरी line पर range करता है, जबकि probability को (0,1)(0,1) में रहना होता है। इनके बीच ले जाने वाला function logistic sigmoid है:

σ(s)=11+es\sigma(s) = \frac{1}{1 + e^{-s}}
TEXT
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.9820

Right-hand column को price list की तरह पढ़ें। 90 % confidence के साथ सही होना 0.105 cost करता है। Commit करने से इंकार करना 0.693 cost करता है — जो log2\log 2 है, shrug की कीमत। Confidently गलत होना 4.6 cost करता है, चवालीस गुना ज्यादा, और जैसे-जैसे model गलती के बारे में ज्यादा sure होता है, कीमत बिना limit बढ़ती है। Cross-entropy सिर्फ errors count नहीं करता: वह arrogance के पैसे वसूलता है।

अध्याय 3 ने कहा था: कुछ भी train करना हो, हर parameter के respect में loss की derivative निकालो। एक example के लिए करें। s=wx+bs = \mathbf{w}\cdot\mathbf{x} + b और p=σ(s)p = \sigma(s) के साथ:

Ls=py,Lw=(py)x,Lb=py\frac{\partial L}{\partial s} = p - y, \qquad \frac{\partial L}{\partial \mathbf{w}} = (p - y)\,\mathbf{x}, \qquad \frac{\partial L}{\partial b} = p - y
विवरण दिखाएँ

वे दो lines जिनसे mess cancel होता है। Sigmoid की derivative unusually pleasant है, σ(s)=σ(s)(1σ(s))=p(1p)\sigma'(s) = \sigma(s)\,(1 - \sigma(s)) = p(1-p)। और loss differentiate होकर बनता है

Lp=yp+1y1p=pyp(1p)\frac{\partial L}{\partial p} = -\frac{y}{p} + \frac{1-y}{1-p} = \frac{p - y}{p\,(1-p)}

Chain rule से दोनों को multiply करें और p(1p)p(1-p) एक बार ऊपर और एक बार नीचे आता है। वह exactly cancel हो जाता है, और pyp - y बचता है। यह cancellation कोई coincidence नहीं — यह तब होता है जब loss किसी distribution की negative log-likelihood हो और output function वही हो जिसे वह distribution naturally use करता है। इस pairing का नाम है — generalised linear model — और साफ-सुथरा gradient उसकी fingerprint है।1

तो update है prediction minus truth, times the input। बस। यह पूरा trainer है, जो अध्याय 3 का descent है, सिर्फ एक line बदली हुई:

logistic.pyPYTHON
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, b

sigmoid में np.where cosmetic नहीं है। 1/(1+es)1/(1+e^{-s}) को directly compute करना बड़े negative ss के लिए overflow कर जाता है; branch वह algebraically identical form चुनती है जो exponent को negative रखती है। यह अध्याय 2 का floating-point box अपना पहला debt collect कर रहा है, और दो sections बाद वह बड़ा debt collect करेगा।

Squared error क्यों नहीं, और जवाब gradient के बारे में क्यों है

सेक्शन का लिंक: Squared error क्यों नहीं, और जवाब gradient के बारे में क्यों है

Squared error की जगह cross-entropy को prefer करने की standard explanation ऊपर वाला likelihood argument है: squared error तब मिलता है जब आप Gaussian noise assume करते हैं, labels Gaussian नहीं होते, इसलिए ऐसा न करें। यह सही है और किसी को convince नहीं करता, क्योंकि आप sigmoid के ऊपर L=(py)2L = (p - y)^2 लिख सकते हैं और वह train हो जाएगा।

जो argument असर करता है, वह gradient के बारे में है। Sigmoid के ऊपर squared error लगाइए और chain rule देता है

Ls=2(py)p(1p)\frac{\partial L}{\partial s} = 2\,(p - y)\,p\,(1-p)

यह extra p(1p)p(1-p) वही है जो पहले cancel हुआ था। अब वह cancel नहीं होता, और जब भी model confident होता है, वह zero की ओर जाता है — तब भी जब model confidently गलत हो। दोनों को कुछ scores पर evaluate करें, एक ऐसे example के लिए जिसका true label 1 है:

score ssppcross-entropy L/s\partial L/\partial ssquared error L/s\partial L/\partial sratio
8-80.0003350.999665-0.9996650.000670-0.0006701,491
4-40.0179860.982014-0.9820140.034690-0.03469028.3
2-20.1192030.880797-0.8807970.184956-0.1849564.8
000.5000000.500000-0.5000000.250000-0.2500002.0
+2+20.8807970.119203-0.1192030.025031-0.0250314.8

s=8s = -8 पर model जितना गलत हो सकता है, उतना गलत है, और squared error cross-entropy की तुलना में 1,491 गुना छोटे gradient से response देता है। गलती जितनी बुरी, model उससे उतना कम सीखता है। Cross-entropy का gradient, meanwhile, 1-1 पर saturate होता है: maximally wrong एक maximally large signal produce करता है, उससे बड़ा नहीं।

Race चलाइए। दो हजार balanced points, identical starting weights जिन्हें confidently wrong चुना गया है (w=[6,6]\mathbf{w} = [-6, -6]), identical learning rate, सिर्फ loss अलग। दोनों runs cross-entropy से score किए गए हैं ताकि columns comparable रहें।

epochcross-entropy lossaccuracysquared-error lossaccuracy
15.48650.23005.94990.2290
101.55250.24605.90420.2290
500.46420.77805.69130.2320
1000.46390.77705.39550.2410
2000.46390.77704.63110.2745
5000.46390.77700.52910.7660
1,0000.46390.77700.46400.7765

Cross-entropy epoch 50 तक finish हो चुका है। Squared error epoch 100 पर अब भी 24 % accuracy पर है — और epoch 10 के 23 % से हिला नहीं था — guessing से भी खराब, क्योंकि वह confidently wrong शुरू हुआ था और उसे बचाने वाला gradient 0.0007 से multiply हो चुका था। वह लगभग epoch 500 पर निकलता है और उसी जगह land करता है। तो honest summary यह है कि sigmoid के ऊपर squared error incorrect नहीं है; वह ठीक वहां धीमा है जहां speed सबसे ज्यादा matter करती है। दो-parameter model पर आप 450 epochs खोते हैं। सौ layers वाले network में, जहां कहीं न कहीं कोई unit हमेशा confidently wrong होता है, आप training run खो देते हैं।

तीन quantities, जिन्हें अध्याय 8 में perplexity के लिए और अध्याय 11 में उस penalty के लिए सही तरह चाहिए जो fine-tuned policy को उसके reference के पास रखती है। ये अपनी reputation से आसान हैं।2

Entropy bits की average संख्या है जो आपको किसी distribution से draw communicate करने में खर्च करनी पड़ती है, अगर आप उसके लिए best possible code इस्तेमाल करें:

H(p)=ipilog2piH(p) = -\sum_i p_i \log_2 p_i

Cross-entropy वह खर्च है जब आप qq के लिए बने code को ऐसे data पर use करते हैं जो वास्तव में pp से आया है:

H(p,q)=ipilog2qiH(p, q) = -\sum_i p_i \log_2 q_i

KL divergence excess है — bits में waste — जो qq पर विश्वास करने से होता है जब truth pp है:

DKL(pq)=H(p,q)H(p)D_{\mathrm{KL}}(p \parallel q) = H(p,q) - H(p)

तीनों को belt पर check करें:

TEXT
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 bits

वहां दो चीजें दिखती हैं। पहली, जो model बस training base rate, 1.69 %, report करता है, वह 0.1330 bits की cross-entropy हासिल करता है, test labels की entropy के लगभग exactly बराबर — जैसा होना ही चाहिए, क्योंकि उसके पास सही distribution है और कोई other information नहीं। Entropy वह floor है जो ignorance-of-the-individual आपको खरीद कर देता है। दूसरी, जो model shrug करता है और 0.5 कहता है, वह exactly 1 bit pay करता है, और दोनों के बीच gap, 0.8671 bits, precisely KL divergence है। H+DKL=H(p,q)H + D_{\mathrm{KL}} = H(p,q) याद करने की identity नहीं है; यह bill है जिसे आप जुड़ते हुए देख सकते हैं।

और training से connection: जब label एक single known class हो, “true” distribution one-hot होता है, उसकी entropy zero होती है, और cross-entropy KL divergence के बराबर होता है। Cross-entropy minimise करना और model की distribution को truth की ओर खींचना वही एक act है।

दो से ज्यादा answers: softmax, और वह shift जिसकी कोई cost नहीं

सेक्शन का लिंक: दो से ज्यादा answers: softmax, और वह shift जिसकी कोई cost नहीं

Defective एक चीज नहीं है। Moulding में part short shot (material कम), flash (बहुत ज्यादा, mould से squeezed out), या burn के रूप में निकल सकता है। चार outcomes, इसलिए चार logits, और उन्हें चार probabilities में बदलना होगा जिनका sum one हो। यही softmax है:

softmax(z)i=ezijezj\operatorname{softmax}(\mathbf{z})_i = \frac{e^{z_i}}{\sum_j e^{z_j}}

इसकी एक property है जो accident जैसी दिखती है और असल में पूरी implementation है:

softmax(z+c)=softmax(z)\operatorname{softmax}(\mathbf{z} + c) = \operatorname{softmax}(\mathbf{z})

किसी भी constant cc के लिए, क्योंकि ezi+c=ecezie^{z_i + c} = e^{c} e^{z_i} और ece^c ऊपर और नीचे cancel हो जाता है। Logits के बीच सिर्फ differences का मतलब होता है। Absolute level information नहीं है।

अच्छा है, क्योंकि absolute level ही computer को तोड़ता है:

TEXT
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

e800e^{800} 64-bit float को overflow कर देता है, sum infinity बन जाता है, और infinity divided by infinity nan है — error नहीं, crash नहीं, बस एक silent hole जहां पहले तीन probabilities थीं। Maximum logit subtract करने से mathematically कुछ नहीं बदलता और numerically सब कुछ बदल जाता है, क्योंकि सबसे बड़ा exponent exactly e0=1e^0 = 1 बन जाता है। यह अध्याय 2 की logsumexp trick है, कामकाजी कपड़ों में, और हर serious implementation यही करती है:

softmax.pyPYTHON
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, b

Gradient फिर prediction minus truth है, अब YY one-hot के साथ। Binary case शुरू से ही special case था।

3,000 parts पर train और 1,000 पर test किया गया, हर part के तीन measurements (width, weight, melt temperature) के साथ, यह 94.00 % accuracy तक पहुंचता है। यह संख्या क्या छिपा रही है:

truth ↓ / predicted →okshort shotflashburnrecall
ok8505900.984
short shot2221000.488
flash2003010.588
burn300390.929
precision0.9500.8080.7690.975

Model आधे से भी कम short shots ढूंढता है। Accuracy यह नहीं देख सकती, क्योंकि 86 % parts ठीक हैं और उन्हें सही करना average को उठा ले जाने के लिए काफी है। Macro F1 — per-class F1 scores का mean, जो rare class को common class जितना ही weight देता है — 0.7983 है, जबकि micro F1 0.9400 है जो definition से accuracy के identical है। जब भी कोई एक F1 number report करे, पूछें कौन सा।

Modelling का हिस्सा यहीं खत्म। अध्याय का बाकी हिस्सा numbers के बारे में है।

Trained binary model लें और हर logit को constant से multiply करके दो variants बनाएं: hesitant version के लिए 0.35, overconfident version के लिए 4। Positive number से multiply करना कोई sign नहीं बदल सकता, इसलिए तीनों models सभी 4,000 test parts के लिए exactly वही label predict करते हैं। Accuracy उन्हें अलग नहीं कर सकती। Cross-entropy को कोई दिक्कत नहीं:

modelaccuracycross-entropyright होने पर mean losswrong होने पर mean lossworst single loss
hesitant (logits × 0.35)0.98300.15490.13691.19902.80
as trained0.98300.05640.01472.46897.82
overconfident (logits × 4)0.98300.15630.00099.142727.63

Hesitant model हर part पर छोटा tax देता है, उन हजारों पर भी जिन्हें वह सही करता है। Overconfident वाला right होने पर लगभग free है और wrong होने पर catastrophic — उस test set में एक part अकेले उसे 27.63 nats cost करता है। दोनों opposite routes से लगभग same total पर land करते हैं, और trained model, जिसकी probabilities data से calibrated हैं, दोनों से तीन गुना नीचे बैठता है।

यह loss और metric के बीच फर्क बताने का सबसे sharp तरीका है। Loss वह है जिसे आप optimise करते हैं: उसे differentiable होना चाहिए, और वह model ने जो भी कहा, सब देखता है, including वह कितना sure था। Metric वह है जिस पर आपको judge किया जाता है: वह step function, business rule, missed defects की count कुछ भी हो सकता है। वे same object नहीं हैं और हमेशा agree नहीं करते — इसलिए आप दोनों को शुरू करने से पहले define करते हैं, और loss को metric की जगह कभी नहीं खड़ा करते सिर्फ इसलिए कि वह screen पर दिख रहा है।

किसी भी model से पहले requirement: सबसे lazy possible answer क्या score करता है? इस belt पर, हमेशा fine कहो:

TEXT
always-say-fine baseline: accuracy = 0.9815
confusion (tn, fp, fn, tp) = (3926, 0, 74, 0)

98.15 %। अब trained logistic model, default threshold 0.5 पर:

TEXT
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 को percentage point के 0.15 से हराया, और जो report accuracy पर रुकती है वह इसे win कहेगी। Confusion matrix बताता है कि वास्तव में क्या हुआ:

predicted finepredicted defective
actually fine3,9242
actually defective668

उसने 74 में से 8 defective parts पाए और 66 को निकलने दिया। तीन numbers उस table को पढ़ने के तीन तरीकों के नाम हैं:

  • Precision =TP/(TP+FP)=8/10=0.800= \mathrm{TP}/(\mathrm{TP}+\mathrm{FP}) = 8/10 = 0.800। जिन parts को उसने flag किया, उनमें से कितने सच में defective थे। यह wasted inspections की cost है।
  • Recall =TP/(TP+FN)=8/74=0.108= \mathrm{TP}/(\mathrm{TP}+\mathrm{FN}) = 8/74 = 0.108। Defective parts में से उसने कितने पकड़े। यह customer तक bad part भेजने की cost है।
  • F1 =2PR/(P+R)=0.190= 2PR/(P+R) = 0.190, दोनों का harmonic mean, जो दोनों में छोटे वाले के पास रहता है और इसलिए सिर्फ एक से flatter होने से इंकार करता है।

क्या matter करता है यह factory पर depend करता है, mathematics पर नहीं: inspection में कुछ seconds लगते हैं और shipped defect recall notice cost करता है, इसलिए यहां recall dominates और 0.108 failure है।

लेकिन model problem नहीं है। Threshold है, और threshold model का हिस्सा नहीं — यह probability पर बाद में applied business decision है। इसे sweep करें:

thresholdTPFPFNaccuracyprecisionrecallF1
0.50082660.98300.8000.1080.190
0.2002728470.98120.4910.3650.419
0.10042118320.96250.2630.5680.359
0.05054236200.93600.1860.7300.297
0.0206757070.85580.1050.9050.188
0.005711,36030.65930.0500.9590.094

Accuracy column को नीचे पढ़ें। यह पूरे रास्ते गिरता है — 98.30 % से 65.93 % तक — जबकि model 8 defects पकड़ने से 74 में से 71 पकड़ने तक जाता है। यह model जो भी useful काम कर सकता है, वह उसकी accuracy को worse बनाता है। Headline number optimise करने वाली team वह version ship करेगी जो कुछ नहीं ढूंढता।

विवरण दिखाएँ

Class weighting signal create नहीं करती, operating point move करती है। Imbalanced classes के साथ usual first reflex है loss में rare class को weight करना। Positives पर 1, 10 और 60 के weights के साथ ऐसा करने पर:

positives पर weightaccuracyprecisionrecallF1AUC
10.98300.8000.1080.1900.9363
100.96050.2530.5810.3520.9361
600.82900.0910.9190.1660.9361

Precision और recall काफी दूर move करते हैं। AUC — यह probability कि model एक random defective part को random good part से ऊपर rank करेगा, जो threshold को पूरी तरह ignore करता है — 0.0002 से move करता है, यानी practically nothing। Reweighting ने वही model उसी trade-off curve पर slide किया। अक्सर यही आप चाहते हैं, और यह कभी new information नहीं होता: अगर ranking खराब है, तो कोई weighting scheme उसे बचा नहीं पाएगी।

तीन splits, और वह leak जिसे आप ढूंढने वाले हैं

सेक्शन का लिंक: तीन splits, और वह leak जिसे आप ढूंढने वाले हैं

तीन splits क्यों, दो क्यों नहीं? क्योंकि जिस क्षण आप examples के किसी set का उपयोग कुछ भी choose करने के लिए करते हैं — threshold, learning rate, छह models में से कौन ship करना है — वह set fitting के लिए use हो चुका है, और उसका score unbiased नहीं रहता।3 इस belt पर measured: validation set पर threshold sweep करने से 0.196 चुना जाता है, और फिर model untouched test set पर F1 = 0.4122 score करता है। अगर sweep सीधे test set पर चलाया गया होता, तो वहां best achievable 0.4186 था — एक ऐसी संख्या जिसे report करने का हक किसी को नहीं।

यहां gap छोटा है, 0.006, क्योंकि यह एक hyperparameter था जिसे 4,000 validation examples के against एक बार sweep किया गया। हर extra decision और validation set के हर shrink के साथ यह बढ़ता है। यह भी note करें कि single run में direction guaranteed नहीं: chosen threshold ने validation पर 0.3902 और test पर 0.4122 score किया, इसलिए validation ने इस बार उसे understate किया। Bias many decisions में systematic है, किसी एक में visible नहीं।4

अब exercise। Belt log एक third column, station_seconds, के साथ आता है: inspection station पर हर part ने कितना समय बिताया। इसे जोड़ना preprocessing में one-line change है। यह क्या करता है:

modelaccuracyprecisionrecallF1cross-entropyAUC
width + weight0.98300.8000.1080.1900.05640.9363
+ station_seconds0.99200.7920.7700.7810.02360.9970

Recall 10.8 % से 77.0 % हो जाता है। F1 चार गुना से ज्यादा हो जाता है। और देखें accuracy ने क्या किया: 98.30 % → 99.20 %, point के नौ tenths का gain, ऐसा number जिसे summary slide में “about 99 % either way” round कर दिया जाता है। Accuracy पहले failure देखने में fail हुई और अब fraud देखने में fail होती है।

आगे पढ़ने से पहले: model cheating कर रहा है। पता लगाइए कैसे।

Leak कैसे hunt करें, उस order में जो इसे सबसे तेजी से ढूंढता है।

  1. Train और test compare करें। Overfitting बड़ा gap बनकर दिखता है। यहां: honest model 0.9838 train / 0.9830 test; leaky model 0.9936 train / 0.9920 test। दोनों gaps 0.2 points से कम हैं। Leak overfitting जैसा नहीं दिखता — leaky feature test time पर भी उतना ही available है, इसलिए model एक ऐसी दुनिया में खूबसूरती से generalise करता है जो exist नहीं करती।

  2. हर feature पर अकेले एक model train करें। जो भी answer carry करता है, खुद announce कर देगा:

    feature aloneaccuracyrecallF1AUC
    width0.98150.0140.0260.8691
    weight0.98150.0000.0000.7914
    station_seconds0.98500.4050.5000.9960

    एक column, अकेले, defects को AUC 0.9960 पर rank करता है। Caliper और scale से लिए गए दो measurements 0.87 और 0.79 manage करते हैं। यही asymmetry alarm है।

  3. पूछें हर number कब लिखा गया था। Mean dwell time: pass हुए parts के लिए 2.23 seconds, fail हुए parts के लिए 15.56 seconds। जाहिर है। Part station पर इसलिए रुकता है क्योंकि inspector ने उसे belt से हटाया — जो बाद में होता है, और सिर्फ इसलिए होता है कि किसी ने decide किया वह defective था। Column part का measurement नहीं है। वह verdict का measurement है।

the planted leakPYTHON
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())  

Highlighted line leak है: defective part का dwell time अलग distribution से drawn है, क्योंकि human ने उसे belt से हटाया। Applied machine learning में यह सबसे common serious bug है, और इसका नाम है: target leakage — training features में ऐसी information जो उस moment available नहीं होगी जब prediction करनी है।5 यह कोई exception नहीं फेंकता। यह बेहतर number produce करता है। Project में हर incentive इसे रखने की तरफ इशारा करता है।

Defence एक सवाल है, हर column से पूछा जाने वाला: जिस instant मुझे यह prediction चाहिए, क्या यह value अभी exist करती है? Live belt पर, station_seconds unknown है जब तक part inspect नहीं हो जाता — और model को इसी चीज को replace करना था।

मान लीजिए आप model को 20 examples पर score करते हैं और वह 17 सही करता है। आप 85 % report करते हैं।

TEXT
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.6477

17/20 की honest reading है कहीं 64 % और 95 % के बीच। एक genuinely 65 % model यह result 4.4 % बार produce करता है — तेईस में एक run — और अगर आपने handful of prompts try किए और best report किया, तो आपने वह run खुद manufacture किया। बीस में सत्रह एक 85 % model को 65 % वाले से distinguish नहीं कर सकता।

Rate पर interval लगाने के दो तरीके, और दोनों आपके toolkit में होने चाहिए:

uncertainty.pyPYTHON
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)

Plain success rate के लिए Wilson6 use करें; यह किसी भी nn पर well behaved रहता है और randomness नहीं मांगता। ऊपर note करें कि n=20n = 20 पर bootstrap का upper end 1.0000 है — 20 points resample करना आसानी से 20 correct draw कर सकता है, इसलिए यह अपनी granularity से narrower interval represent नहीं कर सकता। Bootstrap7 वहां use करें जहां formula मौजूद नहीं, यानी most interesting cases: F1, macro-averages, BLEU, pass@1, rubric-based judge का score। इस belt पर, tuned model के 0.4122 F1 का bootstrap interval [0.3009, 0.5156] है — यही number report में दिखना चाहिए, क्योंकि point estimate alone ऐसी comparison invite करता है जिसे वह support नहीं कर सकता।

एक और measurement, क्योंकि यह बदलता है कि आपको दो models कैसे compare करने चाहिए। Same 500 examples पर score किए गए दो models:

TEXT
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)

उनके intervals overlap करते हैं, और folk rule — overlapping error bars means no significant difference — comparison को inconclusive कहेगा। ऐसा नहीं है। दोनों models same examples पर चले, इसलिए सही quantity per-example difference है, जिसका interval [0.0260, 0.0680] है, आराम से zero से ऊपर। वे 500 items में से सिर्फ 31 पर disagree करते हैं, और A उन disagreements में 27 जीतता है; shared examples, easy और hard दोनों, noise जोड़ने के बजाय cancel हो जाते हैं। Models को paired compare करें, और आप data के fraction से वही conclusion पा लेते हैं।

अब आपके पास एक model है जो calibrated probabilities output करता है, एक loss जो convenience के लिए चुना नहीं गया बल्कि data के बारे में claim से derived है, एक gradient जो literally prediction minus truth है, और — ज्यादा important — यह पता लगाने की machinery कि इनमें से कुछ काम करता भी है या नहीं। ऊपर का ten-line Wilson interval verbatim reuse होता है: यह अध्याय 15 में prompt variants, अध्याय 19 में retrieval tables, और अध्याय 29 में golden set को carry करता है। जब कोई formula मौजूद न हो, bootstrap वही है जिसके लिए आप हाथ बढ़ाते हैं।

लेकिन model अब भी one layer है। वह line draw करता है, और अध्याय 1 ने XOR की चार rows से साबित किया था कि line enough नहीं है। Fix है stack करना: first layer जो space को bend करती है, second जो bent space में line draw करती है।

यहीं इस अध्याय का tidy gradient खत्म हो जाता है। ऊपर सब इसलिए काम किया क्योंकि L/s=py\partial L/\partial s = p - y को hand से, एक बार, ऐसे model के लिए लिखा जा सकता था जिसमें input और loss के बीच एक layer थी। बीच में second layer रखिए और सवाल shape बदल देता है: loss की derivative ऐसे weight के respect में क्या है जो output को बिल्कुल touch नहीं करता — जिसका influence केवल दूसरी layer के through आता है, शायद कई paths पर एक साथ?

वह derivative exists करती है। Toy से बड़े किसी भी model के लिए उसे हाथ से compute करना hopeless है, और उसे एक समय में एक parameter के लिए compute करना अलग scale पर hopeless है। जरूरत है एक ऐसी procedure की जो network की हर derivative को उसी graph पर single backward pass से निकाल दे जिस पर forward pass अभी चला था।

यही अध्याय 5 है, और यही engine है जिस पर इस course का बाकी हिस्सा चलता है।


इस अध्याय के साथ पढ़ने लायक भी: Bishop, Pattern Recognition and Machine Learning §1.2, §1.5, §1.6 और §4.3, जो probability, decision theory, information theory और linear classification को उसी order में cover करता है जिसका यह अध्याय follow करता है; Murphy, Probabilistic Machine Learning: An Introduction, chapters 6 और 10; Prince, Understanding Deep Learning §5.4–5.7; और Saito और Rehmsmeier, The Precision-Recall Plot Is More Informative than the ROC Plot When Evaluating Binary Classifiers on Imbalanced Datasets (PLOS ONE, 2015) — क्यों ऊपर quoted AUC अकेला threshold-free number नहीं होना चाहिए जिसे आप देखें जब 1.7 % parts defective हों।

  1. Ma, T. और Ng, A. CS229 Lecture Notes, Stanford University, chapters 2 और 3। जहां pyp - y produce करने वाला cancellation luck जैसा दिखना बंद करता है: अपने output से match करने वाली exponential-family distribution चुनें, उसका canonical link use करें, और gradient हमेशा prediction minus truth होता है।

  2. Olah, C. Visual Information Theory (2015), colah.github.io/posts/2015-09-Visual-Information। Entropy, cross-entropy और KL divergence को formulas के बजाय bits में costs की तरह समझाने वाला सबसे clear available account।

  3. Abu-Mostafa, Y. S., Magdon-Ismail, M. और Lin, H.-T. Learning From Data (AMLBook, 2012), Caltech course के lectures 13 और 17। Lecture 13 validation है; lecture 17, तीन learning principles पर, वह जगह है जहां data snooping को नाम दिया गया है। दोनों मिलकर इस अध्याय की discipline का source हैं: data set पर हर नजर fitting decision है, चाहे आपने optimiser चलाया हो या नहीं।

  4. James, G., Witten, D., Hastie, T. और Tibshirani, R. An Introduction to Statistical Learning, 2nd edition (Springer, 2021), chapters 2 और 5, bias–variance decomposition और resampling के लिए। Companion volume वह जगह है जहां selection trap सीधे कही गई है: Hastie, Tibshirani और Friedman, The Elements of Statistical Learning, 2nd edition, §7.10.2, The Wrong and Right Way to Do Cross-validation

  5. Kaufman, S., Rosset, S., Perlich, C. और Stitelman, O. Leakage in Data Mining: Formulation, Detection, and Avoidance. ACM Transactions on Knowledge Discovery from Data 6(4), 2012। ऊपर demonstrated failure का formal treatment, competitions की case studies के साथ जिन्हें ऐसे model ने जीता था जिसने यह artefact सीख लिया था कि data assemble कैसे किया गया।

  6. Wilson, E. B. Probable Inference, the Law of Succession, and Statistical Inference. Journal of the American Statistical Association 22(158), pp. 209–212 (1927)। ऊपर wilson() में used score interval, proportion के लिए अब भी right default। Textbook interval p^±zp^(1p^)/n\hat{p} \pm z\sqrt{\hat{p}(1-\hat{p})/n} वह है जिससे बचना चाहिए: यह 0 और 1 के पास nonsense देता है, और छोटे nn पर badly undercovers करता है।

  7. Efron, B. Bootstrap Methods: Another Look at the Jackknife. The Annals of Statistics 7(1), pp. 1–26 (1979)। वह idea जो आपको compute की जा सकने वाली किसी भी statistic पर interval लगाने देता है, including वे जिनकी sampling theory नहीं है।

मॉडल चुनने का काम LIA पर छोड़ने के लिए तैयार हैं?

हर AI मॉडल एक ही जगह — आज ही मुफ़्त शुरू करें।