<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Intuitive ML]]></title><description><![CDATA[I'm learning ML/AI, and like many of you, I've sat through lectures that left me more confused than when I started. This blog is my attempt to make sense of it ]]></description><link>https://intuitiveml.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Intuitive ML</title><link>https://intuitiveml.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 18:32:01 GMT</lastBuildDate><atom:link href="https://intuitiveml.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Tigers, Ghosting, and Bayes' Theorem]]></title><description><![CDATA[Tigers, Ghosting, and Bayes' Theorem
Prior, likelihood, posterior — and the tug-of-war between them, built from scratch
You jolt awake in the dark and hear a tiger roar.
For about half a second, what ]]></description><link>https://intuitiveml.hashnode.dev/tigers-ghosting-and-bayes-theorem</link><guid isPermaLink="true">https://intuitiveml.hashnode.dev/tigers-ghosting-and-bayes-theorem</guid><category><![CDATA[#BayesTheorem]]></category><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[Wei Rui]]></dc:creator><pubDate>Thu, 11 Jun 2026 04:33:36 GMT</pubDate><content:encoded><![CDATA[<h1>Tigers, Ghosting, and Bayes' Theorem</h1>
<h3>Prior, likelihood, posterior — and the tug-of-war between them, built from scratch</h3>
<p>You jolt awake in the dark and hear a tiger roar.</p>
<p>For about half a second, what you do next depends entirely on one thing: where you are. If you're three nights into a temple stay in the forested hills of northern Thailand and it's the middle of the night, your blood runs cold — that's a <em>tiger</em>, and it is close. If you dozed off on the couch on a Sunday evening and your partner is in the next room, you don't even open your eyes — it must be the TV.</p>
<p>Same sound. Opposite reactions. The roar didn't tell you which one it was; <em>what you already knew</em> — call it your <strong>prior</strong> — did. You just ran a Bayesian inference and didn't notice. This article is a look under the hood of the thing your brain was already doing.</p>
<p>Here's the whole idea in one sentence:</p>
<p><strong>Belief is a tug-of-war between your history and your headlines — and every fresh clue restarts the match.</strong></p>
<p>Let's pull that apart with two tigers, a vanishing match, three doors, and a speeding ticket from the wrong continent.</p>
<hr />
<h2>A low prior isn't a veto: the tiger you can't deny</h2>
<p>Back on that couch, the roar fit "real tiger" perfectly and you <em>still</em> didn't believe it — because a live tiger in your living room is essentially impossible. But what if you wake up in a trashed Vegas hotel room, like in <em>The Hangover</em>, and there's a full-grown tiger in the bathroom? The prior on that is so low it's literally the joke of the movie. By your couch logic, you should dismiss it.</p>
<p>Except, you can't. The evidence is overwhelming: four hundred pounds of striped cat, growling, and you can <em>smell</em> it. Ask how perfectly a real tiger explains those clues versus any innocent alternative, and the probability is basically 100%. The evidence is so lopsided it steamrolls the tiny prior, and your belief swings all the way to <em>yes — impossible as it sounds — there really is a tiger.</em></p>
<p>This is the other end of the seesaw: <strong>extraordinary claims require extraordinary evidence.</strong> A low prior isn't a wall, it's a weight — pile on enough evidence and you tip it. It's the same machine you ran on the couch, settling the opposite way: the tiger you can't see (a roar in the dark, weak evidence, the prior wins) and the tiger you can't deny (four hundred pounds in the bathroom, crushing evidence, the prior loses).</p>
<p>So your gut is always weighing two forces: how plausible a story was to begin with, and how well it explains what you just saw. Now watch the brain fumble that weighing in the subject as messy as: ghosting.</p>
<hr />
<h2>Two arrows that point opposite ways</h2>
<p>These days, online dating hands almost everyone this exact story. You match, you go out, and then — nothing. They vanish. After a day of refreshing the thread, your gut has already filed the obituary: <em>they ghosted, so they're done with me</em> — and quietly decided the silence is a fact about you.</p>
<p>Your gut jumped straight to that conclusion because it confuses two completely different questions:</p>
<ol>
<li>The question you generally know the answer to: If someone is genuinely not into you, how likely are they to go silent? Pretty high - let's call it 90%.</li>
<li>The question you should actually care about: If someone goes silent, what is the probability that they are still into you?</li>
</ol>
<p> </p>
<p>To flip this around and answer the second question, you can't just copy and paste the 90% backward. You have to realize that even if they are genuinely into you, but life explodes (a family emergency, a dead phone, a brutal work week), they might still go quiet - call it 10%.</p>
<p>$$P(\text{ghost} \mid \text{not into you}) = 0.90$$</p>
<p>$$P(\text{ghost} \mid \text{into you}) = 0.10$$</p>
<p>To answer the second question, you need your starting line — the prior: how sure were you they liked you before the silence? Watch what happens when you run the exact same ghost through two different priors.</p>
<p><strong>The lukewarm date.</strong> It was fine, a little stiff; you came home calling it a coin flip — a prior of 50%.</p>
<p>$$P(\text{into you} \mid \text{ghost}) = \frac{0.10 \times 0.50}{0.10 \times 0.50 + 0.90 \times 0.50} = \frac{0.05}{0.50} = 10%$$</p>
<p>The ghost is a heavy weight, and with nothing to counterbalance it, it drags your 50/50 down to <strong>10%</strong>. The obituary was right — move on.</p>
<p><strong>The sparks-flying date.</strong> They chased you first, the conversation never stalled, they texted from the cab home and floated a second date. You were sure — a prior of 90%. Same silence, new starting line:</p>
<p>$$P(\text{into you} \mid \text{ghost}) = \frac{0.10 \times 0.90}{0.10 \times 0.90 + 0.90 \times 0.10} = \frac{0.09}{0.18} = 50%$$</p>
<p>You don't crash to 10% — you land on a <strong>coin flip</strong>. The math is saying the silence is a bad sign, sure, but a sudden ghost <em>after</em> that much enthusiasm is contradictory enough that "they lost their phone" is just as plausible as "they faked the whole night."</p>
<p>That's the real power of the machine: read the arrow the right way, weigh it by the prior, and let the math tell you when to move on — and when it's still a coin flip. Time to give the machine its proper name.</p>
<hr />
<h2>Naming the machine: prior, posterior, and the timeline</h2>
<p>Every example so far started from a belief you held <em>before</em> the new evidence arrived — your hunch on the couch, your read on the date. That starting point has a name: the <strong>prior</strong>, <em>P(θ)</em>. The belief you land on <em>after</em> the evidence lands has one too — the <strong>posterior</strong>, <em>P(θ | X)</em>. And here's the part the textbook vocabulary fumbles. <em>Prior</em> and <em>posterior</em> aren't about cause and effect, or about the order things happened in the world. They mark a single moment on <em>your</em> timeline: <strong>the instant you saw the new evidence</strong> — your belief just before it, and just after.</p>
<p><strong>Prior</strong> <em>(what you knew before)</em> → new evidence arrives → <strong>Posterior</strong> <em>(what you know now)</em></p>
<p><em>Prior</em> = your belief before this batch of data. <em>Posterior</em> = your belief after. The only referee deciding which label applies is the question "have you looked at the evidence yet?" That's the entire distinction. A stranger walks up; before they move, you'd put them at maybe 10% left-handed — prior. They sign a receipt with their left hand — evidence. Now you'd say 99% — posterior. Same belief, photographed on two sides of one observation.</p>
<p>Drop all three pieces into their slots and you get the famous formula:</p>
<p>$$P(\theta \mid X) = \frac{P(X \mid \theta), P(\theta)}{P(X)}$$</p>
<p>In plain words:</p>
<p>$$\text{posterior} = \frac{\text{likelihood} \times \text{prior}}{\text{evidence}}$$</p>
<p>The numerator is the <em>fit × prior</em> we've been multiplying by hand all along. The denominator, <em>P(X)</em>, is the only new face — but before we put it under the microscope, let's watch the whole formula compute a real answer.</p>
<hr />
<h2>Monty Hall, run through the machine</h2>
<p>Now the puzzle that humbles everyone. Three doors: a car behind one, goats behind the other two. You pick door A. The host — who <em>knows</em> where the car is and <em>deliberately</em> avoids it — opens door C to reveal a goat, then offers to let you switch to B. Should you?</p>
<p>Before touching the algebra, prime your intuition by blowing it up to <strong>100 doors.</strong> You pick one — a 1% shot. The host throws open 98 goat doors, leaving a single other door shut. Did you nail it on a 1-in-100 guess, or is the car behind the one door he carefully refused to touch? You switch without blinking. Three doors is the exact same story, just quieter — here's the machinery that makes it true.</p>
<p>Define the causes (where the car is): <em>A</em>, <em>B</em>, <em>C</em>. Define the evidence: <em>D</em> = "the host opened door C."</p>
<p><strong>Priors</strong> — before anything, the car is equally likely anywhere:</p>
<p>$$P(A) = P(B) = P(C) = \tfrac{1}{3}$$</p>
<p><strong>Likelihoods</strong> — given the car's location, how likely was the host to open exactly C? This is where all the magic hides. The host's brain contains the answer, and his rules force him to leak it into the room: he cannot touch your door, and he cannot touch the car. His hands are tied by reality — so every door he opens is a quiet confession.</p>
<ul>
<li><p>Car behind A: B and C are both goats, he picks freely → <em>P(D | A) = 1/2</em></p>
</li>
<li><p>Car behind B: your door A is off-limits, the car at B is off-limits, so he's <em>forced</em> to open C → <em>P(D | B) = 1</em></p>
</li>
<li><p>Car behind C: he'd never open the car → <em>P(D | C) = 0</em></p>
</li>
</ul>
<p><strong>The denominator</strong> — total chance he opens C, across all worlds:</p>
<p>$$P(D) = \tfrac{1}{2}\cdot\tfrac{1}{3} + 1\cdot\tfrac{1}{3} + 0\cdot\tfrac{1}{3} = \tfrac{1}{6} + \tfrac{2}{6} + 0 = \tfrac{1}{2}$$</p>
<p><strong>Posteriors:</strong></p>
<p>$$P(A \mid D) = \frac{\tfrac{1}{2}\cdot\tfrac{1}{3}}{\tfrac{1}{2}} = \frac{1}{3}$$</p>
<p>$$P(B \mid D) = \frac{1\cdot\tfrac{1}{3}}{\tfrac{1}{2}} = \frac{2}{3}$$</p>
<p>There it is. Your door stays frozen at <em>1/3</em>: when the car was behind A, the host opening C was just a coin flip that told you nothing special about A. But door B inherits the full <em>2/3</em>, because if the car were behind B the host was <em>forced</em> to expose C — and a forced move is a 100% endorsement. The likelihood <em>P(D | B) = 1</em> is the whole story. <strong>Always switch.</strong></p>
<p>And the whole thing hinges on the host <em>knowing</em>. If a clueless stagehand had flung open door C at random and it happened to be a goat, the forced move evaporates: <em>P(D | B)</em> falls from 1 back to <em>1/2</em>, the likelihoods go flat, and switching gains you nothing — it really would be 50/50. The <em>2/3</em> isn't created by a door being opened; it's created by a door opened <em>on purpose</em> by someone who was avoiding the car. Intent is the hidden variable doing all the work.</p>
<hr />
<h2>The denominator, and a spam filter that never computes it</h2>
<p>Monty Hall just made you compute the bottom of the fraction — <em>P(D) = 1/2</em>, the total chance the host opens door C. It has an intimidating name, <strong>marginal likelihood</strong>, and a humble job: the total probability of seeing the evidence <em>at all</em>, added up across every possible cause.</p>
<p>$$P(X) = \sum_{\theta} P(X \mid \theta), P(\theta)$$</p>
<p>Picture it as the total area of a dartboard. The numerator — <em>fit × prior</em> — is the single wedge you actually care about; the denominator is the whole board. Dividing by it is a pure <strong>normalizer</strong> that rescales your raw scores so they add up to 100%. And because it's the <em>same number</em> dividing every suspect, it never changes which cause is biggest.</p>
<p>That is the ultimate loophole. If all you want is <em>which cause wins</em>, you can skip the denominator entirely and compare numerators:</p>
<p>$$P(\theta \mid X) ;\propto; P(X \mid \theta), P(\theta)$$</p>
<p>Monty <em>did</em> need the real denominator — to land on exact odds of 1/3 versus 2/3 — but plenty of machines don't care about exact odds at all. They just need to rank, and for ranking, that unnormalized score is all you ever need.</p>
<p>Every time your inbox swallows a scam before you lay eyes on it, it's exploiting this exact loophole — the same comparison, played over words instead of doors. We'll classify an email containing the words <strong>"prize"</strong> and <strong>"free"</strong> without ever touching the denominator.</p>
<p>Our prior experience: ten past emails, five spam and five normal — an even prior split, <em>P(spam) = P(normal) = 0.5</em>. Within those, how often each word turns up:</p>
<p>$$P(\text{prize} \mid \text{spam}) = 0.80, ;; P(\text{free} \mid \text{spam}) = 0.60$$</p>
<p>$$P(\text{prize} \mid \text{normal}) = 0.20, ;; P(\text{free} \mid \text{normal}) = 0.01$$</p>
<p>(That last one is really <em>0/5 = 0</em>, but a single zero would annihilate the whole product, so we nudge it up — the standard add-one smoothing trick.)</p>
<p>The word <em>naive</em> in <strong>Naive Bayes</strong> is the assumption that the words appear independently, which lets us just multiply their likelihoods. We compute the numerator — <em>fit × prior</em> — for each side:</p>
<p>$$\text{score}(\text{spam}) = 0.80 \times 0.60 \times 0.50 = 0.24$$</p>
<p>$$\text{score}(\text{normal}) = 0.20 \times 0.01 \times 0.50 = 0.001$$</p>
<p>The score 0.24 utterly buries 0.001, so into the spam folder it goes. The computer never learned the <em>exact</em> probability that the email is spam, because computing the denominator — counting how often "prize" and "free" co-occur across all email everywhere — is a genuine computational monster. By dropping the bottom of the fraction, the classifier runs hundreds of times faster.</p>
<hr />
<h2>One more thing: today's posterior is tomorrow's prior</h2>
<p>Here's the move that turns a static formula into something alive. Evidence rarely arrives all at once; it trickles in, one clue at a time. And the Bayesian update has a beautiful recursive property — <strong>the posterior you land on today becomes the prior you start with tomorrow.</strong> Let me tell it as a story, because you've felt this one.</p>
<p>You're in San Francisco. Flipping through the day's mail, you find an official-looking envelope — a <strong>speeding ticket from the city of Sydney, Australia.</strong> Your immediate read: scam. The prior on "a real Sydney traffic fine, addressed to me, in California" is rock bottom; a scam or a billing mix-up is the overwhelming base rate. The letter is halfway to the recycling bin.</p>
<p>Then a memory surfaces: <em>you were in Sydney a month ago. You rented a car.</em> That isn't new evidence about this letter — your brain just rapidly corrected its <strong>prior</strong>. The base rate clicks into place, and suddenly a real fine is entirely plausible. The thing you were about to trash is now a maybe.</p>
<p>The next day, a second notice lands — this time an email from the <strong>rental company</strong>, referencing the violation, your booking number, the date. <em>This</em> is the new evidence — specific and corroborating. The posterior swings to near-certainty: it's real, and you owe Sydney money.</p>
<p>Feel the shape of that? <em>Scam → wait, maybe → oh no, definitely.</em> Your belief climbed a staircase, and every step started from where the last one left off — yesterday's conclusion was today's starting line. That's not three separate judgments; it's one belief, updated step by step. You were running the spam filter from the last section — on yourself, live, in real time.</p>
<p>That rolling update is the quiet engine under a startling amount of modern AI. A self-driving car's radar doesn't call "obstacle" off one ping; it sweeps again and again, each sweep refining the last until certainty crosses a threshold and the brakes engage.</p>
<p>It's also why arguing on the internet is so famously useless. When two people read the exact same piece of breaking news and walk away with opposite convictions, they usually aren't misreading the data — the evidence is identical for both of them. They just started from radically different priors, and Bayes' theorem faithfully carries the same evidence to two different horizons. Strong priors barely move under weak evidence; that's not a bug in their reasoning, it's the math working exactly as designed. The machine isn't broken. It's just being run from two different starting lines — which is all a <em>perspective</em> really is: the prior you walk in with, before the evidence says a word.</p>
<p>So the next time you hear a sound through a wall and your fear adjusts itself before you're even fully awake — or you talk yourself out of reading a verdict into someone's silence, or you finally believe the absurd thing because the evidence won't stop piling up — give yourself some credit. You're running the same loop that powers the spam filter, the self-driving car, and the puzzle that fools game-show contestants. You were a Bayesian all along.</p>
]]></content:encoded></item><item><title><![CDATA[Logistic Regression is Just Linear Regression with a Midlife Crisis]]></title><description><![CDATA[Logistic Regression is Just Linear Regression with a Midlife Crisis
The intuition behind logistic regression, built from scratch
If you've been learning machine learning, you've probably experienced t]]></description><link>https://intuitiveml.hashnode.dev/logistic-regression-is-just-linear-regression-with-a-midlife-crisis</link><guid isPermaLink="true">https://intuitiveml.hashnode.dev/logistic-regression-is-just-linear-regression-with-a-midlife-crisis</guid><dc:creator><![CDATA[Wei Rui]]></dc:creator><pubDate>Mon, 25 May 2026 23:58:47 GMT</pubDate><content:encoded><![CDATA[<h1>Logistic Regression is Just Linear Regression with a Midlife Crisis</h1>
<h3>The intuition behind logistic regression, built from scratch</h3>
<p>If you've been learning machine learning, you've probably experienced this exact frustration: a course smoothly explains Linear Regression, then classification arrives and suddenly a barrage of new terms appears out of nowhere — Sigmoid functions, Cross-Entropy loss, Maximum Likelihood Estimation — with the instructor diving straight into calculus without explaining why any of it was needed in the first place.</p>
<p>Here's the thing: machine learning isn't a collection of random formulas. It's a series of elegant solutions to very practical problems. Every single piece of logistic regression was <em>forced</em> into existence by one stubborn goal: <strong>making linear regression do something it was never designed to do — classify things.</strong></p>
<p>This article traces that journey from beginning to end. By the time you're done, you won't just know <em>what</em> logistic regression is. You'll understand why it couldn't have been built any other way.</p>
<hr />
<h2>The Setup: We Want to Classify</h2>
<p>Let's use a spam email detector as our running example. We have a bunch of emails, and for each one we've counted the number of flagged keywords ("free", "urgent", "winner", etc.). We want to predict whether an email is Spam (yes or no).</p>
<p>We encode the target as a number: <strong>1 = Spam, 0 = Not Spam.</strong> This is just a special case of one-hot encoding — binary edition.</p>
<p>Now we have a perfectly normal-looking dataset: numbers in, numbers out. So the obvious first question is: can we just throw linear regression at it?</p>
<hr />
<h2>Attempt #1: Linear Regression</h2>
<p>Linear regression gives us:</p>
<p>$$z = wx + b$$</p>
<p>where <em>x</em> is the flagged keyword count, and <em>w</em> and <em>b</em> are the parameters we train.</p>
<p>This <em>kind of</em> works. If you fit a line through the 0s and 1s, it'll lean toward 1 in the spammy region and toward 0 everywhere else. You can even set a threshold — if <em>z &gt; 0.5</em>, predict Spam — and it won't be terrible.</p>
<p>Think of it this way: if the model outputs <em>z = 1.8</em>, that's closer to 1 than to 0, so we call it Spam. If it outputs <em>z = -0.2</em>, that's closer to 0, so we call it Not Spam. Setting the cutoff at 0.5 is just formalizing that intuition — anything above, round up to 1; anything below, round down to 0.</p>
<p>It's crude, but it's not crazy. The problem is that these numbers — 1.8, -0.2 — don't <em>mean</em> anything. They're not probabilities. What does "180% chance of being spam" mean? Nothing. You can't say "I'm 73% sure this is spam" — you can only say "the score is 0.73, and I've decided 0.5 is my cutoff." There's nothing stopping the output from flying off to arbitrarily large or small values, with no natural interpretation attached.</p>
<p>As humans, we are always seeking meaning. Wouldn't it be nice if the output is a real probability — a number that lives cleanly between 0 and 1, no matter what?</p>
<hr />
<h2>The First Patch: Sigmoid</h2>
<p>So we need a <strong>probability compressor</strong> — a function that takes any real number from \( (-\infty, +\infty) \) and squashes it into <em>(0, 1)</em>.</p>
<p>Here's where it gets interesting: this function <em>wasn't guessed</em>. It was derived from a simple question.</p>
<p>Instead of directly modeling the probability <em>P</em>, ask: <strong>what if we model the log-odds?</strong></p>
<p>The odds of an event are \( \frac{P}{1-P} \) — how many times more likely is "yes" than "no." Odds live in \( (0, +\infty) \). Take the log, and they live in \( (-\infty, +\infty) \) — exactly the same range as our linear model's output.</p>
<p>So we set them equal:</p>
<p>$$\log \frac{P}{1-P} = wx + b = z$$</p>
<p>Now solve for <em>P</em>:</p>
<p>$$P = \frac{1}{1 + e^{-z}}$$</p>
<p>That's the <strong>sigmoid function</strong>, written as \( \sigma(z) \). It wasn't invented — it was discovered, by asking what probability function naturally pairs with a linear model.</p>
<p>The name comes from the Greek letter sigma (σ), which is just the Greek S. Plot the function and you'll see why: it traces a perfect S-curve, flat near 0 for very negative inputs, rising steeply through the middle, then flattening again near 1 for very positive inputs. Sigmoid literally means "S-shaped."</p>
<p>Plug any <em>z</em> into it: <em>z = 0</em> gives <em>P = 0.5</em>, large positive <em>z</em> gives <em>P</em> close to 1, large negative <em>z</em> gives <em>P</em> close to 0. It always stays between 0 and 1, and it's smooth all the way through.</p>
<hr />
<h2>Logistic Regression is Born</h2>
<p>We now have our upgraded model:</p>
<p>$$\hat{y} = \sigma(wx + b) = \frac{1}{1 + e^{-(wx+b)}}$$</p>
<p>Notice what <em>didn't</em> change: we're still training exactly the same parameters, <em>w</em> and <em>b</em>. The sigmoid is just a fixed conversion layer — it has no parameters of its own.</p>
<p>What changed is the interpretation. The linear part <em>z = wx + b</em> is no longer trying to approximate a 0 or 1 label directly. It's now computing a <strong>score</strong> — a raw measure of "how spammy is this email?" The sigmoid then translates that score into a probability.</p>
<p>This thing is called <strong>logistic regression</strong>. It's linear regression underneath, wearing a sigmoid on top.</p>
<hr />
<h2>Attempt #2: Keep MSE as the Loss Function</h2>
<p>We have a model that outputs probabilities. Now we need a way to score how good it is — a loss function.</p>
<p>The obvious move: keep using Mean Squared Error (MSE), the same loss we used in linear regression.</p>
<p>$$L_{\text{MSE}} = (\hat{y} - y)^2$$</p>
<p>Seems reasonable. But there's a hidden disaster waiting.</p>
<p>To train the model, we update <em>w</em> and <em>b</em> using gradient descent: nudge each parameter in the direction that reduces the loss. To know which direction, we compute the gradient — the derivative of the loss with respect to <em>w</em> and <em>b</em>.</p>
<p>Using the chain rule:</p>
<p>$$\frac{\partial L}{\partial w} = 2(\hat{y} - y) \cdot \sigma(z)(1 - \sigma(z)) \cdot x$$
$$\frac{\partial L}{\partial b} = 2(\hat{y} - y) \cdot \sigma(z)(1 - \sigma(z)) $$</p>
<p>The three terms are: how wrong the model is, the sigmoid's derivative, and the input <em>x</em>. Here's the problem: <strong>the sigmoid's derivative term goes to zero whenever <em>z</em> is very large or very small.</strong></p>
<p>Think about what that means. Look at the shape of the sigmoid curve: it's steep in the middle, but completely flat at both extreme ends. When the model is catastrophically wrong — say it's 99% confident that a spam email is Not Spam — <em>z</em> is a large negative number, sitting at the flat left end of the curve. The sigmoid's derivative at that point is essentially 0. Multiply that into the gradient and the whole thing collapses to zero.</p>
<p>The model is most wrong, and the gradient is telling it to do <em>nothing</em>. This is called <strong>gradient vanishing</strong>.</p>
<p>Here's why it's so damaging. Gradient descent works by asking at every step: "which direction should I nudge <em>w</em> and <em>b</em> to reduce the loss?" The gradient is the answer — it's the compass. When the gradient vanishes, the compass goes dead. The optimizer looks around, sees flat terrain in every direction, and concludes "I must be at the bottom" — even though it's actually stranded on a plateau far from the true minimum. Training stops, locked into terrible parameters, with no way to know anything is wrong.</p>
<p>The cruel irony is <em>when</em> this happens. The gradient vanishes precisely when the model is most confidently wrong — when it deserves the harshest correction, it gets none at all.</p>
<p>The reason it happens is structural: MSE and sigmoid don't fit together. MSE was designed for unbounded outputs; the sigmoid's squashing nonlinearity creates these dead zones in the gradient landscape.</p>
<hr />
<h2>The Second Patch: Cross-Entropy Loss</h2>
<p>We need a loss function that doesn't go silent when the model is confidently wrong — one that yells at the model and aggressively forces it to correct its parameters. And again, rather than guessing, we can derive the right answer from first principles.</p>
<p>Ask a different question: <strong>what parameters <em>w</em> and <em>b</em> make the training data most likely to have occurred?</strong></p>
<p>This is called <strong>Maximum Likelihood Estimation (MLE)</strong>. For each training sample with true label <em>y</em> and predicted probability \( \hat{y} \), the likelihood of observing that label is:</p>
<p>$$P(y \mid x) = \hat{y}^y \cdot (1 - \hat{y})^{1-y}, \quad \hat{y} = \sigma(wx + b)$$</p>
<p>(When <em>y = 1</em>, this is just \( \hat{y} \); when <em>y = 0</em>, it's \( 1 - \hat{y} \).) Multiply across all training samples to get the total likelihood, take the log to turn products into sums, then flip the sign so we're minimizing instead of maximizing:</p>
<p>$$L_{\text{CE}} = -\frac{1}{N}\sum_{i=1}^{N} \left[ y_i \log\hat{y}_i + (1 - y_i)\log(1 - \hat{y}_i) \right]$$</p>
<p>This is <strong>Binary Cross-Entropy</strong>. It didn't come from trying to fix MSE — it came from asking what makes statistical sense given a model that outputs probabilities.</p>
<p>The gradient vanishing problem? Gone. The full derivation in one line for each parameter:</p>
<p>$$\frac{\partial L_{\text{CE}}}{\partial w} = \frac{\partial L_{\text{CE}}}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial z} \cdot \frac{\partial z}{\partial w} = \frac{\hat{y} - y}{\hat{y}(1-\hat{y})} \cdot \hat{y}(1-\hat{y}) \cdot x = (\hat{y} - y) \cdot x$$</p>
<p>$$\frac{\partial L_{\text{CE}}}{\partial b} = \frac{\partial L_{\text{CE}}}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial z} \cdot \frac{\partial z}{\partial b} = \frac{\hat{y} - y}{\hat{y}(1-\hat{y})} \cdot \hat{y}(1-\hat{y}) \cdot 1 = \hat{y} - y$$</p>
<p>The \( \hat{y}(1-\hat{y}) \) cancels exactly in both cases. No sigmoid derivative. No dead zones. When the model is wrong, the gradient is large. When it's right, the gradient is small. Exactly what you want.</p>
<p>This cancellation isn't a lucky coincidence — it's because sigmoid (derived from log-odds) and cross-entropy (derived from MLE) were always meant to go together. They're two sides of the same mathematical coin. By swapping MSE for cross-entropy, we transform the error landscape from bumpy terrain riddled with dead zones into a perfectly smooth bowl — guaranteeing the model will always find its way to the best possible solution.</p>
<hr />
<h2>Scaling Up: Multiple Features</h2>
<p>Adding more features is almost trivially easy. Instead of just flagged keyword count, we can throw in word count, sender domain reputation, number of exclamation marks, presence of links — anything. Instead of one weight <em>w</em>, we have a weight vector \( \mathbf{w} \), and the linear part becomes a dot product:</p>
<p>$$z = \mathbf{w} \cdot \mathbf{x} + b = w_1 x_1 + w_2 x_2 + \cdots + w_n x_n + b$$</p>
<p>Everything else — sigmoid, cross-entropy, gradient descent — stays exactly the same. The model now weighs each feature's contribution to the spam score, and training finds the combination that best separates spam from legitimate email.</p>
<hr />
<h2>Scaling Up: Multiple Classes</h2>
<p>Now for the real extension. Spam detection is binary — spam or not spam. But what if we have more than two classes? Think of the classic Iris dataset: given a flower's measurements, predict whether it's a Setosa, Versicolor, or Virginica.</p>
<p>The logic is exactly the same, just run in parallel — one linear model per class. For each of the three classes, we compute a score:</p>
<p>$$z = \mathbf{w} \cdot \mathbf{x} + b = w_1 x_1 + w_2 x_2 + \cdots + w_n x_n + b$$</p>
<p>Or more compactly, for each class <em>k</em>:</p>
<p>$$z_k = \mathbf{w}_k \cdot \mathbf{x} + b_k$$</p>
<p>Now we have three scores, one per class — Setosa, Versicolor, Virginica. We need to convert them into three probabilities that add up to 1.</p>
<p>Recall how sigmoid was derived: we modeled the log-odds of one class relative to the other. The natural generalization is to model the log-odds of each class relative to a reference class. Solve that system of equations, and the answer is:</p>
<p>$$P(\text{class } k) = \frac{e^{z_k}}{\sum_{j=1}^{K} e^{z_j}}$$</p>
<p>This is <strong>Softmax</strong>. It takes <em>K</em> arbitrary scores and turns them into <em>K</em> probabilities that sum to exactly 1. Sigmoid is just Softmax with <em>K = 2</em> — they're the same idea at different scales.</p>
<p>The loss function upgrades too. Because our true labels are one-hot encoded — the correct class is 1, everything else is 0 — the categorical cross-entropy loss simplifies to:</p>
<p>$$L = -\log(\hat{y}_{\text{correct class}})$$</p>
<p>The model only pays attention to whether the correct class got a high probability. The rest of the probability mass being distributed wrong is implicitly penalized through softmax's normalization constraint.</p>
<p>The gradient cancellation works here too. Softmax and categorical cross-entropy cancel each other out in exactly the same way sigmoid and binary cross-entropy do.</p>
<hr />
<h2>The Full Picture</h2>
<p>Here's the complete progression:</p>
<table>
<thead>
<tr>
<th>Problem</th>
<th>What it forced</th>
<th>Result</th>
</tr>
</thead>
<tbody><tr>
<td>Linear regression output is unbounded</td>
<td>Derive sigmoid from log-odds</td>
<td>Model outputs probabilities</td>
</tr>
<tr>
<td>MSE + sigmoid causes gradient vanishing</td>
<td>Derive cross-entropy from MLE</td>
<td>Gradients are clean</td>
</tr>
<tr>
<td>One feature → many features</td>
<td>Dot product</td>
<td>Same math, more inputs</td>
</tr>
<tr>
<td>Two classes → many classes</td>
<td>Generalize sigmoid → softmax, binary CE → categorical CE</td>
<td>Full multi-class classifier</td>
</tr>
</tbody></table>
<p>At every step, the solution wasn't invented — it was derived. Sigmoid follows from wanting a probability. Cross-entropy follows from asking what parameters best explain the data. Softmax follows from extending the log-odds idea to <em>K</em> classes.</p>
<p>Nothing was arbitrary. Everything was forced.</p>
<hr />
<h2>One More Thing</h2>
<p>Notice what the final multi-class logistic regression looks like: you have an input vector \( \mathbf{x} \), you multiply it by a weight matrix <em>W</em> (one weight vector per class), you add biases, and you pass the result through softmax.</p>
<p>That structure — linear transformation followed by a nonlinear activation — is exactly one layer of a neural network.</p>
<p>Logistic regression isn't just a classifier. It's the atomic unit that deep learning is built from. Stack a few of these layers on top of each other, and you have a deep neural network.</p>
<p>The midlife crisis turned out to be pretty productive. Once you see the story behind the math, the formulas finally make sense.</p>
]]></content:encoded></item></channel></rss>