« Phase 32 README · Warmup · Deep Dive · Principal Deep Dive · Core Contributor · Staff Notes
Phase 32 — Hitchhiker's Guide
The compressed practitioner tour. Read the WARMUP for the mechanism; this is the stuff you say in the meeting and type from memory.
30-second mental model
ML is function approximation, sorted by what supervises it: supervised (labels), unsupervised (structure), self-supervised (the data predicts itself), reinforcement (delayed reward). Almost every model trains by the same loop — forward → loss → backward → step — and the whole game is generalization: fit the signal, not the noise, and prove it on data you didn't train on. You place the problem in the taxonomy, engineer features without leaking the future, build and train a baseline (logistic regression / a GBM before anything fancy), evaluate with metrics that survive class imbalance, and tune hyperparameters on validation — never the test set. TensorFlow vs PyTorch is an ecosystem choice, not a concept difference. The deep-net internals (attention, autograd engines) are the Senior AI Engineer track; here you own the applied craft.
The numbers and rules to tattoo on your arm
| Thing | The rule |
|---|---|
| Logistic-regression gradient | ∂L/∂z = p − y (prediction error is the gradient) |
| Adam defaults | lr≈3e-4, β1=0.9, β2=0.999; tune LR on a log scale |
| Mini-batch size | 32–512 typical; bigger = smoother gradient, less noise |
| L2 gradient term | + λw (weight decay); L1 term ± λ (drives to zero → sparse) |
| Early stopping | monitor val loss, patience epochs, restore best weights |
| Bias vs variance | train high + val high = underfit; train low + val high = overfit |
| Bellman/Q-learning | Q ← Q + α[r + γ·max Q(s′,·) − Q]; the max = off-policy |
| UCB1 | pick argmax of x̄ + c·√(ln t / n); no randomness, log regret |
| Imbalance metrics | drop accuracy; use precision/recall/F1, PR-AUC over ROC-AUC |
| R² | 1 perfect, 0 = predicting the mean, <0 = worse than the mean |
| The cardinal sin | tuning (or any peeking) on the test set — open it once |
The framework skeletons to know cold
PyTorch — you write the loop:
import torch
from torch import nn
model = nn.Sequential(nn.Linear(d, 64), nn.ReLU(), nn.Linear(64, 1))
criterion = nn.BCEWithLogitsLoss() # sigmoid + BCE, numerically stable
optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=1e-2)
best_val, patience, wait = float("inf"), 5, 0
for epoch in range(max_epochs):
model.train()
for xb, yb in train_loader: # DataLoader(shuffle=True, seeded generator)
optimizer.zero_grad() # grads ACCUMULATE — clear them every step
loss = criterion(model(xb), yb) # forward + loss
loss.backward() # backward: autograd fills param.grad
optimizer.step() # step: update from grads
model.eval() # dropout/batchnorm switch to inference mode
with torch.no_grad():
val = sum(criterion(model(xb), yb).item() for xb, yb in val_loader) / len(val_loader)
if val < best_val - 1e-4:
best_val, wait, best = val, 0, {k: v.clone() for k, v in model.state_dict().items()}
else:
wait += 1
if wait >= patience: # early stop, restore best
model.load_state_dict(best); break
Keras (.fit) — the trainer writes the loop:
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([layers.Dense(64, activation="relu"), layers.Dense(1, activation="sigmoid")])
model.compile(optimizer=keras.optimizers.AdamW(3e-4), loss="binary_crossentropy",
metrics=["accuracy", keras.metrics.AUC(name="pr_auc", curve="PR")])
model.fit(train_ds, validation_data=val_ds, epochs=max_epochs,
callbacks=[keras.callbacks.EarlyStopping(monitor="val_loss", patience=5,
min_delta=1e-4, restore_best_weights=True)])
Same four steps either way; Lab 01 is that loop in pure Python so you can see it. The tf.function
graph-capture, GradientTape custom loop, and torch.compile variants exist too — reach for them
when you need speed or a nonstandard step.
The distinctions that signal seniority
- Supervised vs unsupervised vs RL → labels vs structure vs delayed reward. Name the signal you actually have, not the algorithm you want to use.
- Bias vs variance → too-rigid model vs noise-memorizing model; read it off the train/val gap, respond with the matching lever. "More data" only fixes variance.
- L1 vs L2 → L1's constant-magnitude gradient zeroes weights (sparsity/selection); L2's proportional gradient shrinks them smoothly (the default). Different jobs.
- Q-learning vs SARSA →
max(off-policy, learns optimal values while exploring; makes replay buffers legal) vs actually-taken action (on-policy, values include exploration cost). - ε-greedy vs UCB → fixed random exploration tax forever vs a confidence bonus that shrinks with evidence. UCB wastes fewer pulls and is deterministic.
- ROC-AUC vs PR-AUC → under rare positives ROC flatters (huge negative denominator hides the false positives); PR-AUC tells the truth.
- Accuracy vs F1 → accuracy is the class ratio in disguise under imbalance; F1 balances the two error types you actually pay for.
- TF
tf.functionvs PyTorchtorch.compile→ graph-capture-from-eager, arrived at from opposite directions. Both now do eager-dev / compiled-prod. "TF is graphs, PyTorch is eager" is a decade stale. - PCA vs feature selection → PCA finds high-variance directions (unsupervised, ignores your target); selection keeps original features that predict the target. Not the same tool.
War stories
- The 0.99 AUC that was leakage. A churn model shipped with a near-perfect offline AUC and
flatlined in production. A feature was
days_since_account_closed— a consequence of churning. Target leakage: information present in training that doesn't exist at prediction time. Now any suspiciously predictive feature is guilty until audited. - The scaler fit on the whole dataset. Standardization was computed over all rows before the
train/test split, so test statistics bled into training. Offline numbers looked great, prod was
worse, and nobody could explain the gap. Fit transforms inside the training fold only —
Pipelineinside cross-validation exists for exactly this. - "We're getting throttled, add retries" — no, tune the learning rate. A team fought a loss that
went
NaNon epoch two by lowering batch size, adding gradient clipping, swapping optimizers — the fix was the learning rate was 10× too high. LossNaN/ diverging is LR first, almost every time. - The clustering that found the units, not the clusters. k-means on unscaled features put 99% of
the distance into
annual_income(range 0–200,000) and ignored everything else. Standardize before any distance-based method — k-means, kNN, SVM, PCA. - The Atari agent that "wouldn't learn." Reward stayed flat for thousands of episodes — ε was fixed at 0.01, so it barely explored a sparse-reward grid. Bumping exploration (and annealing it) fixed it in an afternoon. Exploration is a knob, not a default.
Vocabulary
supervised / unsupervised / self-supervised / reinforcement · classification / regression
· bias-variance · over/underfitting · regularization (L1/L2/dropout/early-stopping) ·
loss (MSE / MAE / cross-entropy / hinge) · gradient descent (batch/SGD/mini-batch) ·
momentum / Adam / AdamW · learning rate / schedule / warmup · forward-loss-backward-step
· autograd / backward() / GradientTape · k-means / k-means++ / inertia / silhouette ·
hierarchical / GMM / EM · PCA / eigenvector / power iteration / reconstruction error ·
MDP / policy / value / Q-function / Bellman / TD error · Q-learning (off-policy) / SARSA
(on-policy) · ε-greedy / UCB / exploration-exploitation / bandit · DQN / policy gradient /
PPO / RLHF · MLP / CNN / RNN / LSTM / Transformer · activation (ReLU/GELU/softmax) ·
Xavier/He init · batch/layer norm · feature engineering / encoding / scaling /
imputation · data leakage · train/val/test / k-fold CV / stratified · precision /
recall / F1 / ROC-AUC / PR-AUC / confusion matrix · grid / random / Bayesian / Hyperband ·
nn.Module / Keras .fit / tf.function / torch.compile · TorchServe / TF Serving /
LiteRT / ExecuTorch · JAX.
Beginner mistakes
- Reporting accuracy on an imbalanced dataset (and celebrating the class ratio).
- Fitting scalers/encoders/selection on data that includes val/test rows (leakage).
- Random-splitting time-series data — the model trains on the future.
- Tuning against the test set, then quoting that number as generalization.
- Forgetting
model.eval()/training=Falseat inference — dropout and batchnorm misbehave. - Forgetting
optimizer.zero_grad()in PyTorch — gradients accumulate across steps. - Skipping feature scaling before k-means / kNN / SVM / PCA.
- Reaching for a neural net on 500 rows of tabular data instead of a GBM or logistic regression.
- Treating one lucky seed as a result; a real comparison reports mean ± std over seeds.
- Confusing PCA (unsupervised variance directions) with feature selection for a target.