<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Neural-Networks on Sanketh's Blog</title><link>https://sankethbk.github.io/blog/tags/neural-networks/</link><description>Recent content in Neural-Networks on Sanketh's Blog</description><generator>Hugo -- 0.166.0</generator><language>en-us</language><lastBuildDate>Sun, 20 Sep 2026 00:00:00 +0530</lastBuildDate><atom:link href="https://sankethbk.github.io/blog/tags/neural-networks/index.xml" rel="self" type="application/rss+xml"/><item><title>Attention: Turning Token Vectors into Context Vectors</title><link>https://sankethbk.github.io/blog/posts/ml/2026-09-20-1-attention-turning-token-vectors-into-context/</link><pubDate>Sun, 20 Sep 2026 00:00:00 +0530</pubDate><guid>https://sankethbk.github.io/blog/posts/ml/2026-09-20-1-attention-turning-token-vectors-into-context/</guid><description>&lt;h1 id="attention-turning-token-vectors-into-context-vectors"&gt;Attention: Turning Token Vectors into Context Vectors&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/posts/ml/2026-09-14-4-embeddings-from-one-hot-to-learned-representations"&gt;embeddings note&lt;/a&gt; ended with an honest limitation: a token&amp;rsquo;s embedding is one fixed row of a learned matrix. The word &amp;ldquo;bank&amp;rdquo; gets the same vector in &amp;ldquo;river bank&amp;rdquo; and &amp;ldquo;investment bank&amp;rdquo;. Everything the model can possibly know about &amp;ldquo;bank itself&amp;rdquo; is frozen into that row at training time.&lt;/p&gt;
&lt;p&gt;But meaning is contextual. When a model processes a sentence, what it needs at the position of &amp;ldquo;bank&amp;rdquo; is not &amp;ldquo;the generic bank vector&amp;rdquo; but &amp;ldquo;the vector of bank &lt;em&gt;as it appears in this sentence&lt;/em&gt;&amp;rdquo;. Attention is the mechanism that builds that second thing from the first.&lt;/p&gt;</description></item><item><title>Activation Functions: Why Sigmoid Fades and ReLU Won</title><link>https://sankethbk.github.io/blog/posts/ml/2026-09-14-2-activation-functions-sigmoid-relu/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/ml/2026-09-14-2-activation-functions-sigmoid-relu/</guid><description>&lt;h1 id="activation-functions-why-sigmoid-fades-and-relu-won"&gt;Activation Functions: Why Sigmoid Fades and ReLU Won&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/posts/ml/2026-09-14-1-training-a-2-layer-network-in-numpy"&gt;previous note&lt;/a&gt; finished with pseudocode for a network of any depth
$L$
. One line in that pseudocode deserved more attention:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dZ[l-1] = dA[l-1] * activation_derivative(A[l-1])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Everything else in the backward pass is matrix multiplication — copying, scaling, and adding error signals. This one line is different: it is the only place where the network&amp;rsquo;s &lt;em&gt;non-linearity&lt;/em&gt; touches the gradients. The choice of activation function decides whether error signals survive the trip from output back to input, or die on the way.&lt;/p&gt;</description></item><item><title>Embeddings: From One-Hot Vectors to Learned Representations</title><link>https://sankethbk.github.io/blog/posts/ml/2026-09-14-4-embeddings-from-one-hot-to-learned-representations/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/ml/2026-09-14-4-embeddings-from-one-hot-to-learned-representations/</guid><description>&lt;h1 id="embeddings-from-one-hot-vectors-to-learned-representations"&gt;Embeddings: From One-Hot Vectors to Learned Representations&lt;/h1&gt;
&lt;p&gt;Everything in the previous notes assumed the network&amp;rsquo;s input was already a list of numbers — &lt;code&gt;x1 = 1, x2 = 2&lt;/code&gt;, pixel intensities, whatever. But most interesting data is not numeric. &amp;ldquo;cat&amp;rdquo;, &amp;ldquo;dog&amp;rdquo;, &amp;ldquo;bank&amp;rdquo;, user IDs, product IDs, words of a sentence. Neural networks cannot multiply the string &lt;code&gt;&amp;quot;cat&amp;quot;&lt;/code&gt; by a weight matrix. Somewhere between the raw symbol and the first linear layer, a translation to numbers must happen, and the way we do it — the &lt;strong&gt;embedding layer&lt;/strong&gt; — turns out to be one of the most consequential ideas in modern deep learning.&lt;/p&gt;</description></item><item><title>Softmax and Multiclass Cross-Entropy: Turning Raw Scores Into Probabilities</title><link>https://sankethbk.github.io/blog/posts/ml/2026-09-14-3-softmax-and-multiclass-cross-entropy/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/ml/2026-09-14-3-softmax-and-multiclass-cross-entropy/</guid><description>&lt;h1 id="softmax-and-multiclass-cross-entropy-turning-raw-scores-into-probabilities"&gt;Softmax and Multiclass Cross-Entropy: Turning Raw Scores Into Probabilities&lt;/h1&gt;
&lt;p&gt;So far, every classification in these notes has been binary — spam or not, XOR&amp;rsquo;s 0 or 1 — and the output has been single sigmoid feeding binary cross-entropy, whose gradient collapsed to the beautiful
$\delta = a - y$
.&lt;/p&gt;
&lt;p&gt;Real classifiers rarely answer two-way questions. &amp;ldquo;Which of 10 digits is this image?&amp;rdquo; &amp;ldquo;Which of 50,000 tokens comes next?&amp;rdquo; &amp;ldquo;Is this a cat, a dog, or a bird?&amp;rdquo; This note generalizes the output of a neural network to
$k$
classes, and it turns out almost everything we know carries over — with soft-max doing the job sigmoid did.&lt;/p&gt;</description></item><item><title>Training a 2-Layer Network in NumPy: From Scalar to Vectorized Backprop</title><link>https://sankethbk.github.io/blog/posts/ml/2026-09-14-1-training-a-2-layer-network-in-numpy/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/ml/2026-09-14-1-training-a-2-layer-network-in-numpy/</guid><description>&lt;h1 id="training-a-2-layer-network-in-numpy-from-scalar-to-vectorized-backprop"&gt;Training a 2-Layer Network in NumPy: From Scalar to Vectorized Backprop&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sankethbk.github.io/blog/posts/ml/2026-09-12-3-backpropagation-in-a-fully-connected-network"&gt;previous note&lt;/a&gt; did the backward pass for a small 2-layer network by hand, one scalar at a time. That is the best way to understand what backprop actually does.&lt;/p&gt;
&lt;p&gt;This note takes the next step: turn that scalar walk into compact, vectorized NumPy code. The math is unchanged; the only thing that changes is notation. I will introduce every matrix slowly — what its rows and columns mean, where the division by the batch size comes from, and why it is exactly the same algorithm you already did by hand.&lt;/p&gt;</description></item><item><title>Backpropagation in a Fully-Connected Network, From Scratch</title><link>https://sankethbk.github.io/blog/posts/ml/2026-09-12-3-backpropagation-in-a-fully-connected-network/</link><pubDate>Sat, 12 Sep 2026 00:00:00 +0000</pubDate><guid>https://sankethbk.github.io/blog/posts/ml/2026-09-12-3-backpropagation-in-a-fully-connected-network/</guid><description>&lt;ul&gt;
&lt;li&gt;Why is there no deadlock in the order of corrections?&lt;/li&gt;
&lt;li&gt;Why is this cheap enough to do for billions of parameters?&lt;/li&gt;
&lt;li&gt;What is PyTorch&amp;rsquo;s autograd doing when you call &lt;code&gt;loss.backward()&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="1-what-you-will-learn"&gt;1. What you will learn&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The shape of a fully-connected (dense) network and what &amp;ldquo;fully-connected&amp;rdquo; means.&lt;/li&gt;
&lt;li&gt;How to forward a single training example through every operation, by hand.&lt;/li&gt;
&lt;li&gt;The backward pass as a message-passing process, with the exact algebra at each edge.&lt;/li&gt;
&lt;li&gt;The recursion that lets you go from 2 layers to 100 layers.&lt;/li&gt;
&lt;li&gt;Why nothing breaks due to ordering — the backward pass &lt;em&gt;computes&lt;/em&gt; gradients; it does not &lt;em&gt;apply&lt;/em&gt; updates.&lt;/li&gt;
&lt;li&gt;Why backprop costs about one extra forward pass, not one forward pass per parameter.&lt;/li&gt;
&lt;li&gt;A pseudocode implementation of the whole algorithm.&lt;/li&gt;
&lt;li&gt;What an autograd engine records, and how &lt;code&gt;loss.backward()&lt;/code&gt; / &lt;code&gt;optimizer.step()&lt;/code&gt; / &lt;code&gt;optimizer.zero_grad()&lt;/code&gt; map onto what we do by hand.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-the-network-we-are-going-to-train"&gt;2. The network we are going to train&lt;/h2&gt;
&lt;p&gt;Logistic regression is a single layer: input → weighted sum → sigmoid → probability. Its decision boundary is a line (or hyperplane). There is a famous class of problems it cannot solve — XOR is the classic example — where no single line separates the two classes.&lt;/p&gt;</description></item></channel></rss>