<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>Ju Lin's AI Weblog: Math</title><subtitle>An independent research notebook on AI engineering, agents, models and the systems around them.</subtitle><id>https://julin.ai/atom/tags/math/index.xml</id><link rel="self" type="application/atom+xml" href="https://julin.ai/atom/tags/math/index.xml"/><link rel="alternate" type="text/html" href="https://julin.ai/tags/math/"/><author><name>Ju Lin</name></author><updated>2026-08-28T00:00:00+12:00</updated><entry><title>Partial Derivatives, Reverse-Mode Autodiff</title><id>https://julin.ai/2026/08/28/partial-derivatives/</id><link rel="alternate" type="text/html" href="https://julin.ai/2026/08/28/partial-derivatives/"/><published>2026-08-28T00:00:00+12:00</published><updated>2026-08-28T00:00:00+12:00</updated><category term="explainer"/><category term="learning"/><category term="math"/><category term="neural-networks"/><content type="html">&lt;p&gt;A partial derivative measures how much a function changes when you nudge one input, holding every other input fixed. For &lt;code&gt;f(x, y) = x²y + y + 2&lt;/code&gt;, the partial derivative with respect to &lt;code&gt;x&lt;/code&gt; asks: if &lt;code&gt;y&lt;/code&gt; stays put, how fast does &lt;code&gt;f&lt;/code&gt; move as &lt;code&gt;x&lt;/code&gt; moves?&lt;/p&gt;
&lt;h3 id="manual-differentiation"&gt;Manual differentiation&lt;/h3&gt;
&lt;p&gt;Mathematically, we know that &lt;code&gt;∂f/∂x = 2xy&lt;/code&gt; and &lt;code&gt;∂f/∂y = x² + 1&lt;/code&gt;, using a handful of rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the derivative of a constant is &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the derivative of &lt;code&gt;ax&lt;/code&gt; is &lt;code&gt;a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the derivative of &lt;code&gt;x^a&lt;/code&gt; is &lt;code&gt;a·x^(a-1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the derivative of a sum is the sum of the derivatives: &lt;code&gt;(u + v)' = u' + v'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the derivative of a product follows the product rule: &lt;code&gt;(u·v)' = u'v + uv'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But how can a program know that?&lt;/p&gt;
&lt;h3 id="reverse-mode-autodiff"&gt;Reverse-mode Autodiff&lt;/h3&gt;
&lt;p&gt;The answer is &lt;strong&gt;Reverse-mode autodiff&lt;/strong&gt; — the same technique PyTorch and TensorFlow use.&lt;/p&gt;
&lt;p&gt;It break the computation into small steps, run them forward once to get the value, then walk the same steps backward once, applying the chain rule at each step, to get every partial derivative in a single sweep.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s break &lt;code&gt;f(x, y) = x²y + y + 2&lt;/code&gt; into six nodes:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;n1 = x
n2 = y
n3 = n1²
n4 = n3 · n2
n5 = n4 + n2
n6 = n5 + 2 (this is f)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="/2026/08/28/partial-derivatives/diagram-tree.svg" alt="The computational graph for f(x,y) = x squared times y, plus y, plus 2, with nodes n1 through n6 and their formulas, before any values are computed."&gt;&lt;/p&gt;
&lt;h3 id="forward-pass-compute-the-value"&gt;Forward pass: compute the value&lt;/h3&gt;
&lt;p&gt;Plug in &lt;code&gt;x = 3&lt;/code&gt;, &lt;code&gt;y = 4&lt;/code&gt; and walk the graph left to right, one node at a time. Each node only needs the values of the nodes feeding into it.&lt;/p&gt;
&lt;p&gt;&lt;img src="/2026/08/28/partial-derivatives/diagram-forward.svg" alt="Forward pass: values fill in one node at a time, x=3 and y=4 first, then x squared=9, then x squared times y=36, then plus y=40, then plus 2 gives f=42."&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;n3 = 3² = 9&lt;/code&gt;, &lt;code&gt;n4 = 9 · 4 = 36&lt;/code&gt;, &lt;code&gt;n5 = 36 + 4 = 40&lt;/code&gt;, &lt;code&gt;n6 = 40 + 2 = 42&lt;/code&gt;. By the time the graph reaches &lt;code&gt;n6&lt;/code&gt;, you have &lt;code&gt;f(3, 4) = 42&lt;/code&gt; — and every intermediate value along the way, kept around for the next pass.&lt;/p&gt;
&lt;h3 id="backward-pass-compute-the-gradient"&gt;Backward pass: compute the gradient&lt;/h3&gt;
&lt;p&gt;Now walk the same graph backward, once. At the output, the derivative of &lt;code&gt;f&lt;/code&gt; with respect to itself is &lt;code&gt;1&lt;/code&gt;. At every earlier node, multiply the gradient flowing in from the node(s) it feeds by that node&amp;rsquo;s own &lt;em&gt;local&lt;/em&gt; derivative — the chain rule, applied one edge at a time.&lt;/p&gt;
&lt;p&gt;&lt;img src="/2026/08/28/partial-derivatives/diagram-backward.svg" alt="Backward pass: gradients fill in one node at a time from the output back to the inputs. df/dn6=1, then df/dn5=1, then df/dn4=1, then df/dn3=4 and df/dn2=10 together, then df/dn1=24."&gt;&lt;/p&gt;
&lt;p&gt;Spelled out, one step at a time:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# derivative of f with respect to itself
∂f/∂n6 = 1
# n6 = n5 + 2, so the local derivative ∂n6/∂n5 is 1
# (ax rule for n5, a=1; constant rule for +2, gives 0; sum: 1+0=1)
∂f/∂n5 = ∂f/∂n6 · ∂n6/∂n5
= 1 · 1
= 1
# n5 = n4 + n2, so the local derivative ∂n5/∂n4 is 1
# (ax rule for n4, a=1; n2 doesn&amp;#39;t depend on n4, gives 0; sum: 1+0=1)
∂f/∂n4 = ∂f/∂n5 · ∂n5/∂n4
= 1 · 1
= 1
# n4 = n3 · n2, so the local derivative ∂n4/∂n3 is n2 (product rule)
∂f/∂n3 = ∂f/∂n4 · ∂n4/∂n3
= 1 · n2
= 1 · 4
= 4
# n2 (that&amp;#39;s y) feeds both n5 and n4, so sum both paths
# ∂n5/∂n2 = 1 (ax rule), ∂n4/∂n2 = n3 (product rule, symmetric to n3&amp;#39;s case)
∂f/∂y = ∂f/∂n5 · ∂n5/∂n2 + ∂f/∂n4 · ∂n4/∂n2
= 1 · 1 + 1 · n3
= 1 · 1 + 1 · 9
= 1 + 9
= 10
# n3 = n1², so the local derivative ∂n3/∂n1 is 2·n1 (x^a rule, a=2)
∂f/∂x = ∂f/∂n3 · ∂n3/∂n1
= 4 · 2·n1
= 4 · 2·3
= 4 · 6
= 24
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Follow the same arithmetic back to &lt;code&gt;n1&lt;/code&gt;: &lt;code&gt;∂f/∂x = 2xy = 24&lt;/code&gt;, and &lt;code&gt;∂f/∂y = x² + 1 = 10&lt;/code&gt; — both computed in a single backward pass.&lt;/p&gt;
&lt;h3 id="why-bother-with-the-graph"&gt;Why bother with the graph&lt;/h3&gt;
&lt;p&gt;This is exactly what frameworks like PyTorch and TensorFlow do under the hood, at a much larger scale. One forward pass records the graph; one backward pass computes every partial derivative — no matter how many inputs the function has — for roughly the cost of one extra forward pass. That&amp;rsquo;s &lt;strong&gt;reverse-mode automatic differentiation&lt;/strong&gt;, and it&amp;rsquo;s the mechanism that makes training a network with a billion parameters just as mechanical as this six-node example.&lt;/p&gt;
&lt;h2 id="minimal-example"&gt;Minimal example&lt;/h2&gt;
&lt;p&gt;Stole from Karpathy&amp;rsquo;s &lt;a href="https://karpathy.github.io/2026/02/12/microgpt/"&gt;microgpt&lt;/a&gt; example because I feel this Python implementation is neat and serves as a good education purpose.&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-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; __slots__ &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;grad&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;_children&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;_local_grads&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, data, children&lt;span style="color:#f92672"&gt;=&lt;/span&gt;(), local_grads&lt;span style="color:#f92672"&gt;=&lt;/span&gt;()):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; data &lt;span style="color:#75715e"&gt;# scalar value of this node calculated during forward pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#75715e"&gt;# derivative of the loss w.r.t. this node, calculated in backward pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;_children &lt;span style="color:#f92672"&gt;=&lt;/span&gt; children &lt;span style="color:#75715e"&gt;# children of this node in the computation graph&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;_local_grads &lt;span style="color:#f92672"&gt;=&lt;/span&gt; local_grads &lt;span style="color:#75715e"&gt;# local derivative of this node w.r.t. its children&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__add__&lt;/span&gt;(self, other):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; other &lt;span style="color:#f92672"&gt;=&lt;/span&gt; other &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; isinstance(other, Value) &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; Value(other)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Value(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data &lt;span style="color:#f92672"&gt;+&lt;/span&gt; other&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data, (self, other), (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__mul__&lt;/span&gt;(self, other):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; other &lt;span style="color:#f92672"&gt;=&lt;/span&gt; other &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; isinstance(other, Value) &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; Value(other)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Value(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data &lt;span style="color:#f92672"&gt;*&lt;/span&gt; other&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data, (self, other), (other&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__pow__&lt;/span&gt;(self, other):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Value(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data&lt;span style="color:#f92672"&gt;**&lt;/span&gt;other, (self,), (other &lt;span style="color:#f92672"&gt;*&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data&lt;span style="color:#f92672"&gt;**&lt;/span&gt;(other&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;),))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(self): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Value(math&lt;span style="color:#f92672"&gt;.&lt;/span&gt;log(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data), (self,), (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data,))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;exp&lt;/span&gt;(self): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Value(math&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data), (self,), (math&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data),))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relu&lt;/span&gt;(self): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Value(max(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data), (self,), (float(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;data &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;),))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__neg__&lt;/span&gt;(self): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__radd__&lt;/span&gt;(self, other): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self &lt;span style="color:#f92672"&gt;+&lt;/span&gt; other
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__sub__&lt;/span&gt;(self, other): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;other)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__rsub__&lt;/span&gt;(self, other): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; other &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;self)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__rmul__&lt;/span&gt;(self, other): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self &lt;span style="color:#f92672"&gt;*&lt;/span&gt; other
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__truediv__&lt;/span&gt;(self, other): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self &lt;span style="color:#f92672"&gt;*&lt;/span&gt; other&lt;span style="color:#f92672"&gt;**-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__rtruediv__&lt;/span&gt;(self, other): &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; other &lt;span style="color:#f92672"&gt;*&lt;/span&gt; self&lt;span style="color:#f92672"&gt;**-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;backward&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; topo &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; visited &lt;span style="color:#f92672"&gt;=&lt;/span&gt; set()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;build_topo&lt;/span&gt;(v):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; v &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#f92672"&gt;in&lt;/span&gt; visited:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; visited&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add(v)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; child &lt;span style="color:#f92672"&gt;in&lt;/span&gt; v&lt;span style="color:#f92672"&gt;.&lt;/span&gt;_children:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; build_topo(child)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; topo&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(v)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; build_topo(self)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; v &lt;span style="color:#f92672"&gt;in&lt;/span&gt; reversed(topo):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; child, local_grad &lt;span style="color:#f92672"&gt;in&lt;/span&gt; zip(v&lt;span style="color:#f92672"&gt;.&lt;/span&gt;_children, v&lt;span style="color:#f92672"&gt;.&lt;/span&gt;_local_grads):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; child&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; local_grad &lt;span style="color:#f92672"&gt;*&lt;/span&gt; v&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Value(&lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;b &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Value(&lt;span style="color:#ae81ff"&gt;3.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a &lt;span style="color:#f92672"&gt;*&lt;/span&gt; b &lt;span style="color:#75715e"&gt;# c = 6.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c &lt;span style="color:#f92672"&gt;+&lt;/span&gt; a &lt;span style="color:#75715e"&gt;# L = 8.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;L&lt;span style="color:#f92672"&gt;.&lt;/span&gt;backward()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(a&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad) &lt;span style="color:#75715e"&gt;# 4.0 (dL/da = b + 1 = 3 + 1, via both paths)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(b&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad) &lt;span style="color:#75715e"&gt;# 2.0 (dL/db = a = 2)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is exactly what PyTorch’s &lt;code&gt;.backward()&lt;/code&gt; gives you:&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-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; torch
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; torch&lt;span style="color:#f92672"&gt;.&lt;/span&gt;tensor(&lt;span style="color:#ae81ff"&gt;2.0&lt;/span&gt;, requires_grad&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;b &lt;span style="color:#f92672"&gt;=&lt;/span&gt; torch&lt;span style="color:#f92672"&gt;.&lt;/span&gt;tensor(&lt;span style="color:#ae81ff"&gt;3.0&lt;/span&gt;, requires_grad&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; a &lt;span style="color:#f92672"&gt;*&lt;/span&gt; b
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c &lt;span style="color:#f92672"&gt;+&lt;/span&gt; a
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;L&lt;span style="color:#f92672"&gt;.&lt;/span&gt;backward()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(a&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad) &lt;span style="color:#75715e"&gt;# tensor(4.)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(b&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grad) &lt;span style="color:#75715e"&gt;# tensor(2.)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content></entry></feed>