<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Madhumitha Kolkar</title>
    <description>The latest articles on DEV Community by Madhumitha Kolkar (@madhumithakolkar).</description>
    <link>https://dev.to/madhumithakolkar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4032482%2F8d0c4f6e-c85f-494e-b264-f2a2ac9f8a3a.jpg</url>
      <title>DEV Community: Madhumitha Kolkar</title>
      <link>https://dev.to/madhumithakolkar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/madhumithakolkar"/>
    <language>en</language>
    <item>
      <title>I Built a Neural Network Training Loop in 5 Lines Using JAX - Day 2</title>
      <dc:creator>Madhumitha Kolkar</dc:creator>
      <pubDate>Tue, 21 Jul 2026 04:24:25 +0000</pubDate>
      <link>https://dev.to/madhumithakolkar/i-built-a-neural-network-training-loop-in-5-lines-using-jax-day-2-1a4j</link>
      <guid>https://dev.to/madhumithakolkar/i-built-a-neural-network-training-loop-in-5-lines-using-jax-day-2-1a4j</guid>
      <description>&lt;p&gt;SERIES: Learning RL and JAX in Public - from zero to DeepMind :)&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjoi3sfr0rd91dluf0xpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjoi3sfr0rd91dluf0xpn.png" alt=" " width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;On Day 1 I covered what JAX is and the three superpowers: GPU acceleration, grad, and jit. Today I actually used them. And the moment where I manually verified a gradient by hand and watched JAX confirm it is the one that made everything real for me.&lt;/p&gt;

&lt;p&gt;But before the code, I had to understand what a gradient actually is. Because I realised I had been using them for years without a clean mental model.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What is a derivative, really?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you are adjusting a dial on a machine. The dial controls the volume. Your goal is to get the volume to exactly 50. Right now it is at 30.&lt;/p&gt;

&lt;p&gt;You turn the dial a tiny bit. The volume goes up.&lt;/p&gt;

&lt;p&gt;The derivative answers one question: if I nudge this dial by a tiny amount, how much does the output change?&lt;/p&gt;

&lt;p&gt;That is it. In math:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f(x) = x * x
f(3) = 9
f(3.001) = 9.006001

nudge of 0.001 caused a change of 0.006
rate of change = 0.006 / 0.001 = 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The derivative of x squared at x equals 3 is 6. Meaning: at this point, if x increases by a tiny amount, the output increases 6 times as fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a gradient?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A derivative is for a function with one input. A gradient is the same idea for a function with many inputs. It is just a list of derivatives, one per input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function with 1 input  -&amp;gt;  derivative  (a single number)
function with N inputs -&amp;gt;  gradient    (a list of N numbers)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why does this matter for ML?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every neural network has weights. Training means finding the weights that make the model least wrong. "How wrong" is measured by a number called the loss.&lt;/p&gt;

&lt;p&gt;The gradient of the loss tells you: for each weight, does increasing it make the loss bigger or smaller, and by how much?&lt;/p&gt;

&lt;p&gt;Nudge every weight in the direction that reduces the loss. Repeat thousands of times. That is gradient descent. That is literally how every neural network on the planet trains.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Now the code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First I verified grad by hand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jax&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="n"&gt;grad_of_square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;grad_of_square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 6.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Derivative of x squared is 2x. At x equals 3, that is 6. JAX says 6.0. Verified.&lt;/p&gt;

&lt;p&gt;Then I wrote a real loss function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
    &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;
    &lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;grad_of_loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loss measures how wrong a prediction is. The ideal weight is 5.0 because 5 times 2 equals 10.&lt;/p&gt;

&lt;p&gt;Then gradient descent from scratch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;learning_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;grad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;grad_of_loss&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;learning_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;grad&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: w = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, loss = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;step 1: w = 2.6000, loss = 21.1600
step 2: w = 3.6640, loss = 8.6491
step 3: w = 4.3302, loss = 3.5369
step 4: w = 4.7481, loss = 1.4461
step 5: w = 5.0105, loss = 0.0044 (almost zero, w approaching 5.0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That loop is the core of every neural network training run. More weights, more complex functions, but the same mechanic.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The jit speedup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I benchmarked a large computation with and without jit over 100 runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;slow_computation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jnp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jnp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;jnp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;fast_computation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow_computation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: 32x speedup on my MacBook CPU. On a GPU this goes to 100x or more.&lt;/p&gt;

&lt;p&gt;The first call is always slower because that is when JAX compiles. Every call after uses the cached compiled version. One catch: if you change the shape of your input, JAX recompiles. So keep your array shapes consistent.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;One question I had: do I need to memorise all this syntax?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. The important thing is knowing what to use and when. Nobody in a research role writes jax.grad from memory every time - they know it exists, they know what it does, they look up the exact syntax when needed.&lt;/p&gt;

&lt;p&gt;What you do need to carry in your head: grad differentiates, jit compiles, and they compose together. That mental model handles 90% of situations.&lt;/p&gt;




&lt;p&gt;Day 3 tomorrow: vmap, the fourth JAX superpower. This one genuinely surprised me.&lt;/p&gt;

&lt;p&gt;All code from this series, organised by day, is on my GitHub: &lt;a href="https://github.com/MadhumithaKolkar/jax-rl-lab" rel="noopener noreferrer"&gt;https://github.com/MadhumithaKolkar/jax-rl-lab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy learning everyone !&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Madhumitha Kolkar (index_0)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jax</category>
      <category>machinelearning</category>
      <category>python</category>
      <category>deeplearning</category>
    </item>
    <item>
      <title>I Started Learning JAX as a Senior ML Engineer - Here's My First Impression.</title>
      <dc:creator>Madhumitha Kolkar</dc:creator>
      <pubDate>Mon, 20 Jul 2026 05:41:20 +0000</pubDate>
      <link>https://dev.to/madhumithakolkar/i-started-learning-jax-as-a-senior-ml-engineer-heres-my-first-impression-bm3</link>
      <guid>https://dev.to/madhumithakolkar/i-started-learning-jax-as-a-senior-ml-engineer-heres-my-first-impression-bm3</guid>
      <description>&lt;p&gt;SERIES: Learning RL and JAX in Public - from zero to DeepMind !&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz0y5rhsflp47ubxaiggm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz0y5rhsflp47ubxaiggm.png" alt=" " width="742" height="232"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I have been a machine learning engineer for six years. PyTorch is basically muscle memory at this point. So when I decided to seriously learn JAX, I expected it to feel like switching keyboards - same idea, different layout.&lt;/p&gt;

&lt;p&gt;It is not that. JAX is a genuinely different way of thinking about numerical computing. And on Day 1, I want to share the mental model that made it click for me.&lt;/p&gt;




&lt;p&gt;If you already know NumPy, you already know 80% of JAX's syntax. That part is intentional. The JAX team designed the API to mirror NumPy almost exactly so the learning curve stays shallow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# NumPy
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 6.0
&lt;/span&gt;
&lt;span class="c1"&gt;# JAX - identical
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jax.numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;jnp&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jnp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jnp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 6.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same thing. Where JAX diverges is in three superpowers that NumPy simply does not have.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Superpower 1: It runs on GPU and TPU automatically&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No .to('cuda'). No .cuda(). JAX looks for available accelerators and uses them. You write the same code whether you are on a laptop CPU or a cloud TPU. This alone is huge if you work across different environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Superpower 2: jax.grad - automatic differentiation as a function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In PyTorch, you call .backward() on a loss tensor. In JAX, grad is a standalone function transformer. You hand it any Python function, it hands you back a new function that computes the gradient of the original.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jax&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;derivative&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;derivative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 6.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The derivative of x squared is 2x. At x equals 3, that is 6. JAX confirms it instantly. The fact that this works on any arbitrary Python function is what makes JAX powerful for research.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Superpower 3: jax.jit - compile your code for speed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Python is slow by default. jit (Just-In-Time compilation) takes your function, compiles it to optimised machine code on the first call, and every subsequent call skips Python entirely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;fast_fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First call is slower because of compilation. Every call after that is significantly faster. On Day 2 I benchmarked this and got a 32x speedup. More on that in the next post.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The one rule that surprised me: no in-place mutation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PyTorch lets you modify arrays in place. JAX does not. Every operation creates a new array. This feels wrong for about two days. Then you realise it is what makes grad and jit mathematically clean - they need functions to be pure (same input always gives same output). Mutation breaks that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This errors in JAX
&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;

&lt;span class="c1"&gt;# Do this instead
&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# creates a new array
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Why top research labs use JAX&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The more I dig into JAX, the more I understand why the most ambitious ML research happening today is built on it. Labs like Google DeepMind run their entire research stack on JAX and Flax, and it is not arbitrary. When you are training models across hundreds of TPUs, you need code that is compiled, mathematically clean, and composable at scale. The combination of jit and grad doing exactly that is genuinely elegant. I find myself wanting to understand not just how to use these tools but why they were designed this way, and that curiosity is pushing me to go deeper into the fundamentals than I ever did with PyTorch. There is a certain level of ML engineering where understanding the infrastructure is just as important as understanding the models, and JAX sits right at that intersection.&lt;/p&gt;




&lt;p&gt;Day 1 was arrays and basic operations. Simple stuff. But getting the mental model right before writing complex code matters more than rushing into the deep end.&lt;/p&gt;

&lt;p&gt;Day 2 is grad, jit, and a gradient descent loop from scratch. See you there.&lt;/p&gt;

&lt;p&gt;If you are on a similar journey from PyTorch to JAX, I would love to hear what tripped you up first. Drop it in the comments.&lt;/p&gt;

&lt;p&gt;All code from this series, organised by day, is on my GitHub: &lt;a href="https://github.com/MadhumithaKolkar/jax-rl-lab" rel="noopener noreferrer"&gt;https://github.com/MadhumithaKolkar/jax-rl-lab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy learning everyone !&lt;/p&gt;




&lt;p&gt;~ Madhumitha Kolkar (index_0)&lt;/p&gt;

</description>
      <category>jax</category>
      <category>machinelearning</category>
      <category>python</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
