<?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[From Papers to Code]]></title><description><![CDATA[From Papers to Code]]></description><link>https://ai-coding.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>From Papers to Code</title><link>https://ai-coding.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 16:17:03 GMT</lastBuildDate><atom:link href="https://ai-coding.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[A World Model Can Lower MSE and Still Choose the Wrong Action]]></title><description><![CDATA[Suppose two world models feed the same planner. One has ten times less mean squared prediction error. Would you deploy that one?
Before answering, inspect which action each model chooses.
This post us]]></description><link>https://ai-coding.hashnode.dev/a-world-model-can-lower-mse-and-still-choose-the-wrong-action</link><guid isPermaLink="true">https://ai-coding.hashnode.dev/a-world-model-can-lower-mse-and-still-choose-the-wrong-action</guid><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[ym p]]></dc:creator><pubDate>Fri, 16 Oct 2026 05:24:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6acae344a92634871bd205b0/8c6eb749-0a0a-47b2-8014-34315d64a918.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Suppose two world models feed the same planner. One has ten times less mean squared prediction error. Would you deploy that one?</p>
<p>Before answering, inspect which action each model chooses.</p>
<p>This post uses a three-action Python experiment to separate prediction accuracy from decision quality. No simulator, GPU, or model API is needed. The example is deliberately small enough that every reported number can be checked by hand.</p>
<h2>The counterexample</h2>
<p>Consider a planner that minimizes predicted cost:</p>
<table>
<thead>
<tr>
<th>Action</th>
<th>True cost</th>
<th>Model A prediction</th>
<th>Model B prediction</th>
</tr>
</thead>
<tbody><tr>
<td>left</td>
<td>0</td>
<td>2</td>
<td>0</td>
</tr>
<tr>
<td>right</td>
<td>1</td>
<td>1</td>
<td>3</td>
</tr>
<tr>
<td>wait</td>
<td>100</td>
<td>100</td>
<td>94</td>
</tr>
</tbody></table>
<p>Model A chooses <code>right</code>. Its true execution cost is 1.</p>
<p>Model B chooses <code>left</code>. Its true execution cost is 0.</p>
<p>Meanwhile, A's squared errors are 4, 0, and 0. B's are 0, 4, and 36. Averaging across the same three actions gives:</p>
<table>
<thead>
<tr>
<th>Model</th>
<th>Prediction MSE</th>
<th>Chosen action</th>
<th>Decision regret</th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>1.333333</td>
<td>right</td>
<td>1</td>
</tr>
<tr>
<td>B</td>
<td>13.333333</td>
<td>left</td>
<td>0</td>
</tr>
</tbody></table>
<p>A has one tenth of B's MSE, but makes the worse decision.</p>
<p>B's large error on <code>wait</code> dominates its MSE. In this candidate set, that prediction remains far above both alternatives, so it does not affect the selected action. A's smaller error reverses the ranking precisely where the decision is made.</p>
<p>These are constructed predictions, not benchmark results from trained models.</p>
<h2>Score the selected action against reality</h2>
<p>To isolate the final selection step, assume each model already supplies predicted action costs. This is a small slice of a world-model planning pipeline: predict outcomes, calculate costs, select an action. It does not reproduce a full learned environment model.</p>
<p>For this experiment:</p>
<ul>
<li>MSE averages squared cost-prediction errors over every candidate action.</li>
<li>The planner chooses the lowest predicted cost, with action names breaking ties.</li>
<li>Regret is the selected action's <strong>true</strong> cost minus the best true cost in the candidate set.</li>
</ul>
<p>Using predicted costs to calculate regret would let the model grade its own choice. It would always consider its selected action optimal.</p>
<pre><code class="language-python">import math

def evaluate_forecast(predicted, true_costs):
    if not true_costs or set(predicted) != set(true_costs):
        raise ValueError("expected matching, nonempty action dictionaries")
    if not all(isinstance(a, str) for a in true_costs):
        raise ValueError("action names must be strings")
    if not all(math.isfinite(x) for x in (*predicted.values(), *true_costs.values())):
        raise ValueError("costs must be finite")

    actions = sorted(true_costs)
    chosen = min(actions, key=lambda a: predicted[a])
    mse = math.fsum(
        (predicted[a] - true_costs[a]) ** 2 for a in actions
    ) / len(actions)
    regret = true_costs[chosen] - min(true_costs.values())
    return {"chosen": chosen, "mse": mse, "regret": regret}

truth = {"left": 0.0, "right": 1.0, "wait": 100.0}
pred_a = {"left": 2.0, "right": 1.0, "wait": 100.0}
pred_b = {"left": 0.0, "right": 3.0, "wait": 94.0}

for name, prediction in (("A", pred_a), ("B", pred_b)):
    result = evaluate_forecast(prediction, truth)
    print(f"{name}: action={result['chosen']}, "
          f"MSE={result['mse']:.6f}, regret={result['regret']:.6f}")
</code></pre>
<p>Output:</p>
<pre><code class="language-text">A: action=right, MSE=1.333333, regret=1.000000
B: action=left, MSE=13.333333, regret=0.000000
</code></pre>
<p>The qualifier “in the candidate set” matters. Zero regret here does not establish global optimality over every possible action sequence. A candidate generator may have omitted a better option entirely.</p>
<h2>You do not need an irrelevant third action</h2>
<p>The first example contains a clearly unattractive action. The mismatch can also happen with just two alternatives.</p>
<p>Let the true costs be <code>(0, 1)</code>. Compare predictions <code>(10, 11)</code> with <code>(0.6, 0.4)</code>:</p>
<pre><code class="language-python">two_actions = {"left": 0.0, "right": 1.0}
offset = evaluate_forecast({"left": 10.0, "right": 11.0}, two_actions)
reversed_order = evaluate_forecast({"left": 0.6, "right": 0.4}, two_actions)

assert offset["mse"] == 100.0
assert offset["regret"] == 0.0
assert math.isclose(reversed_order["mse"], 0.36)
assert reversed_order["regret"] == 1.0
</code></pre>
<p>The first predictor has a large common offset but preserves the ordering. The second is closer to both true costs but crosses the decision boundary.</p>
<p>This offset argument concerns <strong>cost predictions</strong>. Adding an offset to predicted states need not preserve action rankings after a nonlinear cost function is applied.</p>
<h2>A condition under which accuracy does protect the decision</h2>
<p>Assume a unique true best action. Call the cost difference between the best and second-best candidates <code>gap</code>.</p>
<p>If every candidate's absolute cost-prediction error is at most <code>epsilon</code>, then this sufficient condition guarantees the same best action:</p>
<pre><code class="language-text">gap &gt; 2 * epsilon
</code></pre>
<p>In the worst case, the best action is overestimated by <code>epsilon</code> and a competitor is underestimated by <code>epsilon</code>. Their combined distortion still cannot erase the gap.</p>
<p>That is a uniform error bound, not an average error metric. Substituting MSE directly for <code>epsilon</code> changes the statement. A small average can hide a relatively large error on a decision-critical candidate.</p>
<p>Prediction accuracy remains useful. The missing step is checking whether errors are small relative to the decision margins that matter for the task.</p>
<h2>Test the evaluator too</h2>
<p>An evaluation helper can silently mix up prediction and execution costs, or treat two equally good actions as different outcomes. These checks expose those mistakes:</p>
<pre><code class="language-python">perfect = evaluate_forecast(truth, truth)
assert perfect["mse"] == 0.0 and perfect["regret"] == 0.0

# Prediction ties follow action-name order, not dictionary insertion order.
tied = evaluate_forecast({"z": 0.0, "a": 0.0}, {"z": 0.0, "a": 5.0})
assert tied["chosen"] == "a" and tied["regret"] == 5.0

# Different action IDs can be equally optimal under the true costs.
equally_good = evaluate_forecast({"a": 1.0, "b": 0.0}, {"a": 2.0, "b": 2.0})
assert equally_good["chosen"] == "b" and equally_good["regret"] == 0.0

# With one candidate, candidate-set regret is always zero.
single = evaluate_forecast({"only": 7.0}, {"only": 5.0})
assert single["mse"] == 4.0 and single["regret"] == 0.0
print("All evaluator checks passed")
</code></pre>
<p>Sorting the action names costs O(A log A) time and O(A) space. Obtaining trustworthy execution costs is usually much harder than calculating the metrics.</p>
<h2>Connecting the toy example to world-model research</h2>
<p>The September 2026 preprint <a href="https://arxiv.org/abs/2609.32322">Not All Errors Matter: Decision-Relevant Prediction Error Predicts Planning Quality</a> examines how error allocation across state dimensions relates to planning and introduces DRPE. The experiment above is an original cost-ranking illustration, not a reproduction of its experiments or its metric.</p>
<p><a href="https://arxiv.org/abs/2606.15032">How Should World Models Be Evaluated for Embodied Decision-Making?</a> likewise argues that evidence should match the claimed use. A model presented as useful for planning needs evaluation of that use, beyond visual plausibility alone.</p>
<p>For a practical comparison, hold the task, candidate-generation method, planner budget, and evaluation protocol fixed. Report prediction quality alongside real execution outcomes. Vary rollout horizon explicitly. If exact optimal costs are unavailable, identify the comparator rather than labeling a baseline-relative gap as exact optimal regret.</p>
<p>I maintain <a href="https://tensordrill.com/">TensorDrill</a>, an AI coding practice site. Its <a href="https://tensordrill.com/problems/prediction-vs-decision/">forecast MSE versus planning regret exercise</a> turns this diagnostic into a small Python implementation task with a fixed contract and tests.</p>
<p>A lower prediction error answers an important question. Whether the planner chooses well deserves its own measurement.</p>
]]></content:encoded></item><item><title><![CDATA[Constitutional AI in Python: Keep the Soft Labels, Not Just the Winner]]></title><description><![CDATA[An AI judge prefers answer A with probability 0.6. Should the preference model train on 0.6, or should we round it to a hard label of 1?
Those choices optimize different objectives. The difference bec]]></description><link>https://ai-coding.hashnode.dev/constitutional-ai-in-python-keep-the-soft-labels-not-just-the-winner</link><guid isPermaLink="true">https://ai-coding.hashnode.dev/constitutional-ai-in-python-keep-the-soft-labels-not-just-the-winner</guid><category><![CDATA[Python]]></category><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[ym p]]></dc:creator><pubDate>Thu, 15 Oct 2026 00:43:54 GMT</pubDate><content:encoded><![CDATA[<p>An AI judge prefers answer A with probability 0.6. Should the preference model train on 0.6, or should we round it to a hard label of 1?</p>
<p>Those choices optimize different objectives. The difference becomes obvious when a model assigns A a very large score advantage: a hard winner encourages certainty, while a soft target can penalize it.</p>
<p>While adding Constitutional AI exercises to TensorDrill, the AI coding practice site I maintain, I separated this into two small components: transform supplied judge scores, then compute a preference loss. Neither component needs a model API or a GPU.</p>
<h2>First, identify the stage you are implementing</h2>
<p>The Constitutional AI paper separates critique-and-revision training from learning with AI-generated preferences. This article focuses on transforming supplied preference judgments, rather than generating critiques or training a complete aligned assistant.</p>
<p>For this exercise, the judge provides natural log probabilities for two answer options from the same prompt. These are not the preference model's response scores. We normalize the two option probabilities to obtain a target for that later model.</p>
<h2>Normalize probabilities, not negative log values</h2>
<p>For two log probabilities <code>a</code> and <code>b</code>, the normalized probability of option A is:</p>
<pre><code class="language-text">target_A = exp(a) / (exp(a) + exp(b))
</code></pre>
<p>Dividing <code>a</code> by <code>a+b</code> is a different operation. Exponentiating both values directly also fails for inputs such as <code>-1000</code> and <code>-1001</code>: both exponentials underflow to zero.</p>
<p>Subtracting the maximum solves the numerical problem:</p>
<pre><code class="language-python">import math

def preference_label(logp_a, logp_b, clamp=False):
    peak = max(logp_a, logp_b)
    a = math.exp(logp_a - peak)
    b = math.exp(logp_b - peak)
    p_a = a / (a + b)
    if clamp:
        p_a = min(0.6, max(0.4, p_a))
    return p_a, 1.0 - p_a

assert preference_label(-2, -2) == (0.5, 0.5)
p, q = preference_label(-1000, -1001)
assert abs(p - 0.7310585786300049) &lt; 1e-12
assert abs(p + q - 1.0) &lt; 1e-12
assert preference_label(0, -1000, True) == (0.6, 0.4)
assert preference_label(-1000, 0, True) == (0.4, 0.6)
</code></pre>
<p>The inputs here are finite natural log probabilities at most zero. The optional 0.4–0.6 clamp illustrates the paper's main chain-of-thought feedback setting. It is not a general instruction to clamp every preference dataset, and it does not establish that a judge is calibrated.</p>
<p>Always construct the second probability after clamping the first. Otherwise the pair can stop summing to one.</p>
<h2>A target is not a predicted probability</h2>
<p>Now suppose a preference model assigns response scores <code>s_a</code> and <code>s_b</code>. Their difference determines the predicted preference:</p>
<pre><code class="language-text">d = s_a - s_b
prediction_A = sigmoid(d)
</code></pre>
<p>The judge's normalized probability is the target, not that prediction. Pairwise binary cross-entropy compares the two:</p>
<pre><code class="language-text">loss = -target * log(prediction_A)
       -(1-target) * log(1-prediction_A)
</code></pre>
<p>For a target of 0.6, the loss is minimized when the prediction is 0.6. If we round the target to 1, increasingly confident predictions keep reducing the loss instead.</p>
<p>This is a standard soft-label pairwise logistic objective. It exposes one preference-model component; it is not a claim to reproduce every training choice in the Constitutional AI paper.</p>
<h2>Avoid computing log of a rounded zero</h2>
<p>Large score differences can make a floating-point sigmoid return exactly zero or one. Computing the logarithms directly can then fail, even though the mathematical loss is finite.</p>
<p>A stable expression works in score-difference space:</p>
<pre><code class="language-python">def preference_loss(scores_a, scores_b, targets):
    losses = []
    for a, b, target in zip(scores_a, scores_b, targets):
        d = a - b
        losses.append(
            max(d, 0.0) - target*d
            + math.log1p(math.exp(-abs(d)))
        )
    return math.fsum(losses) / len(losses)

assert abs(preference_loss([0], [0], [.6]) - math.log(2)) &lt; 1e-12
assert preference_loss([1000], [0], [1]) == 0
assert preference_loss([1000], [0], [0]) == 1000
assert preference_loss([1000], [0], [.6]) == 400
assert preference_loss([-1000], [0], [1]) == 1000
</code></pre>
<p>The lists are equal-length and nonempty, targets lie in <code>[0,1]</code>, and scores are finite with absolute value at most one million. The function computes a mean loss in nats; it does not update parameters.</p>
<p>The <code>400</code> result is the useful counterexample. An extremely confident preference is cheap under a compatible hard label, but expensive when the target still assigns meaningful probability to the other answer.</p>
<h2>Test the objective, not just whether it runs</h2>
<p>Useful tests distinguish these common mistakes:</p>
<table>
<thead>
<tr>
<th>Mistake</th>
<th>A case that exposes it</th>
</tr>
</thead>
<tbody><tr>
<td>Exponentiating raw log probabilities</td>
<td><code>-1000</code> versus <code>-1001</code></td>
</tr>
<tr>
<td>Omitting an explicitly requested clamp</td>
<td>Strong A or B preference</td>
</tr>
<tr>
<td>Turning all targets into winners</td>
<td>A target of 0.6 with score difference 1000</td>
</tr>
<tr>
<td>Summing a batch loss</td>
<td>Two identical examples should retain the same mean</td>
</tr>
<tr>
<td>Reversing the score difference</td>
<td>Swap A/B and replace target with its complement</td>
</tr>
</tbody></table>
<pre><code class="language-python">base = preference_loss([2], [0], [.7])
assert abs(preference_loss([2, 2], [0, 0], [.7, .7]) - base) &lt; 1e-12
assert abs(preference_loss([0], [2], [.3]) - base) &lt; 1e-12
assert abs(preference_loss([7], [5], [.7]) - base) &lt; 1e-12
</code></pre>
<p>The last case checks that a common score offset changes neither preference nor loss.</p>
<h2>Agreement is not a harmlessness guarantee</h2>
<p>A low loss shows agreement with supplied targets. It does not independently establish that responses are harmless, correct, or helpful. Judge errors can become training targets too. The paper's broader pipeline also includes helpfulness data and reinforcement learning.</p>
<p>To practice the components in sequence, I put revision data preparation, soft-label normalization, and preference loss in the <a href="https://tensordrill.com/practice-sets/constitutional-ai-from-revision-to-preference/">TensorDrill Constitutional AI learning unit</a>. It includes inspectable browser tests and complete Python solutions. The wider library covers agents, world models, Attention, Flow Matching and other AI components.</p>
<h2>References</h2>
<ul>
<li><a href="https://arxiv.org/pdf/2212.08073">Constitutional AI: Harmlessness from AI Feedback</a>, especially the supervised and AI-feedback stages.</li>
<li><a href="https://www.anthropic.com/research/constitutional-ai-harmlessness-from-ai-feedback">Anthropic's research overview</a>.</li>
<li><a href="https://docs.python.org/3/library/math.html#math.log1p">Python math.log1p</a>.</li>
</ul>
<p>AI assisted the wording of this article. Every Python block and assertion was executed and checked.</p>
]]></content:encoded></item><item><title><![CDATA[TensorDrill update: visual AI coding practice and interview labs]]></title><description><![CDATA[TensorDrill is a Python practice site for implementing AI components: Softmax, Attention, Transformers, diffusion, Flow Matching, agents, world models and more. It also has a separate set of exercises]]></description><link>https://ai-coding.hashnode.dev/tensordrill-update-visual-ai-coding-practice-and-interview-labs</link><guid isPermaLink="true">https://ai-coding.hashnode.dev/tensordrill-update-visual-ai-coding-practice-and-interview-labs</guid><category><![CDATA[Python]]></category><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[ym p]]></dc:creator><pubDate>Tue, 13 Oct 2026 16:23:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6acae344a92634871bd205b0/29c4ebe0-3fd9-46c9-9424-087fbfd925cb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://tensordrill.com/">TensorDrill</a> is a Python practice site for implementing AI components: Softmax, Attention, Transformers, diffusion, Flow Matching, agents, world models and more. It also has a separate set of exercises for working with existing code.</p>
<p>I'm building the project, and the latest update adds three interactive walkthroughs: <strong>Top-K token probabilities, classifier-free guidance (CFG), and global gradient clipping</strong>. Each connects a small numerical example to the function you implement, its tests, and a complete Python solution.</p>
<p>Here is what changed, with runnable examples of the ideas behind the visuals.</p>
<h2>Top-K probabilities: filtering is only half the job</h2>
<p>Suppose the logits are <code>[2, 4, 1, 3]</code> and <code>k = 2</code>. The retained token indices are <code>1</code> and <code>3</code>. Their final probabilities are approximately:</p>
<pre><code class="language-python">[0.0, 0.731059, 0.0, 0.268941]
</code></pre>
<p>Applying Softmax to the whole vocabulary and then zeroing the tail gives a different result: the surviving probability mass is about <code>0.880797</code>, rather than <code>1</code>. You still need to renormalize.</p>
<p>The new walkthrough places three bar charts side by side: full Softmax, the zeroed tail without renormalization, and the required Top-K output. Changing <code>k</code> makes the redistribution visible. All three charts use the same probability scale.</p>
<p>A complete implementation is small:</p>
<pre><code class="language-python">import math

def top_k_probabilities(logits, k):
    selected = sorted(range(len(logits)), key=lambda i: (-logits[i], i))[:k]
    peak = max(logits[i] for i in selected)
    weights = [math.exp(logits[i] - peak) for i in selected]
    total = sum(weights)
    result = [0.0] * len(logits)
    for index, weight in zip(selected, weights):
        result[index] = weight / total
    return result

assert top_k_probabilities([0, 2, 2, 2], 2) == [0.0, 0.5, 0.5, 0.0]
</code></pre>
<p>The tie rule matters: this exercise retains exactly <code>k</code> indices, preferring lower indices for equal logits. It returns probabilities in the original vocabulary order and does not sample a token. Library tie handling may differ.</p>
<p><a href="https://tensordrill.com/editorials/llm-topk-softmax/">Try the Top-K walkthrough</a>.</p>
<h2>CFG: see when interpolation becomes extrapolation</h2>
<p>The CFG exercise combines unconditional and conditional epsilon predictions at the same noisy input and timestep:</p>
<pre><code class="language-python">def cfg_epsilon(eps_uncond, eps_cond, guidance_scale):
    return [u + guidance_scale * (c - u) for u, c in zip(eps_uncond, eps_cond)]

assert cfg_epsilon([-1, 0], [1, 1], 0) == [-1, 0]
assert cfg_epsilon([-1, 0], [1, 1], 1) == [1, 1]
assert cfg_epsilon([-1, 0], [1, 1], 1.5) == [2, 1.5]
</code></pre>
<p>The two-dimensional view shows the two predictions and the combined result. Between <code>0</code> and <code>1</code>, the point interpolates. Above <code>1</code>, it continues beyond the conditional prediction. The table exposes the difference vector and its scaled contribution coordinate by coordinate.</p>
<p>This also makes a notation trap easier to explain. The expression <code>c + w * (c - u)</code> matches <code>u + s * (c - u)</code> when <code>s = 1 + w</code>. The same numeric scale is not interchangeable between the formulas.</p>
<p>The diagram is prediction space, not an image or a denoising trajectory. This helper does not run a model or a sampler, and increasing the scale does not guarantee better images.</p>
<p><a href="https://tensordrill.com/editorials/diffusion-cfg-epsilon/">Try the CFG walkthrough</a>.</p>
<h2>Global clipping: a vector norm is not a coordinate limit</h2>
<p>For a gradient <code>[3, 4]</code>, the L2 norm is <code>5</code>. With <code>max_norm = 2.5</code>, global clipping multiplies both coordinates by <code>0.5</code> and returns <code>[1.5, 2.0]</code>.</p>
<p>Clamping each coordinate separately instead gives <code>[2.5, 2.5]</code>. Its norm is about <code>3.535534</code>, still above the requested limit, and its direction has changed.</p>
<pre><code class="language-python">import math

def clip_global_norm(grad, max_norm):
    norm = math.sqrt(sum(value * value for value in grad))
    factor = min(1.0, max_norm / norm) if norm &gt; 0 else 1.0
    return [value * factor for value in grad]

assert clip_global_norm([3, 4], 2.5) == [1.5, 2.0]
assert clip_global_norm([0, 0], 2.5) == [0.0, 0.0]
assert clip_global_norm([], 2.5) == []
</code></pre>
<p>The visualization compares these operations against a circle whose radius is <code>max_norm</code>. Both axes use equal units, so the circle and vector directions remain meaningful. The displayed coordinate range adapts to the input and threshold; the axis ticks show that change.</p>
<p><a href="https://tensordrill.com/editorials/optimizer-global-norm-clipping/">Try the gradient-clipping walkthrough</a>.</p>
<h2>A second practice format: take over code, review a suggestion, test a change</h2>
<p>Implementing an AI component and safely changing an existing program exercise different skills. TensorDrill now has seven existing-code labs alongside the implementation problem bank.</p>
<p>Their workflow is:</p>
<ol>
<li><p>Read the task and existing implementation.</p>
</li>
<li><p>Review a preset AI suggestion and decide what it misses.</p>
</li>
<li><p>Debug, repair, or extend the program.</p>
</li>
<li><p>Run tests and check the behavior that must remain intact.</p>
</li>
</ol>
<p>Examples include maze traversal, load balancing, template rendering, and invoice pagination. The suggestions are preset teaching material; the site does not connect to a live AI assistant. These are original practice exercises, not a claim to offer official company interview questions.</p>
<p><a href="https://tensordrill.com/labs/">Explore the AI-assisted coding interview labs</a>.</p>
<h2>What stays practical</h2>
<p>The current implementation bank contains 100 Python challenges. Practice and reference solutions are free, the interface is available in English and Chinese, and Python runs in the browser. No sign-up or model API key is required. Progress is stored on the device, with export/import for backups.</p>
<p>Visual walkthroughs are available on selected problems; the rest of the bank has written explanations and reference code. The new three walkthroughs were checked with 1,085 numerical traces against Python references and independent formulas, including every reachable numerical control setting.</p>
<p>The goal is to make it easier to connect a formula, an implementation, and a test that would catch a plausible mistake. I plan to keep expanding the exercises and the visual explanations. Feedback on unclear examples or useful next topics is welcome.</p>
<h2>Further reading</h2>
<ul>
<li><p><a href="https://huggingface.co/blog/how-to-generate#top-k-sampling">Hugging Face: Top-K sampling and probability redistribution</a></p>
</li>
<li><p><a href="https://arxiv.org/abs/2207.12598">Ho and Salimans: Classifier-Free Diffusion Guidance</a></p>
</li>
<li><p><a href="https://huggingface.co/docs/diffusers/main/api/modular_diffusers/guiders#diffusers.ClassifierFreeGuidance">Diffusers: the two CFG scale conventions</a></p>
</li>
<li><p><a href="https://arxiv.org/abs/1211.5063">Pascanu et al.: On the difficulty of training Recurrent Neural Networks</a></p>
</li>
<li><p><a href="https://docs.pytorch.org/docs/main/generated/torch.nn.utils.clip_grad_norm_.html">PyTorch: global gradient norm clipping</a></p>
</li>
</ul>
<p>Writing assistance: this post was drafted with AI assistance. The numerical examples were checked against Python reference implementations.</p>
]]></content:encoded></item><item><title><![CDATA[Beyond LeetCode: Where to Practice AI Coding, from Attention to Flow Matching]]></title><description><![CDATA[There’s a particular kind of frustration that comes with learning AI.
You finish reading a tutorial on Transformers, understand the basic idea of Attention, and feel reasonably confident about the equ]]></description><link>https://ai-coding.hashnode.dev/beyond-leetcode-where-to-practice-ai-coding-from-attention-to-flow-matching</link><guid isPermaLink="true">https://ai-coding.hashnode.dev/beyond-leetcode-where-to-practice-ai-coding-from-attention-to-flow-matching</guid><dc:creator><![CDATA[ym p]]></dc:creator><pubDate>Sun, 11 Oct 2026 03:25:45 GMT</pubDate><content:encoded><![CDATA[<p>There’s a particular kind of frustration that comes with learning AI.</p>
<p>You finish reading a tutorial on Transformers, understand the basic idea of Attention, and feel reasonably confident about the equations. Then you open a blank Python file and try to implement it yourself.</p>
<p>Suddenly, things get complicated.</p>
<p>Which dimension should Softmax operate on? How exactly should the mask be applied? What happens when the input values become very large?</p>
<p>Understanding a concept and implementing it correctly are two different skills.</p>
<p>This gap becomes even more noticeable when moving beyond classical machine learning into areas like Diffusion Models, Flow Matching, AI Agents, and World Models.</p>
<p>That got me thinking: we have LeetCode for algorithms, but where do we go to practice the actual building blocks of modern AI?</p>
<p>There are already a few interesting platforms trying to answer that question, although they approach it in different ways.</p>
<ol>
<li>Four Platforms, Four Different Approaches</li>
</ol>
<p>Before getting into specific AI topics, it's worth looking at what different coding platforms are designed to teach.</p>
<p>Platform</p>
<p>Main Focus</p>
<p>What You Can Practice</p>
<p>LeetCode</p>
<p>Data structures and algorithms</p>
<p>General programming, algorithmic thinking, coding interviews</p>
<p>Deep-ML</p>
<p>Machine learning fundamentals</p>
<p>ML algorithms, mathematical operations, numerical implementations</p>
<p>TensorTonic</p>
<p>AI and ML engineering</p>
<p>Machine learning implementations, PyTorch, CUDA, Triton, and related technologies</p>
<p>TensorDrill</p>
<p>AI concepts from foundations to newer research topics</p>
<p>Transformer components, generative models, Agents, World Models, and more</p>
<p>I don't think there's a single winner here. The platforms serve somewhat different purposes.</p>
<p>LeetCode is still a great place to develop general programming skills. If you're preparing for software engineering interviews or want to get better at algorithms, it's hard to ignore.</p>
<p>Deep-ML brings the coding-challenge format into machine learning. Instead of solving another graph traversal problem, you might implement a numerical operation or an ML algorithm from scratch. It's a useful bridge between mathematical knowledge and working code.</p>
<p>TensorTonic is interesting for people who want to explore practical AI implementation across different technologies. In particular, PyTorch, CUDA, and Triton introduce a different set of engineering challenges from pure Python algorithm exercises.</p>
<p>TensorDrill takes a more topic-oriented approach, organizing small Python challenges around AI concepts, including some areas that appear frequently in recent research.</p>
<p>The important distinction isn't simply how many questions each platform offers. It's what kind of understanding you're trying to develop.</p>
<ol>
<li>Can Research Concepts Become Coding Challenges?</li>
</ol>
<p>At first, the idea of turning research topics into LeetCode-style problems might sound a little strange.</p>
<p>After all, a modern generative model can involve billions of parameters, distributed training, complicated data pipelines, and substantial GPU resources.</p>
<p>You obviously can't reproduce all of that in a ten-minute coding challenge.</p>
<p>But many of the underlying mechanisms are surprisingly small.</p>
<p>Consider a few examples.</p>
<p>Attention</p>
<p>You don't need to train a language model to implement Scaled Dot-Product Attention.</p>
<p>The core computation is:</p>
<p>[ \operatorname{Attention}(Q,K,V)=\operatorname{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V ]</p>
<p>Implementing this correctly forces you to think about tensor shapes, scaling, masks, and numerical stability.</p>
<p>Diffusion Models</p>
<p>You can explore diffusion without training an image generator.</p>
<p>For example, implementing the forward noising process, a noise prediction loss, or a DDIM sampling step helps connect the equations in a paper to executable operations.</p>
<p>AI Agents</p>
<p>Even though agents often involve large language models, many of their supporting mechanisms can be tested independently.</p>
<p>A ReAct trace parser, a tool-call validator, a retry policy, or a dependency-aware task scheduler can all become small programming exercises.</p>
<p>World Models</p>
<p>The same idea applies to world models.</p>
<p>State transitions, belief updates, trajectory rollouts, and planning objectives can be studied with compact numerical examples.</p>
<p>A particularly interesting exercise is comparing two predictive models: one might achieve a lower prediction error but still lead to worse planning decisions.</p>
<p>That is a concept worth understanding through code rather than simply memorizing as a statement.</p>
<p>The common theme is that you don't always need to build the entire system to understand one of its essential mechanisms.</p>
<ol>
<li>A Concrete Example: Learning Flow Matching Through Code</li>
</ol>
<p>Flow Matching is a good example because its core mathematics is elegant, yet implementation details can still be confusing.</p>
<p>Suppose we have two points, (x_0) and (x_1), and define a simple linear interpolation:</p>
<p>[ x_t=(1-t)x_0+tx_1 ]</p>
<p>The corresponding target velocity is:</p>
<p>[ u_t=x_1-x_0 ]</p>
<p>These two equations already suggest several useful exercises.</p>
<p>Exercise 1: Implement the interpolation.</p>
<p>Write a function that takes (x_0), (x_1), and (t), and returns (x_t).</p>
<p>Test the boundary cases. At (t=0), the result should be (x_0). At (t=1), it should be (x_1).</p>
<p>Exercise 2: Implement the target velocity.</p>
<p>For this particular linear path, the target velocity is constant.</p>
<p>A simple implementation can help you see why it does not depend on (t), even though the interpolated state does.</p>
<p>Exercise 3: Implement a velocity regression loss.</p>
<p>Given predicted velocities and target velocities, compute a mean squared error objective.</p>
<p>Pay attention to reduction conventions and tensor shapes.</p>
<p>Exercise 4: Implement a numerical ODE solver.</p>
<p>Start with the Euler method, then try Heun's method.</p>
<p>Compare the approximation errors on a velocity field with a known solution.</p>
<p>None of these exercises requires training a full generative model.</p>
<p>Yet together, they provide a much clearer understanding of what happens inside a Flow Matching implementation.</p>
<p>And once you've worked through them, reading a more complete paper or codebase becomes easier because the individual operations are already familiar.</p>
<p>This is the kind of progression I find useful: start with a small mathematical mechanism, implement it, verify it, and only then move to the larger architecture.</p>
<ol>
<li>The Most Useful Part of a Coding Problem Might Be the Explanation</li>
</ol>
<p>Online judges are good at answering one question:</p>
<p>Does this implementation produce the expected output?</p>
<p>But when learning AI, that's only part of what matters.</p>
<p>Suppose you're implementing Softmax.</p>
<p>You know the formula:</p>
<p>[ \operatorname{softmax}(x_i)=\frac{e^{x_i}}{\sum_j e^{x_j}} ]</p>
<p>A straightforward implementation might appear correct for ordinary inputs.</p>
<p>But what happens when an input contains a value like 1000?</p>
<p>Directly computing its exponential can overflow.</p>
<p>A more numerically stable implementation subtracts the maximum value before exponentiation.</p>
<p>This is a small implementation detail, but it's also an important general lesson about numerical computing.</p>
<p>A good coding exercise should help you understand both the mathematical operation and the engineering decisions needed to implement it reliably.</p>
<p>That is why I prefer exercises that provide more than a reference solution.</p>
<p>Ideally, they should explain the mathematical reasoning, important edge cases, complexity considerations, and common implementation mistakes.</p>
<p>For example, if an Attention implementation fails a test, it's much more helpful to understand whether the problem comes from an incorrect mask, a shape mismatch, or numerical instability than to receive a generic "Wrong Answer."</p>
<p>The goal shouldn't be to memorize solutions. It should be to understand why one implementation works and another doesn't.</p>
<ol>
<li>Why Actually Running the Code Matters</li>
</ol>
<p>There's also a meaningful difference between answering a conceptual question and implementing the concept correctly.</p>
<p>Someone might easily explain why we divide Attention scores by (\sqrt{d_k}).</p>
<p>But can they implement Attention correctly with a causal mask?</p>
<p>Can they handle batch dimensions?</p>
<p>Can they write a Softmax function that remains stable with large inputs?</p>
<p>Those details are difficult to evaluate through multiple-choice questions alone.</p>
<p>With executable coding exercises, the feedback loop is more concrete:</p>
<p>Write code → Run tests → Inspect failures → Revise → Understand</p>
<p>The tests themselves matter, too.</p>
<p>An implementation that passes one example isn't necessarily correct. Good test cases should include boundary conditions and common mistakes, rather than checking only the most straightforward input.</p>
<p>One approach I've been exploring with TensorDrill is keeping the exercises small enough to run directly in the browser while providing reference implementations and detailed explanations.</p>
<p>As of October 2026, the project includes 100 Python challenges, 26 concept pages, and 19 practice sets. Its reference implementations have been checked against 553 assertions, along with tests designed to reject 91 deliberately incorrect implementations.</p>
<p>Those numbers don't guarantee that every edge case has been covered, but they reflect an attempt to treat test quality as part of the learning experience.</p>
<p>There are trade-offs, of course.</p>
<p>The platform currently runs Python locally in the browser, and its tests are public. That's convenient for practicing and debugging, but it isn't the same as a secure competitive programming judge with private tests.</p>
<p>It also isn't a replacement for a proper PyTorch or GPU environment when you need to train models or optimize large computational kernels.</p>
<p>For learning individual concepts, though, small executable exercises can be a useful intermediate step.</p>
<ol>
<li>How I Would Structure an AI Coding Practice Roadmap</li>
</ol>
<p>If you're trying to learn AI through programming, I wouldn't recommend jumping randomly between unrelated topics.</p>
<p>There's a natural dependency structure worth following.</p>
<p>Start With Numerical Foundations</p>
<p>Before worrying about the latest model architecture, make sure you're comfortable implementing basic operations.</p>
<p>Matrix multiplication, normalization, Softmax, gradients, and optimization algorithms appear across a huge range of AI systems.</p>
<p>Being able to implement and debug them is useful almost everywhere.</p>
<p>Move to Transformer Components</p>
<p>Once the foundations are in place, start exploring Attention, causal masking, multi-head operations, positional embeddings such as RoPE, and feed-forward components such as SwiGLU.</p>
<p>These exercises help turn a Transformer from a complicated diagram into a collection of understandable computations.</p>
<p>Explore Generative Modeling</p>
<p>From there, move into VAEs, GANs, Diffusion Models, DDPM/DDIM sampling, and Flow Matching.</p>
<p>Try to connect the underlying mathematics rather than treating every new model family as an entirely separate subject.</p>
<p>Numerical integration is especially useful to understand because it appears in several continuous-time generative modeling approaches.</p>
<p>Then Explore Agents and World Models</p>
<p>Finally, consider mechanisms such as tool calling, ReAct execution, retrieval evaluation, state transitions, trajectory rollouts, and planning.</p>
<p>These topics are particularly interesting because they connect mathematical predictions and model outputs to actual decisions and actions.</p>
<p>Of course, this is just one possible path.</p>
<p>If you're already comfortable with the fundamentals, you can jump directly into a topic that matches your interests.</p>
<p>The important thing is to build connections between concepts instead of collecting isolated solutions.</p>
<ol>
<li>So Which Platform Should You Use?</li>
</ol>
<p>It really depends on what you're trying to get better at.</p>
<p>If you're preparing for a conventional coding interview, LeetCode is probably the most obvious starting point.</p>
<p>If you want to strengthen your understanding of classical machine learning through implementation, Deep-ML is worth checking out.</p>
<p>If you're more interested in AI systems engineering or lower-level implementation technologies, TensorTonic may be a better fit.</p>
<p>And if you're looking for topic-based exercises that extend from AI fundamentals into Transformers, generative models, agents, and world models, TensorDrill is another option to explore.</p>
<p>These platforms can also complement one another.</p>
<p>You might practice general algorithms on LeetCode, implement numerical ML operations on Deep-ML, explore different engineering stacks through TensorTonic, and work through modern AI components on TensorDrill.</p>
<p>What matters most is choosing exercises that expose the gaps in your understanding.</p>
<p>Final Thoughts</p>
<p>AI moves quickly. New model architectures, training methods, and agent frameworks appear all the time.</p>
<p>Trying to keep up by reading every new paper is difficult enough.</p>
<p>But reading alone doesn't always translate into practical understanding.</p>
<p>For me, a more useful question is:</p>
<p>Can I take a mathematical equation or model component, implement it without copying the original code, and verify that it behaves as expected?</p>
<p>If the answer is yes, I've probably learned something meaningful.</p>
<p>If not, I've found a gap worth working on.</p>
<p>That's what makes small, well-designed coding challenges valuable, even in research areas that normally involve enormous models and complicated infrastructure.</p>
<p>Sometimes the best way to understand a complicated AI system is to start by implementing one small piece of it.</p>
]]></content:encoded></item></channel></rss>