SR
ML Playbook / say it out loud

Answers you can say, not topics you recognise

Covers the full ML engineer loop. Every entry is written as the sentence you speak in the room. Questions are collapsed by default so you test recall instead of re-reading. The amber cards are traps — questions where the obvious answer is wrong.

Test mode

Read the question, answer it out loud, then open the card. If you couldn't say it, you don't have it.

Mark the shaky ones

Hit Mark for review inside a card, then filter to just those on the second pass.

One hour?

Skim Ground floor, then attention, then LLMs & agents, then RAG. Skip the rest.

Read this first

The protocol for when you don't know

This matters more than any single concept, because you are always one question from the edge of what you know, and how you behave at that edge is most of what is being measured.

A gap is not what loses an interview. Everyone has gaps. What loses it is the gap turning into silence, because silence reads as this person cannot think when they are stuck — a far worse signal than this person has not memorised the softmax scaling.

Three moves, in order

  1. Reason out loud from what you do know. "I don't remember the exact form, let me work it out from the shapes." An interviewer would much rather watch you derive something half-right than watch you freeze. You cannot demonstrate reasoning while silent.
  2. If you truly don't know, say so in one sentence and offer the nearest thing you do. "I haven't worked with that — closest I've done is X, is that useful?" Then stop. No second apology, no explanation of why you don't know it.
  3. Ask them to narrow it. "Which part do you mean?" is legitimate, not a dodge. Half the time the question was broader than you thought.
Never

Go quiet. Guess confidently and get caught. Start apologising for your background. One honest "I don't know" costs almost nothing; three minutes of visible panic costs the interview.

The allocation lesson

A week on the paper and one midnight pass on fundamentals is backwards. The paper is the visible thing, so it attracts the time — but an interviewer can only test what they can ask in sixty seconds, which means fundamentals get asked far more often than papers do. Fundamentals first, always, then the specific material.

Ground floor

The words everyone assumes you know

These get asked because they're assumed. Fumbling "what's a token" is worse than missing something advanced, because it reads as not having the ground under you. Each of these should take you one sentence.

TEXT "tokenising" TOKENS token is ing sub-word pieces, not words ~4 characters of English each lookup EMBEDDINGS one learned vector per token this is where meaning lives model the weights LOGITS raw scores, one per vocabulary entry. can be negative softmax PROBS non-negative, sum to 1 Five words, one chain. Token — a sub-word chunk of text, the unit the model actually reads. Embedding — the learned vector that token maps to. Logits — the model's raw, unbounded output scores. Softmax — exponentiate and normalise, turning scores into probabilities. Vocabulary — the fixed set of tokens the model knows; the output layer has one logit for each.
Text in, probabilities out. If you can narrate this chain you have answered four or five of the most common warm-up questions at once.
What is a token?

The unit of text a language model actually reads. Text is split into sub-word pieces by an algorithm like byte-pair encoding: start from characters and repeatedly merge the most frequent adjacent pair until you reach a fixed vocabulary size.

Common words end up as a single token; rare ones break into several. Rough rule: one token is about four characters of English, so roughly 0.75 words.

Trick Is a token the same as a word?

No. "Tokenising" might be three tokens; "the" is one; an emoji can be several; and a space usually attaches to the front of the following token.

Two consequences worth naming, because they explain real behaviour:

  • Numbers tokenise badly — digits get chopped inconsistently, which is part of why models are weak at arithmetic.
  • Non-English text costs more tokens per word, so the same content is more expensive and eats more context.
What is an embedding?

A learned vector that represents a discrete thing — a token, a patch, an entire image — as a point in a continuous space. The embedding table is a lookup: token id in, vector out.

The useful property is that geometry carries meaning: similar things land near each other, so distance and direction in that space are informative. That's what makes "representation" a meaningful word rather than jargon.

Trick Are logits probabilities?

No. Logits are the raw, unbounded real-valued outputs of the final layer — they can be negative and they don't sum to anything in particular. Softmax turns them into probabilities.

Why it matters practically: loss functions in PyTorch like CrossEntropyLoss expect logits, not softmaxed probabilities, because they apply the softmax internally in a numerically stable way. Applying softmax yourself first is a common and quiet bug.

Trick Is softmax just normalising the numbers?

No — it exponentiates first, then normalises. That's the whole character of it: the exponential amplifies differences, so a modest lead in the logits becomes a large lead in probability. Plain normalisation would preserve the ratios and would break on negative values.

The exponential is also why large logits saturate it, which is the reason attention divides by √dk.

Parameter versus hyperparameter?

Parameters are learned by the optimiser from data — the weights and biases. Hyperparameters are set by you before or around training — learning rate, batch size, number of layers, weight decay, how long to train.

The clean test: did gradient descent choose it? Then it's a parameter. Learning rate is a hyperparameter, which is why it's tuned on the validation set and not learned.

What is a tensor, and what is a channel?

A tensor is just an n-dimensional array. Scalar, vector, matrix, then everything above. A batch of RGB images is a 4D tensor shaped (batch, channels, height, width).

A channel is one feature map at every spatial position — the 3 of RGB at the input, and after a conv layer, one channel per learned filter. "64 channels" means 64 different learned feature detectors, each giving a value at every location.

The training loop

batch of data 1 forward compute output 2 loss vs ground truth 3 backward chain rule → grads 4 optimiser updates weights repeat — one pass through all the data = one EPOCH Backprop computes the gradients. The optimiser applies the update. They are two different steps. Conflating them is one of the most common sloppy answers, and separating them cleanly reads as precision. Batch — the group of samples in one step. Iteration / step — one pass of this loop, one weight update. Epoch — one full sweep through the training set. 1000 samples, batch 100 → 10 iterations = 1 epoch.
Four steps, repeated. Almost every basic question about training is a question about where in this loop something happens.
Trick Does backpropagation update the weights?

No — it computes the gradients. Backprop is the chain rule applied efficiently backwards through the computation graph, producing ∂loss/∂parameter for every parameter. The optimiser (SGD, Adam) is what then uses those gradients to change the weights.

In PyTorch this is literally two calls: loss.backward() then optimizer.step(). Separating them cleanly sounds precise; conflating them sounds vague.

What is a gradient, in plain words?

The vector of partial derivatives of the loss with respect to every parameter. It points in the direction of steepest increase of the loss, which is why you step in the negative gradient direction.

Practically: each component says "if I nudge this one weight up slightly, how much does the loss change, and in which direction".

Epoch, batch, iteration — distinguish them.

Batch is the group of samples processed together in one step. Iteration (or step) is one forward-backward-update cycle, so one weight update. Epoch is one full pass through the training set.

1000 samples at batch size 100 gives 10 iterations per epoch. People mix up epoch and iteration constantly.

Trick What is a deep network with no activation function?

A single linear layer. The composition of linear maps is itself linear, so stacking fifty of them gives you exactly the expressive power of one — you've just factorised one matrix into fifty, at enormous cost.

Non-linearity is the entire reason depth buys anything. ReLU is the standard choice because it's cheap and doesn't saturate for positive inputs, unlike sigmoid and tanh which squash into a bounded range and kill gradients at the extremes.

Training versus inference?

Training: forward pass, loss, backward pass, update. Gradients are computed and stored, so memory use is much higher. Dropout is active, BatchNorm uses batch statistics.

Inference: forward pass only. No gradients (torch.no_grad()), dropout off, BatchNorm using running averages. This is what model.eval() switches — forgetting it is a classic bug that shows up as noisy or shifted predictions.

The vocabulary, compactly

TermIn one sentence
Ground truth / labelThe correct answer you train against. In imaging it's an annotation someone drew, which means it carries human error and inter-observer variability.
FeatureAny measured or computed quantity the model uses. A feature map is the spatial grid of one such quantity inside a CNN.
Latent / representationAn internal learned encoding — not the input, not the output, the compressed thing in between.
Architecture vs model vs checkpointArchitecture is the structure; model is architecture plus trained weights; checkpoint is the saved weights file.
Pre-training vs fine-tuningPre-training learns general representations on a large corpus; fine-tuning adapts that model to your specific task with far less data.
Zero-shot / few-shotPerforming a task with no examples, or a handful given in the prompt — with no weight updates in either case.
End-to-endOne model trained jointly from raw input to final output, with gradients flowing all the way through, rather than separately trained stages bolted together.
Inductive biasAssumptions baked into the architecture. Convolution assumes locality and translation equivariance; attention assumes very little, which is why it needs more data.

Learning paradigms

ParadigmWhat the supervision is
SupervisedHuman-provided labels for every example.
UnsupervisedNo labels at all — clustering, density estimation.
Self-supervisedLabels manufactured from the data itself (predict the masked part, match two views). Then fine-tune on a small labelled set.
Semi-supervisedA small labelled set plus a large unlabelled one, used together. Common in medical imaging, where labels are expensive.
ReinforcementNo labels, only a reward signal from acting in an environment.

Task types

TaskOutput
ClassificationOne label for the whole input. Is there a tumour?
RegressionA continuous number. How large is it?
DetectionBoxes plus labels. Where are the lesions?
SegmentationA label per pixel or voxel. Which exact voxels are tumour?
RegistrationA transformation aligning one image to another.
GenerationA new sample from the learned distribution.

The one that cost you

Attention, until it is boring

Attention(Q, K, V) = softmax ( QKT√dk ) V

Three learned projections, one similarity matrix, one weighted average.

TOKENS x₁ x₂ x₃ x₄ n × d W_Q W_K W_V Q K V what I'm looking for what I advertise what I pass on QKᵀ SCORES n × n every token vs every token ÷√d softmax per row WEIGHTS each row sums to 1 × V OUTPUT z₁ z₂ z₃ z₄ n × d Each output token is a weighted average of every token's value vector. The weights come from how well that token's query matches each token's key. Nothing is learned in the softmax or the mixing — all the learning lives in W_Q, W_K, W_V. × h HEADS head concat W_O d_k = d/h, so cost is unchanged
One head, start to finish. Read it left to right and narrate as you draw: tokens, three projections, scores, scale and softmax, weighted sum of values. Multi-head runs this h times in parallel with different projections, concatenates, and applies one more linear layer.
The spoken answer — about forty seconds

Every token produces three vectors by multiplying its embedding with three learned matrices: a query, a key and a value. The query is what this token is looking for, the key is what it advertises about itself, the value is what it passes on if attended to.

To get the new representation of a token, you dot its query with every token's key. That gives a score per token. You divide by the square root of the key dimension, softmax the scores so they become weights summing to one, then take the weighted sum of all the value vectors. So each token's output is a mixture of every token's value, weighted by how much it cares about them.

That's one head. Multi-head does several in parallel with different projections, concatenates them, and passes the result through one more linear layer, so different heads can specialise.

If they hand you a marker

input n × d W Q n × dₖ K n × dₖ V n × dᵥ QKᵀ scores n × n × V output n × d If you blank: "let me build it up from the shapes"
The shapes walk you to the answer. If you lose the thread, write the dimensions. An interviewer watching you reason from shapes sees competence, not a gap.

Questions

Why divide by the square root of dk?

Dot products of two random vectors of dimension dk have variance proportional to dk, so the standard deviation grows like √dk. Large scores push the softmax toward a one-hot distribution, where it saturates and its gradient goes to almost zero.

Say "so the gradients don't vanish" — that is the point. Dividing by √dk keeps the score variance near 1, where softmax still learns.

Trick Why √dk rather than dk?

Because the variance scales with dk, so the standard deviation — the scale the numbers actually live on — scales with √dk. You normalise by the standard deviation, not the variance. Dividing by dk would over-shrink the scores and flatten the attention distribution toward uniform.

What is the computational complexity?

O(n²d) time and O(n²) memory in the sequence length n. QKᵀ multiplies n × dk by dk × n, producing an n × n matrix.

That quadratic cost is why long context was hard, why flash attention exists (same maths, tiled so the n × n matrix is never materialised), and why linear-attention approximations get written.

Trick Is multi-head attention more expensive than single-head?

No — roughly the same. The usual setup is dk = dmodel / h, so each head works in a smaller subspace and the total work across h heads matches one full-width head.

You get specialisation for free. That is the actual argument for multi-head, not extra capacity.

Trick Is self-attention permutation invariant?

Equivariant, not invariant. Shuffle the input tokens and you get the same outputs, shuffled the same way. An invariant function would return an identical result regardless of order.

This is exactly why positional encoding has to be added separately — attention has no notion of order on its own.

Self-attention versus cross-attention?

In self-attention, Q, K and V all come from the same sequence — tokens attend to each other. In cross-attention, Q comes from one sequence while K and V come from another.

Cross-attention is how a decoder reads an encoder, and how modules in a perception stack read a shared feature map: the queries are the module's own, the keys and values come from the shared representation.

What is causal / masked attention and why does it matter?

Before the softmax, you add −∞ to the scores at positions a token isn't allowed to see — future positions in a language model, or padding. After softmax those weights are exactly zero.

This is what makes a decoder autoregressive, and it is why training is parallel across all positions while generation is sequential: during training the whole target sequence is present and masked, but at inference each token must exist before the next can attend to it.

CAUSAL MASK −∞ −∞ query row i attends only to keys j ≤ i Training whole sequence present, mask applied, all positions computed in parallel Generation strictly one token at a time — the KV cache exists because of this asymmetry
The mask is why training parallelises and generation doesn't. A very common follow-up, and the answer most people half-know.
Trick Does attention have learnable parameters in the softmax?

No. The softmax, the scaling and the weighted sum are all parameter-free. Every learned parameter in an attention block sits in the projections WQ, WK, WV and the output projection WO.

Good follow-on: the mixing operation itself is fixed; what the model learns is what to compare and what to pass along.

Why attention instead of an RNN?

Give both reasons. Path length: every position reaches every other in one step rather than through n sequential hops, so long-range dependencies don't have to survive a chain of updates. Parallelism: it's a couple of matrix multiplications, so training parallelises across the sequence, which an RNN fundamentally cannot.

Everything around attention

The rest of the transformer

RESIDUAL STREAM input LayerNorm Attention mixes BETWEEN tokens + LayerNorm FFN processes EACH token alone d → 4d → d + output Most parameters live in the FFN, not attention. People reliably guess the opposite.
Pre-norm block. Attention mixes information between tokens; the feed-forward network transforms each token independently. The residual stream is the shared workspace each block reads from and writes back into.

Questions

How does position get into a transformer?

Separately, because attention is permutation-equivariant. Three flavours worth naming:

  • Sinusoidal — fixed, different frequencies, lets the model read relative offsets.
  • Learned absolute — one vector per position. Simple, doesn't extrapolate past the trained length.
  • RoPE (rotary) — rotates Q and K by an angle proportional to position, so the dot product between two tokens depends only on their relative distance. What most current LLMs use.

Naming RoPE signals you're current.

Why LayerNorm rather than BatchNorm in a transformer?

LayerNorm normalises across the feature dimension within one token, independently of other samples. BatchNorm normalises each feature across the batch, so it depends on batch composition, needs running statistics at inference, and breaks with variable sequence lengths and small batches.

You want inference to be independent of what else is in the batch. Hence LayerNorm. RMSNorm is the cheaper modern variant that drops mean-centring.

Pre-norm or post-norm, and does it matter?

The original paper was post-norm: LayerNorm(x + sublayer(x)). Current practice is pre-norm: x + sublayer(LayerNorm(x)).

It matters a lot. Pre-norm leaves a clean identity path down the residual stream, so deep stacks train stably without delicate learning-rate warmup. Post-norm at depth is notoriously fragile.

Trick Where do most of a transformer's parameters live?

The feed-forward network, not attention. The FFN expands to roughly 4× the model dimension and back, which is about 8d² parameters per block, against roughly 4d² for the four attention projections.

Almost everyone guesses attention, because that's the part that gets talked about.

Trick Does the KV cache speed up training?

No. It only helps autoregressive generation. During training the full sequence is available at once and processed in parallel, so there is nothing to cache across steps.

Worth adding: for long contexts the KV cache, not the weights, is usually what fills the GPU — it grows with sequence length × layers × heads.

Encoder-only, decoder-only, encoder-decoder — what's the difference?
  • Encoder-only (BERT): bidirectional, trained by masked prediction. Classification, embeddings.
  • Decoder-only (GPT, Llama): causally masked, next-token prediction. Every modern LLM.
  • Encoder-decoder (T5, the original): encodes one sequence, generates another, with cross-attention between them. Translation, and the structure perception stacks borrow.
What is a vision transformer, in one line?

Cut the image into patches (16×16, say), linearly embed each patch as a token, add positional embeddings, run a standard transformer. The only real change from text is how you make tokens.

Today's interview

LLMs and agents

OPEN LOOP — BARE LLM prompt LLM answer done. no way to find out if it was right CLOSED LOOP — AGENT LLM decides next action tool call Harness plain code. executes. World API, file, optimiser observation — what actually happened State what's been tried current status budget left Stop when goal met / budget spent / no progress The LLM never acts. It emits text. The harness decides whether to honour it and executes. That separation is where all safety lives — it's the only part you control. The defining line: who chooses the next action at runtime. Programmer chose it in advance → pipeline. Model chooses while running → agent.
The whole difference is the feedback edge. A bare model answers and stops. An agent acts, sees the result, and revises — so it only has to be approximately right each step and able to recognise its own mistakes.
The crisp version

A language model maps text to text in one pass, so it can't take actions, can't reach anything it wasn't trained on, and can't tell whether it was right. An agent wraps it in a loop with tools: the model proposes an action, the harness executes it, the result comes back, and the model decides what to do next. The point is the feedback — it means the model only has to be approximately right each step rather than correct first time. That's a much lower bar, which is why it works.

Why the loop buys so much

Verifying is easier than producing

A bare LLM has to know the answer. An agent only has to recognise a good answer when it sees one, and be able to try again. Writing correct SQL from scratch is hard; noticing your query returned zero rows is easy. Wherever checking is cheaper than solving, the loop converts a knowledge problem into a search problem.

Reliability compounds

95% reliable per step, twenty steps blind → about 36% success. Errors multiply. A 95%-per-step model with a working feedback loop beats a 99%-per-step model without one on any long task.

Questions

Trick Does the LLM execute the tool?

No. The harness does. The model emits a structured request — a name and JSON arguments — and ordinary code decides whether to honour it, validates the arguments, executes, and appends the result to the context.

This is the most important architectural fact about agents and the one that makes safety tractable. If asked about safety, the answer is structural: you constrain what the harness will execute, not what the model is willing to ask for.

Trick Does temperature 0 make an agent deterministic?

No. Greedy decoding removes sampling noise from the model, but an agent trajectory still varies: tool results change, timing and ordering change, floating-point non-determinism on GPU changes logits at the margin, and one different token early sends the whole trajectory elsewhere.

Which is exactly why you run each case several times and report the spread, not a single number. Most published agent work is weak here — saying so is cheap and marks you out.

Trick Is a fixed pipeline that calls an LLM several times an agent?

No. If you wrote the order of operations in advance, it's a pipeline. It becomes an agent when the model chooses what to do next and when to stop, at runtime.

That's the cleanest available definition of "agentic", and a good answer to a vague question.

What is perplexity?

The exponential of the mean cross-entropy loss. Loosely: how many tokens the model is effectively choosing between at each step. Lower is better.

And the thing to add: perplexity measures prediction, not truthfulness. A model can get dramatically better at predicting the next token and no better at being right.

Prompting, RAG, LoRA or full fine-tuning — how do you choose?
OptionWhat it isWhen
PromptingInstructions and examples in contextDefault. Always try first
RAGRetrieve documents, put them in contextKnowledge lives in documents and changes
LoRA / PEFTFreeze the base, train small low-rank matricesBehaviour change, thousands of examples
Full fine-tuneUpdate everythingRarely worth it; can degrade general ability
Trick Is fine-tuning a good way to add knowledge?

Not really — it's much better for behaviour, format and style than for facts. Facts injected by fine-tuning are learned unreliably, can't be updated without retraining, and don't come with a citation. Retrieval is the right tool for knowledge.

A common follow-up is whether RAG is a kind of fine-tuning. It isn't — the weights never change.

Trick Does more context always help?

No. Three reasons: attention is quadratic so cost rises sharply; the KV cache grows linearly and fills memory; and retrieval quality degrades in the middle of very long contexts, the "lost in the middle" effect.

The engineering answer is to keep structured state outside the model and feed it a compact view.

Name the agent loop patterns.
  • ReAct — interleave reasoning, action, observation. The default.
  • Plan-and-execute — commit to a plan first. More sample-efficient, less adaptive.
  • Reflection — critique the last attempt before the next one. Cheap to add, and strongest where each result is genuinely informative feedback.
  • Multi-agent — separate roles, commonly a proposer and a critic.
How do you evaluate an agentic system?

Task success rate, number of tool calls, cost, latency, and variance across repeated runs. Overlap metrics and LLM-as-judge both have problems — judges favour longer answers and their own outputs.

And the structural point: you need baselines that each kill one alternative explanation — a human reference for scale, the existing product for commercial relevance, a one-shot LLM to isolate whether the loop does anything, and random search on a matched budget to isolate whether the LLM's prior does anything.

The point that lands hardest

An agent optimising against a scored objective will satisfy what is scored and wreck what is not. So a benchmark needs two tiers: the criteria the agent is scored on, and guard metrics it is never told about. If the scored tier improves while the guard tier degrades, the agent is gaming, not solving.

Agents in more depth

What makes a system an agent rather than a chatbot?

Four parts: an LLM that decides, tools it can call, a loop that feeds results back, and state it carries between steps. The defining property is that the model chooses the next step, not the programmer.

How does function calling work?

You describe each tool with a name, description and a JSON schema for its arguments. The model outputs a structured call; your code validates it, runs the tool and returns the result as a new message. Tool descriptions are prompts — vague ones cause wrong tool choices.

Trick A step succeeds 95% of the time. How reliable is a 20-step task?

About 36% (0.95²⁰). Errors compound across steps, which is why long agent runs fail more than single-step demos suggest. Fixes: fewer, more capable tools, verification steps, and checkpoints where the agent checks its own progress.

How do agents handle memory?

Short-term: the context window — summarise or trim as it fills. Long-term: write facts or past episodes to a store (vector database, files) and retrieve them when relevant. Memory is just retrieval; the same pitfalls as RAG apply.

Trick Are more agents better than one?

Not by default. Multi-agent setups multiply cost and latency and add hand-off errors. They pay off when work is genuinely parallel (an orchestrator dispatching independent research threads) or when separate roles (critic, verifier) catch real mistakes. Start with one agent and good tools.

What are the common agent failure modes?

Looping on the same action, calling tools with hallucinated arguments, stopping too early and claiming success, losing the goal in a long context, and over-trusting tool output. Guard with step limits, schema validation, explicit success checks and traces you actually read.

How do you make an agent safe to run?

Least privilege on tools, sandboxes for code execution, human approval for irreversible actions (payments, deletion, sending messages), and treating all retrieved or tool-returned text as data, not instructions — the defence against prompt injection.

What is MCP?

The Model Context Protocol: an open standard for exposing tools and data sources to LLM applications, so a tool is written once and used by any compatible client — rather than writing a custom integration per app.

How do you control an agent's cost and latency?

Route easy steps to smaller models, cache repeated tool calls and prompts, cap steps and tokens, run independent tool calls in parallel, and measure cost per completed task, not per call.

Trick Would you use an agent for a fixed, well-understood process?

Usually not. If the steps are known, a deterministic workflow that calls the LLM where needed is cheaper, faster and easier to test. Use agents where the path genuinely depends on what's found along the way.

Grounding models in your data

Retrieval-augmented generation

The spoken answer — about thirty seconds

RAG retrieves relevant documents at query time and gives them to the model as context, so it answers from your data instead of from memory. Offline you chunk the documents, embed them and store them in an index. At query time you embed the question, retrieve the closest chunks — usually hybrid with keyword search — rerank them, and have the model answer with citations. It gives you fresh, private, checkable knowledge without retraining, and when it goes wrong, it's usually retrieval, so you evaluate that separately.

INDEXING — OFFLINE documents chunk embed vector index QUERY — ONLINE question rewrite + embed retrieve top-k rerank LLM + cite dense + BM25 Most RAG failures are retrieval failures. If the right chunk never reaches the prompt, no model or prompt fixes it. Evaluate retrieval (recall@k) separately from generation (faithfulness), and debug in that order.
Two pipelines sharing one index. Indexing runs once per document; the query path runs per question. The reranker is the cheapest big quality win.

Questions

What is RAG and why use it?

Retrieval-augmented generation: fetch relevant documents at query time and put them in the prompt, so the model answers from them rather than from memory.

It gives fresh knowledge without retraining, access to private data, citations you can check, and fewer hallucinations. The weights never change.

Walk through a RAG pipeline end to end.

Indexing (offline): load documents → clean → chunk → embed each chunk → store vectors plus metadata in an index.

Query (online): rewrite the query if needed → embed it → retrieve top-k (dense, often hybrid with BM25) → rerank → assemble the prompt with the chunks → generate with citations → optionally verify the answer is grounded.

How do you choose a chunk size?

It's a trade-off. Small chunks retrieve precisely but lose context; large chunks keep context but dilute the embedding and waste prompt space. Typical starting point: a few hundred tokens with 10–20% overlap.

Better: split on structure (headings, paragraphs, code blocks) rather than fixed length, and tune chunk size against retrieval recall on your own eval set.

Trick Is bigger chunk size always better because the LLM gets more context?

No. One embedding has to summarise the whole chunk, so a large chunk covering several topics matches none of them well. You also fit fewer distinct chunks in the prompt. A common fix is small-to-big: retrieve on small chunks, then pass their parent section to the model.

Dense vs sparse retrieval — and why hybrid?

Sparse (BM25): keyword matching. Great for exact terms, names, IDs, error codes. Misses synonyms.

Dense: embedding similarity. Captures meaning and paraphrase. Weak on rare exact tokens.

Hybrid runs both and fuses the rankings, usually with reciprocal rank fusion. It reliably beats either alone, which is why it's the production default.

Bi-encoder vs cross-encoder — where does each go?

A bi-encoder embeds query and document separately, so document vectors are precomputed and search is fast. Used for first-stage retrieval.

A cross-encoder reads query and document together and outputs a relevance score. Far more accurate but must run per pair, so it's used to rerank the top 20–100 candidates.

How does a vector index search millions of vectors quickly?

Approximate nearest neighbour search. HNSW builds a layered proximity graph and greedily walks it; IVF clusters vectors and searches only the nearest clusters; product quantisation compresses vectors to save memory. You trade a little recall for orders-of-magnitude speed.

Trick Is a vector database required for RAG?

No. For thousands of chunks, brute-force cosine similarity in NumPy is fine. Postgres with pgvector or plain Elasticsearch/BM25 often suffice. A dedicated vector DB pays off at scale or when you need filtering, updates and replication.

Cosine similarity or dot product?

Cosine ignores vector length; dot product doesn't. If embeddings are L2-normalised they're identical. Use what the embedding model was trained with.

How do you improve the query side?

Query rewriting (turn a chatty follow-up into a standalone question using chat history), multi-query (generate several phrasings and merge results), HyDE (generate a hypothetical answer and embed that, since answers look more like documents than questions do), and metadata filters (date, product, permissions).

How do you evaluate a RAG system?

Split it into two problems, because they fail differently.

Retrieval: recall@k, MRR, nDCG against a labelled set of question → relevant-chunk pairs. Generation: faithfulness (is every claim supported by the retrieved context?), answer relevance, and correctness against references. Tools like RAGAS automate parts with LLM judges; spot-check them by hand.

Trick The RAG answer is wrong. Where do you look first?

Retrieval. Check whether the right chunk was in the top-k at all. If it wasn't, no prompt change will help — fix chunking, embeddings, hybrid search or the query. If it was retrieved and the answer is still wrong, then look at the prompt, context order and the model.

What is 'lost in the middle' and how does it affect RAG?

Models use information at the start and end of a long context better than the middle. So stuffing 50 chunks can hurt. Retrieve fewer, rerank, and put the most relevant chunks first or last.

How do you stop RAG hallucinating anyway?

Instruct the model to answer only from the provided context and to say when it can't; require citations per claim; set a retrieval score threshold below which you abstain; and run a groundedness check on the output.

Trick Long-context models — does that make RAG obsolete?

No. Putting everything in context costs far more per query, is slower, still suffers lost-in-the-middle, and can't cover corpora larger than the window or enforce per-user access. Long context and RAG are complementary: retrieve, then use the long window to include more of what you retrieved.

What are advanced RAG patterns worth naming?

Agentic RAG: the model decides when and what to search, possibly several times. GraphRAG: build a knowledge graph of entities for multi-hop and global questions. Contextual retrieval: prepend a short document-level summary to each chunk before embedding so it keeps its context. Self-RAG / corrective RAG: the model grades retrieved documents and re-retrieves if they're poor.

RAG vs fine-tuning — when each?

RAG for knowledge: facts that change, need citations, or are private. Fine-tuning for behaviour: format, style, domain jargon, tool use. They combine well — fine-tune the model to use retrieved context better.

What security issues does RAG introduce?

Prompt injection through retrieved documents (a page saying 'ignore previous instructions'), and access-control leaks — retrieving chunks the user isn't allowed to see. Enforce permissions as filters at retrieval time, not in the prompt, and treat retrieved text as data.

Where the embeddings live

Vector databases and indexing

The spoken answer — about thirty seconds

A vector database stores embeddings and finds the ones nearest to a query vector. Exact search compares against every vector, which is fine up to around a million but too slow beyond. So we use approximate nearest-neighbour indexes. IVF clusters the vectors and searches only the closest clusters. HNSW builds a layered graph and walks greedily towards the query — fast and accurate, but memory-hungry. Product quantisation compresses vectors so billions fit in memory. Each trades a little recall for speed, so I measure recall against exact search and tune parameters like nprobe or efSearch. The database part adds metadata filtering, updates, hybrid search and scaling.

FLATcompare with every vectorexact · O(n)IVFsearch nearest clusters onlynprobe = clusters searchedHNSWentrygreedy walk on a graphfast · memory-hungryPQvector (128 floats)split into 8 sub-vectorseach → nearest of 256centroids = 1 bytecompress each vector512 B → 8 B hereIn production: IVF-PQ for billions of vectors on little memory; HNSW for millions in RAM.Every one trades a little recall for a lot of speed — so measure recall@k against flat search on your own data.
Four ways to find the nearest vectors. Flat search checks everything; IVF only checks the clusters near the query (shaded); HNSW hops through a graph towards it; PQ shrinks every vector so far more fit in memory.

Questions

What does a vector database actually do?

Stores embeddings with their IDs and metadata, and answers k-nearest-neighbour queries fast. On top of the index it adds what a library like FAISS doesn't: inserts, updates and deletes, metadata filtering, persistence, replication, access control and often hybrid keyword search.

Why not just compute similarity against every vector?

That's flat (brute-force) search: exact, simple, O(n·d) per query. It's fine — even on a GPU it's fast — up to roughly a million vectors. Beyond that, or at high query rates, latency and cost push you to approximate indexes.

What does 'approximate' cost you, and how do you measure it?

Some true neighbours get missed. Measure recall@k: the fraction of the exact top-k (from a flat search) that the index returns. Tune for a target like 95% recall at your latency budget, on your own data and queries.

How does an IVF index work?

Run k-means to partition vectors into nlist clusters (Voronoi cells). Each vector is stored in its cluster's inverted list. At query time, find the nprobe nearest centroids and search only those lists. Raising nprobe raises recall and latency.

Trick A query sits near a cluster boundary. What happens with nprobe = 1?

Its true nearest neighbours may sit in the next cluster and are missed. That's exactly why nprobe > 1 is used. It also explains IVF's recall ceiling at small nprobe.

How does HNSW work?

Hierarchical Navigable Small World: a multi-layer graph where each vector links to its nearest neighbours. Upper layers are sparse, with long-range links; the bottom layer has everything. A search enters at the top, greedily moves to the closest neighbour, drops a layer, and repeats. Roughly logarithmic search time with very high recall.

What are HNSW's knobs?

M: links per node — more means better recall and more memory. efConstruction: candidate list size while building — slower build, better graph. efSearch: candidate list size per query — the main recall-versus-latency dial at query time.

Trick Is HNSW always the best choice?

No. It's excellent for millions of vectors in RAM, but it stores the full vectors plus the graph, builds slowly, and handles deletes poorly. At billions of vectors, IVF with product quantisation or disk-based indexes like DiskANN are cheaper.

What is product quantisation?

Split each vector into m sub-vectors, learn 256 centroids per sub-space with k-means, and store each sub-vector as its 1-byte centroid ID. A 128-float vector (512 bytes) becomes 8–16 bytes. Distances are approximated with lookup tables. Often combined with IVF as IVF-PQ.

How do you recover the accuracy PQ loses?

Re-rank: retrieve a larger candidate set with the compressed codes, then compute exact distances on the full vectors for those candidates only. Most production systems do this.

Cosine, dot product or Euclidean?

Use whatever the embedding model was trained with. On L2-normalised vectors all three give the same ranking, so normalising lets you use the fastest inner-product index. Mixing metrics silently degrades results.

How does metadata filtering interact with the index?

Post-filtering — search, then drop rows that fail the filter — can return far fewer than k results when the filter is selective. Pre-filtering restricts the search to matching rows but can break graph traversal. Good databases filter during traversal, or partition by common filters such as tenant.

Trick Do you always need a dedicated vector database?

No. For thousands to a few million vectors, NumPy, FAISS in memory, or pgvector in an existing Postgres is often simplest. A dedicated database (Milvus, Qdrant, Weaviate, Pinecone) pays off with scale, heavy filtering, multi-tenancy or frequent updates.

What happens when you switch embedding models?

Every stored vector must be re-embedded and the index rebuilt — vectors from different models live in different spaces and can't be compared. Store the source text and the model version with each vector, and plan migrations as a full re-index.

How do you handle frequent inserts and deletes?

Graph indexes mark deleted nodes as tombstones and degrade over time, so they need periodic rebuilds. Many systems write new vectors to a small fresh segment searched alongside the main index, then merge in the background.

FAISS, pgvector, Qdrant — how would you choose?

FAISS: a library, fastest and most flexible, no persistence or filtering. pgvector: when you already run Postgres and want joins and transactions. Qdrant, Milvus, Weaviate: when you need a service with filtering, scaling and updates. Benchmark recall and latency on your own data — published benchmarks rarely match your workload.

Asked more often than papers

Fundamentals

BIAS / VARIANCE model complexity → error bias² variance total sweet spot OVERFITTING, DIAGNOSED epochs → loss train validation stop here
Left: bias falls and variance rises with capacity; total error is the U. Right: the diagnostic — training loss still falling while validation loss turns up.
Explain bias and variance.

Bias is error from the model being too simple to represent the truth. Variance is error from the model being too sensitive to the particular training sample. High bias underfits, high variance overfits.

The caveat worth adding: very overparameterised networks break the simple story — they can interpolate the training data and still generalise. One sentence of that signals you've read past the textbook.

Trick Does more data fix overfitting?

It reduces variance, not bias. If the model is too simple for the problem, infinite data won't help — you'll just fit the wrong function very precisely.

So "get more data" is the right answer to a variance problem and the wrong answer to a bias problem, and distinguishing them is the actual skill.

Walk through your regularisation options.
  • L2 / weight decay — pulls weights toward zero, prefers smaller smoother solutions.
  • L1 — drives weights to exactly zero, gives sparsity.
  • Dropout — randomly zeroes activations in training, roughly approximating an ensemble of sub-networks. Off at inference.
  • Early stopping — also regularisation; you're limiting how far the optimiser goes.
  • Augmentation — for imaging, reach for this first, because data is what you lack.
Trick Does L2 regularisation produce sparse weights?

No — L1 does. L2 shrinks weights smoothly toward zero but essentially never to exactly zero, because its gradient vanishes as the weight does. L1's gradient has constant magnitude, so it pushes weights all the way to zero and keeps them there.

Trick Is dropout active at test time?

No. At inference dropout is disabled and activations are scaled so the expected value matches training (or, with inverted dropout, the scaling happened during training and nothing changes at test). Leaving it on is a classic bug that shows up as noisy, irreproducible predictions.

Related: BatchNorm also behaves differently — training uses batch statistics, inference uses running averages. Forgetting model.eval() breaks both.

Train, validation, test — what is each for?

Train fits parameters. Validation selects hyperparameters and decides when to stop. Test is touched once, at the end.

The subtlety: validation is a form of fitting too. Every hyperparameter you choose on it leaks a little information, which is exactly why the test set has to stay sealed.

Why not just use MSE for classification?

With a softmax output, MSE gives small gradients when the model is confidently wrong, so it learns slowly in exactly the situation you care about. Cross-entropy's gradient stays proportional to the error.

Cross-entropy is also the maximum-likelihood objective for a categorical distribution, so it's the principled choice rather than a trick.

How do you detect overfitting?

Compare training and validation loss over training or over model size: a widening gap with validation loss turning upward is the signature. Learning curves against training-set size tell you whether more data would help (gap closing) or the model is too simple (both curves high).

Trick How does early stopping work, and what is the trap?

Monitor validation loss and stop when it hasn't improved for a set number of epochs or trees (the patience), keeping the best checkpoint. The trap: the validation set used for stopping is now part of model selection, so it must not also be your test set.

Where careless answers show

Metrics and imbalance

CONFUSION MATRIX predicted positive negative actual pos neg TP FN FP TN precision = TP / (TP+FP) of what I flagged, how much was right recall = TP / (TP+FN) of what was really there, how much I found The clinical framing In screening you accept poor precision to protect recall — a missed tumour is worse than a false alarm that gets reviewed. Say this. It's what makes you sound serious.
Precision reads down the predicted-positive column; recall reads across the actual-positive row. If you can place TP, FP and FN on the grid you will never mix them up again.
Trick The model is 99% accurate. Is it good?

Unknowable without the class balance. If 99.9% of voxels are background, predicting "nothing everywhere" scores 99.9% and finds no lesions at all.

The right move is to change the metric, not celebrate: precision and recall, or Dice, or PR-AUC.

Trick Is a high ROC-AUC enough?

Not under heavy imbalance. ROC-AUC is the probability a random positive ranks above a random negative. With vast numbers of negatives, the false-positive rate stays tiny even when the absolute number of false positives is enormous, so the curve looks great while the model is unusable.

Precision-recall AUC is the right choice there, because precision is sensitive to the number of false positives rather than their rate.

What is Dice, and how does it relate to IoU and F1?

Dice = 2|A∩B| / (|A|+|B|). It is exactly F1 computed over voxels, with the segmentation's predicted and true masks as the two sets.

And the relation worth knowing: Dice = 2·IoU / (1 + IoU), so Dice is always ≥ IoU, and they rank models identically. If someone quotes one and you think in the other, you can convert.

Trick Is Dice differentiable?

Hard Dice isn't — it's computed on thresholded binary masks, and thresholding has zero gradient. Soft Dice is: you use the predicted probabilities directly instead of thresholding, which makes it differentiable and usable as a loss.

That's why the standard recipe is cross-entropy plus soft Dice: cross-entropy gives well-behaved per-voxel gradients, Dice optimises the overlap you're actually judged on.

Why report Hausdorff distance alongside Dice?

Dice is a volume-overlap measure, so it is dominated by the bulk of a large structure. A segmentation can score 0.95 Dice while having one badly wrong protrusion, and Dice barely notices.

Hausdorff measures the worst boundary error, so it catches exactly that. Report both — and prefer the 95th-percentile Hausdorff, since the raw maximum is hostage to a single outlier voxel.

Macro vs micro vs weighted F1?

Macro: compute F1 per class, then take the plain mean — every class counts equally, so rare classes matter. Micro: pool all true positives, false positives and false negatives first — dominated by frequent classes. Weighted: per-class F1 averaged by class frequency. Use macro when rare classes matter, as with drones versus birds.

Trick For single-label multiclass, what does micro-F1 equal?

Plain accuracy. Every wrong prediction is one false positive for the predicted class and one false negative for the true class, so micro precision, micro recall and micro-F1 all reduce to accuracy — and inherit its blindness to rare classes.

RMSE vs MAE — when does each mislead?

RMSE squares errors, so a few large misses dominate; it is the right target when big errors are disproportionately costly, but one outlier can swamp it. MAE treats all errors linearly and corresponds to predicting the median; it can hide rare large failures. RMSE ≥ MAE always, and a large gap signals heavy-tailed errors. Report both, in the target's units.

Trick Is a high R² proof of a good regression model?

No. R² depends on how much the target varies in the test set: on a wide-ranging set a model can score 0.95 while being too inaccurate for the job. Report errors in physical units against the tolerance that matters.

Training behaviour

Optimisation

WHY MOMENTUM minimum plain SGD oscillates across with momentum damps the oscillation, accelerates along the valley
Momentum averages past gradients. Components that keep flipping sign cancel; the consistent direction accumulates.
Explain Adam in two sentences.

Adam keeps running averages of the gradient (first moment) and its square (second moment), and divides the step by the square root of the second moment — so every parameter gets its own effective learning rate, larger where gradients have been consistently small.

AdamW decouples weight decay from the gradient update, which is the correct formulation and is now standard.

Trick Does Adam always beat SGD?

No. Adam converges faster and is far more forgiving about learning rate, but well-tuned SGD with momentum frequently generalises better on vision tasks, and most ImageNet-era benchmarks were set with it.

The honest answer: Adam is the right default, SGD+momentum is worth trying if you have the budget to tune it and generalisation is what you care about.

Trick Does gradient clipping change the direction of the update?

Depends which kind — and this is the trap.

  • Clip by norm rescales the whole gradient vector if its norm exceeds a threshold. Direction is preserved, only the magnitude changes.
  • Clip by value clamps each component independently. This does change the direction, because components are rescaled unequally.

Clip by norm is what people usually mean and usually want.

Trick What happens if you initialise all weights to zero?

Nothing learns. Every unit in a layer computes the same output and receives the same gradient, so they stay identical forever. Symmetry never breaks, and a layer of n units has the expressive power of one.

The whole point of random initialisation is symmetry breaking. Xavier/Glorot for symmetric activations, He/Kaiming for ReLU — which accounts for ReLU zeroing half the inputs, so it uses a larger variance.

Why do transformers need learning-rate warmup?

Early in training the gradients are large and the adaptive moment estimates in Adam are still poorly conditioned, so full-size steps destabilise the model — especially with post-norm, where there's no clean identity path. Ramping the learning rate up over the first few hundred steps avoids that.

Pre-norm reduces the need for it considerably, which is part of why pre-norm won.

Trick Is a lower learning rate always safer?

No. Too low and you train impractically slowly, and you may settle into a sharp minimum nearby rather than escaping to a flatter one. Gradient noise is partly a feature — it's one reason smaller batches often generalise better.

Learning rate is the hyperparameter that matters most, and it's the first thing to check when a run misbehaves.

A model won't train. How do you debug it?

In this order:

  1. Can it overfit a single batch? If not, the bug is in the code or the loss, not the model. This one test eliminates most causes.
  2. Check the learning rate — too high diverges, too low looks like nothing happening.
  3. Check the data and labels are actually aligned.
  4. Check input normalisation.
  5. Check gradients are reaching all parameters — anything accidentally frozen or detached.

Leading with the single-batch test marks you as someone who has actually debugged training.

Imaging

CNNs and segmentation

U-NET bottleneck in out encoder ↓ decoder ↑ skip connections Deep features know WHAT. Skipped features know WHERE. Downsampling destroys the spatial precision you need to place a boundary. Without skips: right regions, badly localised edges. RECEPTIVE FIELD input layer 1 layer 2 layer 3 One deep unit sees a wide input region — but it takes depth to get there. A transformer gets global context in one layer, which is the honest case for attention. Two 3×3 convs = one 5×5 receptive field, with fewer parameters and an extra non-linearity. That's why 3×3 won.
The skip-connection question is the single most likely CNN question in a medical imaging interview. Have the what/where answer ready.
Trick Is a CNN translation invariant?

Equivariant, not invariant — the classic trap. Shift the input and the feature maps shift with it. Convolution does not discard position.

Partial invariance comes later, from pooling and from a global pooling or flatten at the end. And for segmentation you specifically want equivariance, because the output is spatial.

How many parameters in a convolutional layer?

k × k × Cin × Cout + Cout for a 2D layer (the trailing term is the bias). In 3D it's k³ × Cin × Cout + Cout.

The two things people forget: the Cin factor — each kernel spans all input channels — and the bias. Note the count is independent of input spatial size, which is the weight-sharing property.

Why does a 1×1 convolution do anything?

It has no spatial extent, so it mixes channels — a learned linear projection applied at every spatial position. That's how you change channel count cheaply, which is what the bottleneck in a ResNet block is for.

What is dilation for?

Inserting gaps in the kernel enlarges the receptive field without adding parameters and without downsampling. That's exactly the trade segmentation needs: you want wide context but cannot afford to throw away the resolution that locates the boundary.

What would you use as a baseline for medical segmentation?

nnU-Net. Not a new architecture — an automatic configuration pipeline that picks patch size, spacing, normalisation and augmentation from the dataset's own properties. It remains a hard baseline to beat, and saying "I'd start from nnU-Net" is a sign of someone who knows the field.

3D, 2D or 2.5D for volumes?

Full 3D uses real spatial context but is memory-hungry, so you train on patches. 2D slice-by-slice is cheap but ignores through-plane context. 2.5D feeds a few adjacent slices as channels as a compromise.

The detail that sounds like experience: patch-based 3D training forces tiny batch sizes, which is why you use GroupNorm or InstanceNorm rather than BatchNorm.

Two things with confusingly similar names

Vision transformers and spatial transformers

Clear this up first

A vision transformer is a transformer — attention, queries, keys, values — applied to image patches. A spatial transformer has no attention in it at all; it is a differentiable warping module from 2015, two years before "Attention Is All You Need". They share a word and nothing else. If someone uses the bare phrase "spatial transformer", they mean the warping module.

Vision transformers

IMAGE 224 × 224 cut into 16 × 16 patches flatten PATCHES ⋮ (224/16)² = 196 patches linear TOKENS [CLS] 197 tokens, + positional standard transformer unchanged from text The only change from text is how you make tokens. Everything after the embedding layer is the same architecture. Patch size is the cost dial — and it's quadratic. Patch 16 → 196 tokens. Patch 8 → 784 tokens, so 16× the attention cost. Patch 1 (every pixel a token) is hopeless. In 3D it's (H/P)(W/P)(D/P), which explodes — hence windowed attention for volumes.
Patchify, embed, run a normal transformer. A ViT is not a new architecture so much as a new tokeniser bolted onto the old one.
INDUCTIVE BIAS vs DATA training data (log scale) → accuracy CNN locality + equivariance built in — good early ViT almost no built-in assumptions — must learn them from data crossover
The honest comparison. A CNN assumes locality and translation equivariance; a ViT assumes almost nothing, so it has to learn those from data — which is why it loses on small datasets and wins at scale or after heavy pre-training.
Trick Is a ViT translation equivariant like a CNN?

No — that property is lost. Patches are cut on a fixed grid, so shifting the image by less than one patch width changes the tokenisation entirely: different pixels land in different patches and every token changes. A CNN's kernel slides, so a shift just shifts the feature map.

ViTs recover approximate invariance from data and augmentation rather than from architecture. That is exactly the inductive-bias trade, and it is the reason the data requirement is higher.

How many tokens does a ViT see, and why does it matter?

(H/P) × (W/P), plus one if there's a CLS token. A 224×224 image at patch size 16 gives 14×14 = 196 patches, 197 tokens.

It matters because attention is quadratic in token count. Halving the patch size to 8 quadruples the tokens and multiplies attention cost by sixteen. In 3D it's (H/P)(W/P)(D/P), which is why volumetric transformers almost always use windowed or hierarchical attention rather than global.

Trick Can you feed a trained ViT a different image size?

Not without handling the positional embeddings. The patch embedding itself is fine — it's applied per patch, so more patches just means more tokens, and attention handles variable length.

But learned positional embeddings are one vector per position for a fixed grid. At a new resolution there are positions you have no embedding for. The standard fix is to interpolate the positional embeddings onto the new grid, which is what every fine-tuning recipe does.

CLS token or global average pooling?

Two ways to get a single vector for the whole image. The CLS token is an extra learned token prepended to the sequence; it attends to everything and its final state is used as the image representation. Global average pooling just averages all the patch tokens.

They perform comparably. CLS is inherited from BERT; GAP is simpler and common in later work.

Name the variants worth knowing.
  • Swin — hierarchical, attention inside shifted local windows. Linear rather than quadratic in image size, and it restores a multi-scale feature pyramid, so it works as a detection and segmentation backbone.
  • DINOv2 — self-supervised ViT. The practical default when you want strong general visual features without labels, and the obvious starting point for a foundation-model project.
  • MAE — masked autoencoder. Mask ~75% of patches, reconstruct. The standard self-supervised recipe for ViTs.
  • ConvNeXt — a CNN modernised with ViT-era design choices that matches ViT performance. The useful counterpoint: a lot of ViT's advantage was training recipe, not attention.
  • UNETR / Swin-UNETR — transformer encoder with a convolutional decoder for 3D medical segmentation. This is what a ViT usually looks like in a medical imaging paper.

Spatial transformer networks

Jaderberg et al., 2015. This is the module that makes learned registration possible, so be able to explain it precisely — it's the piece that turns registration into something a network can be trained on end to end.

THE THREE PARTS moving + fixed image 1 · localisation U-Net predicts φ 2 · grid where to sample from 3 · sampler bilinear interpolation warped image loss vs fixed gradients flow back THROUGH the sampler WHY BILINEAR, NOT NEAREST a b c d The sample point lands between pixels. Bilinear blends a, b, c, d by distance — so moving the point slightly changes the output slightly. That is a non-zero derivative with respect to the sampling coordinates, which is the whole trick. Nearest-neighbour would be useless. It's piecewise constant: nudge the coordinate and the output is identical until it snaps to another pixel. Gradient zero almost everywhere. Nothing trains.
The sampler is the clever part. Bilinear interpolation is differentiable with respect to the sampling coordinates, so the loss on the warped image produces a gradient on the deformation field, and therefore on the network that predicted it.
What is a spatial transformer, in one answer?

A differentiable module that applies a geometric transformation to a feature map. Three parts: a localisation network predicts the transformation parameters, a grid generator turns those into sampling coordinates for every output position, and a sampler reads the input at those coordinates using bilinear interpolation.

Because every step is differentiable, you can put it in the middle of a network and train the whole thing by backpropagation. Its original purpose was letting a network learn to crop, rotate and rectify its own input — a learned, differentiable form of spatial attention.

Trick Could you use nearest-neighbour sampling instead of bilinear?

No, and this is the heart of it. Nearest-neighbour is piecewise constant in the sampling coordinate — nudge the coordinate a little and the output doesn't change at all until it jumps to a different pixel. The derivative is zero almost everywhere and undefined at the jumps. No gradient reaches the deformation field, so nothing trains.

Bilinear interpolation blends the four surrounding pixels by distance, so the output varies smoothly with the coordinate and the derivative exists. That single property is what makes learned registration possible.

How does the spatial transformer make VoxelMorph unsupervised?

Follow the loop: the network takes the moving and fixed images and outputs a deformation field. The spatial transformer warps the moving image by that field. The loss compares the warped image to the fixed one, plus a regularisation term on the field.

Because the warp is differentiable, the gradient of that image-similarity loss flows back through the sampler, onto the deformation field, and into the network that produced it. So you never need a ground-truth deformation — the supervision comes from how well the warped image matches, which you can always compute.

This is the bridge between the registration section and this one, and it's worth being able to say in one breath.

Trick Is a spatial transformer a kind of transformer?

No. No attention, no queries, keys or values, no tokens. It's a differentiable warping module and the name is a coincidence of vocabulary.

The dates settle it: spatial transformer networks are from 2015, the attention transformer from 2017. The spatial one came first.

What's the difference between the STN's transformation and a registration deformation?

Mechanically none — both are sampling grids fed to the same sampler. The difference is their form and where they come from.

The original STN predicts a global, low-dimensional transformation, typically a six-parameter affine, so the whole image moves together. Deformable registration predicts a dense field — a displacement vector at every voxel, millions of parameters — usually parameterised as a velocity field and exponentiated so the result is a diffeomorphism.

Same sampler, vastly different degrees of freedom, which is exactly why the dense case needs a regularisation term and the affine case doesn't.

Sampling, likelihood and synthesis

Generative models

GAN noise G D sharp · unstable · mode collapse no likelihood VAE enc z dec stable · usable latent space blurry — likelihood rewards hedging DIFFUSION denoise, many steps best quality · stable slow — many forward passes AtlasGAN, in the Moreno papers, does not generate brains from noise. A decoder maps age + condition to a template; a VoxelMorph-style network warps that template onto real subjects. The generated object is a conditional template plus a deformation — so identity is preserved by construction.
Three families, three failure modes. The speed column is what InBrainSyn exploits — about two minutes against twenty-three for the diffusion baseline.
Trick Can a GAN tell you how likely a sample is?

No. A GAN is an implicit model — it can produce samples but gives no density. You cannot evaluate p(x), which is why GAN evaluation relies on proxy scores like FID rather than held-out likelihood.

VAEs give a likelihood bound (the ELBO); diffusion models can give one too; autoregressive models give an exact likelihood.

Why are VAE outputs blurry?

Because the reconstruction term is typically a per-pixel Gaussian likelihood, which is minimised by predicting the conditional mean. When several outputs are plausible, the mean of them is a blur. The KL term pushing the posterior toward the prior adds to it.

Trick Diffusion is state of the art — so is it fast?

No, it's the slowest of the three at inference, because sampling is tens to hundreds of sequential forward passes. GANs and VAEs generate in one. Distillation and flow-matching approaches exist to cut the step count, but the baseline fact stands.

This is a real engineering consideration, not trivia — it's why a deformation-based method can beat a diffusion method on wall-clock by an order of magnitude.

What is mode collapse, and which model has it?

GANs. The generator discovers a narrow set of outputs that reliably fool the discriminator and stops covering the rest of the distribution. Samples look fine individually and lack diversity collectively.

It's a consequence of the adversarial objective: nothing in it requires covering the data distribution, only fooling the current discriminator.

Foundation models

Self-supervised learning

CONTRASTIVE pull together two views, same image other image push apart MASKED hide patches, reconstruct no negatives needed The medical-imaging problem Contrastive assumes two different images are negatives. Two healthy brain MRIs are already nearly identical. So you risk pushing apart things that genuinely are alike — discarding anatomy while keeping scanner differences. Masked modelling sidesteps it entirely, because it never needs negatives. Say this if foundation models come up.
The four families: contrastive, non-contrastive, masked, cross-modal. The medical caveat is the part that sounds like thought rather than revision.
Trick Why doesn't BYOL collapse to a constant?

This is the standard probing question, because the loss alone appears to have a trivial solution — output the same vector always.

It doesn't collapse because of asymmetry: an extra predictor head on the online branch only, a stop-gradient on the target branch, and the target being an exponential moving average of the online network. The target is therefore always a lagged version of the student, and the dynamics never settle on the constant.

VICReg and Barlow Twins solve the same problem differently: explicit variance and covariance terms that make collapse directly costly.

Do you always need negative pairs?

No. Contrastive methods (SimCLR, MoCo) need them, and their quality depends heavily on having many — hence large batches or a memory bank. Non-contrastive methods (BYOL, VICReg, Barlow Twins) and masked modelling (MAE, BERT) need none.

Trick Can you use standard image augmentations on medical scans?

Not blindly. Two concrete examples worth having:

  • Horizontal flip on a chest X-ray turns a normal heart into dextrocardia — you are training the model that a pathological configuration is normal.
  • Aggressive intensity augmentation on CT destroys information that is quantitative: Hounsfield units are physically meaningful and calibrated, unlike RGB values.

Useful medical-specific ones instead: elastic deformation, bias-field simulation, anisotropic resampling, simulated motion artefact.

Aligning images — be exact

Registration

THE LOSS HAS TWO PARTS moving image deformation φ warped → fixed? 1 · similarity SSD / NCC same modality mutual info across modality 2 · regularisation penalise the gradient of the displacement field Without the second term the problem is ill-posed: you can warp anything onto anything by tearing it apart. JACOBIAN DETERMINANT det J > 0 — valid det J < 0 — folded Report the fraction of negative Jacobians. It's the quality check people forget, and it's how you show a deformation is physical.
If you say one thing about registration, say that the loss needs a regularisation term. Similarity alone is ill-posed, and an unregularised deformation can score perfectly while being anatomical nonsense.
Trick What does registration output?

A transformation, not an image. The warped image is a by-product you get by applying it. This matters because the transformation is the object you analyse — which is exactly what the synthetic-ageing work does: it generates, transports and decomposes deformation fields.

Which similarity metric, and when?
  • SSD — same modality, same intensity scale.
  • Normalised cross-correlation — same modality, intensities linearly related but not identical. Robust to bias field.
  • Mutual information — different modalities. It measures statistical dependence rather than intensity agreement, which is why it's the standard answer for MR-to-CT.
What is a diffeomorphism and why do you want one?

A smooth, invertible transformation with a smooth inverse. It preserves topology — no tearing, no folding, structures stay connected and in the same order. It also gives inverse consistency, so registering A→B and B→A agree.

In practice you get it by parameterising a stationary velocity field and exponentiating it (scaling and squaring), which guarantees a diffeomorphism by construction. That representation is also what makes parallel transport possible — velocity fields live in a vector space where you can do algebra.

Trick Is VoxelMorph supervised?

Unsupervised. People assume supervised because it's a neural network predicting a deformation, but there are no ground-truth correspondences. The loss is computed by warping the moving image with a differentiable spatial transformer and comparing it to the fixed one — the same similarity-plus-regularisation objective classical methods optimise, just amortised into a network.

Inference drops from minutes of iterative optimisation to one forward pass.

Trick High Dice on warped labels means good registration?

Not necessarily. Label overlap is an indirect proxy. A deformation can push labels into agreement while being locally implausible — folded, wildly non-uniform, or compressing tissue in ways no anatomy does.

That's why you report regularity alongside overlap: fraction of negative Jacobian determinants, and the distribution of the Jacobian. Volunteering this is the most sophisticated thing you can say about registration evaluation.

Synthetic vs real training pairs, in one line

Synthetic pairs give exact ground-truth correspondence, which real pairs never have; real pairs keep the model honest about actual anatomical variation. Neither alone is sufficient.

Be ready for

If you have trained on synthetic deformations: "How exactly was the synthetic supervision generated?" — the most likely follow-up and the most interesting part. Know how the fields were produced, why they were plausible, and the weakness if there is one. If they were smoother than real anatomical variation, say so yourself. Volunteering it is worth more than a clean story.

Where domain maturity shows

Medical data traps

SPLIT BY IMAGE — WRONG TRAIN patient A scan 1 TEST patient A scan 2 the model has already seen this anatomy — the number is inflated SPLIT BY PATIENT — RIGHT TRAIN patients A, B, C TEST patients D, E better still: hold out a whole site or scanner Holding out a site is the only way to know whether the model learned anatomy or learned the protocol. Say this if you get any opening about evaluation. It's the most common real-world mistake and it shows domain maturity.
The single most common evaluation mistake in medical ML. Two scans of one patient on opposite sides of the split makes every number meaningless.
Trick Is ImageNet pre-training useless for medical images?

No — it still helps, even though the domain is completely wrong, because low-level features (edges, textures, gradients) transfer. The gains are smaller than in natural images and mostly show up when labelled data is scarce.

The better answer: self-supervised pre-training on unlabelled scans from your own domain tends to help more, which is the whole commercial argument for foundation models in a medical imaging company.

How do you know a model generalises?

Held-out performance on a different site, scanner or hospital. Anything less is a weaker claim than it sounds — a random split within one dataset mostly measures how consistent that dataset's acquisition is.

What is a voxel?

The 3D analogue of a pixel — "volume element". A scan is a grid of them, each holding one intensity at a position, each a small cuboid of tissue.

The detail worth adding: voxels are frequently anisotropic — MRI often has thicker slices than in-plane resolution, say 0.9 × 0.9 × 3 mm. That's why resampling matters before registration, and why 3D convolutions with isotropic kernels can be the wrong assumption.

Before deep learning

Classical ML

Still asked everywhere, because tabular data is still most of industry — and gradient boosting still wins on it.

A DECISION TREEtumour size > 2cm?noyesbenignage > 60?benignbiopsyeach split picks the feature + threshold that most reduces impurityBAGGING — parallel, averagesaverage↓ varianceBOOSTING — sequential, correctseach tree fits the previous ensemble's errors↓ bias
Trees split; ensembles combine them two ways. Random forests average many deep trees built in parallel to cut variance. Gradient boosting adds shallow trees one after another, each fixing the last one's mistakes, to cut bias.
Linear vs logistic regression?

Linear regression predicts a continuous value and minimises squared error. Logistic regression predicts a probability by passing a linear score through a sigmoid, and minimises log loss.

Despite the name, logistic regression is a classifier. Its decision boundary is linear.

Trick Is logistic regression's loss convex?

Yes — log loss is convex in the weights, so there's a single global minimum. MSE through a sigmoid would not be convex, which is another reason cross-entropy is used.

Explain a decision tree.

Recursively split the data on the feature and threshold that most reduce impurity (Gini or entropy for classification, variance for regression), until a stopping rule. Interpretable, handles mixed types, no scaling needed — and overfits badly alone.

Random forest vs gradient boosting?

Random forest: many deep trees trained in parallel on bootstrap samples with random feature subsets, averaged. Reduces variance.

Gradient boosting (XGBoost, LightGBM, CatBoost): shallow trees trained sequentially, each fitting the residual gradient of the previous ensemble. Reduces bias. Usually more accurate, more sensitive to tuning.

Trick Do tree models need feature scaling?

No. Splits are thresholds on one feature at a time, so any monotonic transform leaves the tree unchanged. Scaling matters for distance- and gradient-based models: kNN, SVM, linear models with regularisation, neural nets.

Bagging vs boosting in one line each?

Bagging: train independent models on resampled data and average — cuts variance. Boosting: train models in sequence, each correcting its predecessor — cuts bias.

What does an SVM optimise, and what's the kernel trick?

It finds the hyperplane with the maximum margin to the nearest points (the support vectors), with a soft-margin penalty for violations.

The kernel trick computes inner products in a high-dimensional feature space without ever building it, so a linear separator there is a non-linear one in input space (RBF kernel is the usual default).

k-means — how, and what are its failure modes?

Pick k centroids, assign each point to its nearest, move each centroid to the mean of its points, repeat until stable.

Failures: you must choose k (elbow, silhouette); sensitive to initialisation (use k-means++); assumes roughly spherical, equal-size clusters; sensitive to scale and outliers.

Trick Is kNN's training expensive?

No — training is free; inference is expensive. It just stores the data. Every prediction scans for neighbours, O(n·d) naively. And it degrades in high dimensions, where all distances become similar (curse of dimensionality).

What does PCA do?

Finds orthogonal directions of maximum variance — the eigenvectors of the covariance matrix (computed via SVD in practice) — and projects onto the top k.

Caveats: linear only, and variance ≠ importance for your label. Standardise first, or large-scale features dominate.

Trick Does PCA select features?

No. Each component is a linear combination of all original features. It's dimensionality reduction, not feature selection — you lose interpretability.

Naive Bayes — what is naive about it?

It assumes features are conditionally independent given the class. Almost never true, yet it works surprisingly well for text classification because ranking, not calibrated probability, is what matters.

What is the curse of dimensionality, and when does it bite?

As dimensions grow, data becomes sparse: the volume to cover grows exponentially, and distances between points concentrate so nearest and farthest neighbours become almost equally far. It hurts distance-based methods (kNN, clustering, RBF kernels) and density estimation most. Remedies: feature selection, PCA or learned embeddings, regularisation — and noting that real data usually lies near a much lower-dimensional manifold.

The maths under everything

Probability and statistics

Short, sharp questions where hesitation is visible.

1,000 PEOPLE TESTED · DISEASE IN 1 · TEST 99% ACCURATE1 true positive~10 false positives~989 true negativesP(disease | positive)= 1 / (1 + 10)≈ 9%The rare condition is swampedby errors on the healthy many.
Bayes in one picture. Out of 11 positive results, only one person is actually ill. When the prior is tiny, even an accurate test produces mostly false alarms — the reason screening programmes confirm positives.
State Bayes' theorem and give the intuition.

P(A|B) = P(B|A)·P(A) / P(B). Posterior ∝ likelihood × prior.

The classic trap: a 99%-accurate test for a 1-in-1000 disease. A positive result still means only about a 9% chance of disease, because false positives from the huge healthy population swamp the true positives.

MLE vs MAP?

MLE picks parameters that maximise the likelihood of the data. MAP maximises likelihood × prior. L2 regularisation is MAP with a Gaussian prior; L1 is MAP with a Laplace prior. That link is the line that impresses.

Trick What is a p-value?

The probability of seeing data at least this extreme if the null hypothesis were true.

It is not the probability the null is true, and not the probability your result is a fluke.

Type I vs Type II error?

Type I: false positive — rejecting a true null (rate α). Type II: false negative — missing a real effect (rate β). Power is 1 − β.

Central limit theorem — why do we care?

Means of many independent samples are approximately normal regardless of the underlying distribution. It's why confidence intervals and A/B tests on averages work.

Trick Does correlation of zero mean independence?

No. Pearson correlation only measures linear dependence. y = x² over symmetric x has zero correlation and is completely dependent on x.

Define KL divergence and entropy.

Entropy H(p) is the expected surprise of a distribution. Cross-entropy H(p,q) is the expected surprise when coding p with q. KL(p‖q) = H(p,q) − H(p): the extra cost. Minimising cross-entropy loss is minimising KL to the data distribution.

Trick Is KL divergence a distance?

No — it isn't symmetric and doesn't satisfy the triangle inequality. KL(p‖q) ≠ KL(q‖p); forward KL is mode-covering, reverse KL is mode-seeking.

Where most of the work is

Data and feature engineering

LEAKAGE: FIT THE SCALER BEFORE SPLITTING — WRONGall datafit scalermean, stdtraintesttest stats leaked into trainingRIGHT: SPLIT FIRST, FIT ON TRAIN ONLYall datatraintestfit scalerapply onlyTIME SERIES: SPLIT BY TIMEtrain on the past → validate on the future(rolling / expanding window)
Every preprocessing step is part of the model. Anything fitted — scalers, imputers, target encoders — must be fitted on training data only. For temporal data, never shuffle: the future cannot help predict the past.
How do you handle missing values?

First ask why they're missing — at random, or informative? Options: drop, impute (mean/median, model-based), or add a missingness indicator feature. Tree boosters handle NaN natively.

How do you encode categoricals?

One-hot for low cardinality. Target encoding or learned embeddings for high cardinality — with target encoding done out-of-fold, or you leak the label.

What is data leakage? Give examples.

Information at training time that won't be available at prediction time. Examples: fitting a scaler on the full dataset before splitting; features computed from the future; duplicate or same-patient rows across splits; target-encoding without folds.

Symptom: validation scores too good to be true.

Trick Should you fit normalisation on the full dataset?

No — fit on train only, then apply to validation and test. Fitting on everything leaks test statistics into training.

How do you handle class imbalance?

In rough order: use the right metric (PR-AUC, F1, recall at fixed precision); class-weighted loss or focal loss; resampling (undersample majority, oversample minority / SMOTE); tune the decision threshold. Don't resample the test set.

Trick Random split for time-series data?

No. Split by time — train on the past, validate on the future — or you leak future information. Use rolling/expanding-window validation.

What is k-fold cross-validation and when not to use it?

Split into k folds, train on k−1, validate on the rest, rotate, average. Use grouped CV when samples share an entity (patient, user), and time-based CV for temporal data. Too expensive for large deep models — use a single held-out set.

Stratified, grouped and time-series cross-validation — when each?

Stratified k-fold: keep class proportions in every fold; the default for imbalanced classification. Group k-fold: keep all samples from one entity (vehicle, patient, recording, tracked object) in the same fold, otherwise the model is tested on things it has effectively seen. Time-series split: always validate on data later than the training data.

What is walk-forward validation?

Train on data up to time t, test on the next block, then move forward and repeat — either expanding the training window or sliding a fixed-size one. It mimics how the model will be used and shows how performance changes over time, not just on average.

Why leave a gap between train and test in time-series validation?

Lag and rolling features computed near the boundary can reach into the test period, and neighbouring samples are strongly correlated. A gap (embargo) of at least the longest feature window stops that leakage.

Trick Can you report the cross-validation score you tuned hyperparameters on?

Not as an unbiased estimate. Choosing the best of many configurations on the same folds makes that score optimistic. Use nested cross-validation (tuning inside, evaluation outside) or a held-out test set touched once.

What features would you engineer from sensor time series?

Lags of the target and key signals; rolling statistics over several windows (mean, std, min, max, slope); exponentially weighted averages; differences and rates of change; time since an event; frequency-domain features such as band powers; and normalisation per operating condition so the model sees deviations rather than regime changes. Compute all of them using only past data.

Walk me through train / validation / test for a time-series model.

Sort by time and cut three consecutive blocks: train on the earliest, validate on the next (for tuning and early stopping), test on the latest, touched once. Fit scalers and encoders on train only. Leave a gap between blocks at least as long as the longest lag or rolling window. If data comes from several vehicles or engines, also keep each unit in a single split. For the final model, retrain on train + validation with the chosen settings and report the test score.

Trick Can you shuffle the training windows after a temporal split?

Yes — inside the training set. Shuffling mini-batches for gradient descent is fine and usually helps. What must never be random is the split: no validation or test window may come from before the end of the training period.

Language, before and after LLMs

Natural language processing

The spoken answer — about thirty seconds

Modern NLP turns text into sub-word tokens, maps them to vectors, and runs a transformer over them. Encoders like BERT see the whole sentence and are best for understanding tasks — classification, entity extraction, embeddings for search. Decoders like GPT see only the left context and are built to generate. Older methods still matter: TF-IDF and BM25 are strong, cheap baselines, especially for exact terms. And for evaluation, overlap metrics like BLEU and ROUGE don't measure correctness, so for clinical text you check factual consistency separately.

THREE GENERATIONS OF TEXT REPRESENTATION1 · COUNTSTF-IDF / bag of wordsorder ignoredsparse, explainablestill wins: BM25 search2 · STATIC VECTORSword2vec · GloVeone vector per wordsimilar context ⇒ similar vector'bank' has one meaning3 · CONTEXTUALBERT · GPTvector depends on sentencetransformer, pre-trainedbasis of modern NLPENCODER vs DECODER — WHAT EACH TOKEN CAN SEEBERT · bidirectionalmasked LM:fill in [MASK]→ classify, NER, embeddingsGPT · causalnext token:left context only→ generateSub-word tokensunbelievableBPE merges frequent pairs, so rarewords split and nothing is unknown.
From counting words to reading them in context. Each generation fixed the last one's blind spot: counts ignore meaning, static vectors ignore context, contextual models read the whole sentence. The attention mask is what separates an encoder from a decoder.

Questions

How does BPE tokenisation work?

Start from characters (or bytes). Repeatedly find the most frequent adjacent pair in the training corpus and merge it into a new token, until the vocabulary reaches a target size (often 32k–200k).

Common words become single tokens; rare words split into pieces, so there is no out-of-vocabulary problem. WordPiece (BERT) and SentencePiece/Unigram are close relatives.

Why not tokenise by word, or by character?

Words: huge vocabulary, and any unseen word becomes an unknown token. Characters: tiny vocabulary but very long sequences, which is expensive for attention and makes the model learn spelling from scratch. Sub-words sit in between.

Trick Why are LLMs bad at counting letters in a word?

They never see the letters. 'strawberry' arrives as two or three sub-word tokens, so the character count isn't directly in the input. The same root cause hurts arithmetic on long numbers and rhyming.

Bag-of-words and TF-IDF — what are they, and are they still useful?

Bag-of-words counts word occurrences, ignoring order. TF-IDF weights each count by how rare the word is across documents, so 'the' counts for little and 'myocarditis' for a lot.

Still useful: as a fast, explainable baseline for classification, and as BM25 in search, where it routinely beats dense retrieval on exact terms.

How does word2vec learn embeddings?

Train a shallow network to predict a word from its neighbours (CBOW) or neighbours from a word (skip-gram), using negative sampling to keep it cheap. Words appearing in similar contexts end up with similar vectors — the distributional hypothesis.

The famous result: king − man + woman ≈ queen.

Trick Does word2vec give 'bank' different vectors in 'river bank' and 'bank loan'?

No — one vector per word type, a blend of all its senses. That's the core limitation contextual models (ELMo, BERT) fixed: the vector depends on the sentence.

BERT vs GPT — what is the actual difference?

BERT is an encoder trained with masked language modelling: it sees the whole sentence in both directions. Great for understanding tasks — classification, NER, embeddings.

GPT is a decoder trained on next-token prediction with a causal mask: it only sees the left context. Built for generation. T5 and BART are encoder–decoder, suited to translation and summarisation.

What is masked language modelling, exactly?

Hide about 15% of tokens and train the model to predict them from both sides. (BERT replaces 80% of those with [MASK], 10% with a random token, 10% unchanged, so the model can't rely on seeing [MASK] at fine-tune time.)

Trick Can you generate fluent text with BERT?

Not naturally. It was never trained to produce text left to right, so there's no clean way to sample a sequence. It's an encoder; use it to read, not to write.

How do you build sentence embeddings for search?

Fine-tune an encoder with a contrastive objective on pairs that should match (question–answer, paraphrases), pulling them together and pushing in-batch negatives apart. Mean-pool the token vectors. Sentence-BERT is the classic recipe; modern embedding models follow it.

Trick Is the raw BERT [CLS] vector a good sentence embedding?

Usually not. Without contrastive fine-tuning, raw BERT embeddings cluster in a narrow cone and cosine similarity between them is poorly informative — often worse than averaged GloVe vectors.

What is named entity recognition and how is it framed?

Tagging spans like PERSON, DRUG, DATE. Framed as token classification with BIO tags (Begin, Inside, Outside), so 'acute myeloid leukaemia' becomes B-DISEASE I-DISEASE I-DISEASE. Evaluated with span-level F1, not token accuracy.

How do you evaluate generated text?

BLEU (n-gram precision, translation), ROUGE (n-gram recall, summarisation), BERTScore (embedding similarity), and increasingly LLM-as-judge plus human evaluation.

All the overlap metrics reward copying the reference's words, not being right.

Trick Does a high ROUGE score mean a summary is accurate?

No. A summary can share most of its words with the reference and still flip a negation or invent a number. For anything clinical, check factual consistency separately (entailment models, QA-based checks, or expert review).

What is perplexity?

The exponential of the average negative log-likelihood per token: roughly, how many tokens the model is choosing between at each step. Lower is better. Only comparable between models with the same tokeniser and the same test text.

Trick Lower perplexity, better clinical QA?

Not necessarily. Perplexity measures how well the model predicts text, not whether its answers are correct. Domain-adapting a model can cut perplexity sharply while factual QA barely moves — measure the task directly.

Fine-tune a classifier, or prompt an LLM?

Prompt an LLM when labels are scarce, the task changes often, or you need it working today. Fine-tune a small encoder when you have a few thousand labels, need low latency and cost at scale, or need stable, auditable behaviour. A common path: use the LLM to label data, then distil into a small model.

What NLP problems are specific to clinical text?

Abbreviations and ambiguity ('MS' = multiple sclerosis or mitral stenosis), negation ('no evidence of pneumonia'), copy-pasted note bloat, de-identification requirements, and a vocabulary general tokenisers split badly. Negation handling alone breaks many naive keyword systems.

Pre-transformer, still asked

RNNs and sequence models

RNN, UNROLLED IN TIMEh₁x₁h₂x₂h₃x₃h₄x₄h₅x₅gradient shrinks at every step backLSTM: A SEPARATE CELL STATE WITH ADDITIVE UPDATEScₜ×forget ×what to drop+input +what to addooutputwhat to exposeWhy it helpsThe cell state is updatedby addition, not repeatedmultiplication — like aresidual connection.Gradients can flow backmany steps withoutvanishing. Not forever,and still sequential.
The fix for vanishing gradients is an additive path. An RNN multiplies by the same matrix at every step; an LSTM carries a cell state that gates add to and subtract from. Transformers removed the sequential chain entirely.
Why do vanilla RNNs struggle with long sequences?

Backprop through time multiplies by the same recurrent Jacobian at every step, so gradients shrink or blow up exponentially with length — vanishing/exploding gradients.

How does an LSTM fix it?

A separate cell state updated additively, gated by forget, input and output gates. The additive path lets gradients flow across many steps — the same idea as a residual connection. GRU is a simpler two-gate variant.

Trick Does an LSTM eliminate vanishing gradients?

It mitigates them, it doesn't eliminate them. Very long dependencies are still hard, and training remains sequential — which is why attention won.

What is teacher forcing?

During training, feed the ground-truth previous token rather than the model's own prediction. Fast and stable, but creates exposure bias: at inference the model sees its own mistakes, which it never trained on.

Greedy, beam search, sampling — compare.

Greedy: argmax each step, fast, repetitive. Beam: keep top-k partial sequences, good for translation. Sampling with temperature / top-k / top-p (nucleus): diverse, better for open-ended generation.

Beyond prompting

How LLMs are trained and served

HOW A CHAT MODEL IS MADEpre-trainnext tokentrillions of tokensSFTinstruction pairs~10⁴–10⁶ examplespreferenceRLHF / DPOchosen vs rejectedservequantise, KV cachespeculative decodinglearns knowledgelearns behaviourLoRA — FINE-TUNE WITHOUT TOUCHING WWfrozen d×d+B d×rA r×dr ≪ d, so only a sliver of parameters train.BA merges into W after training — no extra inference latency.QLoRA does the same on a 4-bit quantised base model.
Pre-training buys knowledge; everything after buys behaviour. That is why fine-tuning is the wrong tool for adding facts and the right one for format, style and tool use.
Walk through the LLM training pipeline.

Pre-training: next-token prediction on trillions of tokens. Supervised fine-tuning: instruction–response pairs. Preference tuning: RLHF (reward model + PPO) or DPO directly on preference pairs. Each stage changes behaviour far more than knowledge.

RLHF vs DPO?

RLHF trains a reward model on human preferences, then optimises the policy against it with RL plus a KL penalty to the reference model. DPO skips the reward model and RL loop, optimising a closed-form classification loss on preferred vs rejected pairs. DPO is simpler and stabler; RL-based methods remain strong for reasoning.

What is LoRA, mechanically?

Freeze W; learn a low-rank update ΔW = BA with rank r ≪ d. Trains a tiny fraction of parameters and can be merged into W after training, so no inference latency cost. QLoRA does this on a 4-bit-quantised base.

What are scaling laws?

Loss falls as a smooth power law in parameters, data and compute. Chinchilla showed many models were under-trained: compute-optimal is roughly ~20 tokens per parameter. In practice, models are now over-trained past that because inference cost dominates.

Trick Does quantisation always hurt accuracy noticeably?

No. 8-bit is usually near-lossless and 4-bit (GPTQ, AWQ) costs little for large models. Damage concentrates in outlier activations, which is what those methods handle.

How does RAG work end to end?

Chunk documents → embed → store in a vector index. At query time, embed the query, retrieve top-k by similarity (often hybrid with BM25, then rerank with a cross-encoder), put them in the prompt, generate with citations.

Most RAG failures are retrieval failures, so evaluate retrieval (recall@k) separately from generation.

What is a mixture of experts?

Replace the FFN with many expert FFNs and a router that sends each token to the top-k. Total parameters are huge, but compute per token is that of a small model. Costs: load balancing, all-expert memory footprint, communication.

Why do LLMs hallucinate?

They are trained to produce probable text, not true text, and the objective rewards fluent guessing over saying 'I don't know'. Mitigations: retrieval grounding, calibrated abstention training, verification tools.

What is speculative decoding?

A small draft model proposes several tokens; the big model verifies them in one parallel pass and accepts the matching prefix. Same output distribution, 2–3× faster, because generation is memory-bandwidth-bound, not compute-bound.

Training big things

Distributed training and efficiency

DATA PARALLELGPU 0GPU 1GPU 2full model on each GPU,different batch sliceTENSOR PARALLELGPU 0GPU 1GPU 2each matrix splitacross GPUsPIPELINE PARALLELGPU 0GPU 1GPU 2layers splitacross GPUsMemory, the number that decides everything: ~16 bytes per parameter for Adam in mixed precision.weights (2) + grads (2) + fp32 master (4) + two Adam moments (8). A 7B model needs ~112 GB before activations —so you shard it (FSDP / ZeRO), checkpoint activations, or freeze it and train LoRA adapters.
Three ways to split work across GPUs. Data parallelism copies the model; tensor and pipeline parallelism cut it up. Large runs combine all three, with optimiser state sharded on top.
Data, tensor and pipeline parallelism?

Data: replicate the model, split the batch, all-reduce gradients. Tensor: split individual matrices across GPUs. Pipeline: split layers across GPUs, micro-batch to fill the bubble. Big runs combine all three.

What does ZeRO / FSDP shard?

Optimiser state, gradients and finally the parameters themselves across data-parallel workers, gathering them only when needed. Adam's states are 2× the parameters in fp32, so sharding them is the big memory win.

Mixed precision — why does it work?

Compute in fp16/bf16 for speed and memory, keep a fp32 master copy of weights for the update. fp16 needs loss scaling to avoid gradient underflow; bf16 has fp32's exponent range, so it usually doesn't.

What is gradient checkpointing?

Store only some activations in the forward pass and recompute the rest during backward. Trades roughly 30% more compute for a large memory saving.

Trick Does gradient accumulation equal a bigger batch?

Mathematically for the gradient, yes — but not for BatchNorm, whose statistics still come from the small micro-batch. Also, the LR schedule must be in terms of optimiser steps.

Memory estimate for training a 7B model with Adam?

Rule of thumb ~16 bytes per parameter for mixed-precision Adam (weights, grads, fp32 master, two moments) ≈ 112 GB before activations. That's why you shard or use LoRA.

Common at product companies

Recommender systems

TWO-STAGE RECOMMENDER10,000,000all items~500candidates · two-tower + ANN~50ranked · heavy model, rich features10shown · diversity + business rulescheap and broad at the top · expensive and precise at the bottom
The funnel is the architecture. You can't run a heavy model over millions of items per request, so a fast retrieval stage narrows the field and a slow ranking stage orders what's left.
Collaborative vs content-based filtering?

Collaborative: learn from the user–item interaction matrix (users like you liked this). Content-based: match item features to user profiles. Hybrids are standard; content features solve cold start.

Describe a two-stage recommender.

Candidate generation narrows millions of items to hundreds cheaply — two-tower embeddings with approximate nearest neighbour search. Ranking scores those with a heavy model using rich features. Often a re-ranking stage adds diversity and business rules.

How do you handle cold start?

New users: popularity, onboarding questions, contextual features. New items: content features, exploration (bandits).

Trick Is offline AUC enough to ship a recommender?

No. Logged data is biased by the old system's choices, and offline metrics correlate weakly with engagement. Ship via an online A/B test.

Enough to not be lost

Reinforcement learning

Agentpolicy π(a|s)Environmentaction aₜstate sₜ₊₁ · reward rₜGoalmaximiseexpecteddiscountedreturn:Σ γᵗ rₜγ < 1 valuessooner rewardsexplore (try new actions) vs exploit (use the best known one) — ε-greedy, UCB, Thompson sampling
No labels — only consequences. The agent acts, the environment answers with a new state and a reward, and the policy improves to collect more reward over time. RLHF is this loop with a learned reward model.
Define the core RL terms.

Agent, environment, state, action, reward, policy π(a|s), value function V(s) (expected return from s), Q(s,a) (expected return taking a in s), discount factor γ.

Exploration vs exploitation?

Exploit what you know pays off, or explore to find better. ε-greedy, UCB and Thompson sampling are the standard answers; multi-armed bandits are the simplest setting.

Value-based vs policy-gradient?

Value-based (Q-learning, DQN) learns Q and acts greedily — good for discrete actions. Policy gradient (REINFORCE, PPO) optimises the policy directly — handles continuous actions. Actor-critic combines both.

On-policy vs off-policy?

On-policy learns from data generated by the current policy (PPO). Off-policy can learn from any data, e.g. a replay buffer (Q-learning, DQN) — more sample efficient, less stable.

Trick Is PPO's clipping what stops the policy collapsing?

Largely — it clips the probability ratio so one update can't move the policy too far, a cheap approximation of TRPO's trust region. It's also why PPO was the default RL algorithm for RLHF.

Getting it into production

Deployment and MLOps

SHIPPING A MODEL SAFELYoffline evalheld-out datashadow moderuns, not servedcanary 1–5%real trafficA/B testbusiness metricfull rampwith rollbackWHAT BREAKS AFTER LAUNCHdata driftinputs shift (new scanner, new users)concept driftthe input → label rule itself changestraining–serving skewfeatures computed differently online
Each step risks a little more traffic. And launch is the start, not the end: monitor input and prediction distributions, because labels arrive late and silent failures are the common kind.
What can go wrong after deployment?

Data drift (input distribution shifts), concept drift (the input–label relationship changes), training–serving skew (features computed differently online), silent upstream breakages, and feedback loops where the model shapes its own future training data.

How do you monitor a model without labels?

Input feature distributions (PSI, KS test), prediction distribution and confidence, latency and error rates, and delayed labels or proxy metrics once they arrive.

Batch vs online inference?

Batch: precompute predictions on a schedule — cheap, simple, stale. Online: predict on request — fresh, latency-bound, needs a feature store for consistent features.

What is training–serving skew?

When features at serving time are computed differently from training. The fix is one shared feature definition — a feature store — and logging serving features for retraining.

How would you roll out a new model safely?

Offline eval → shadow mode (run alongside, don't serve) → canary to a small slice → A/B test on the business metric → gradual ramp, with automatic rollback triggers.

Trick Is a statistically significant A/B result always worth shipping?

No. Check practical effect size, guard metrics, novelty effects, peeking (repeated checking inflates false positives), and sample ratio mismatch.

What makes ML experiments reproducible?

Version code, data and config together; fix seeds; log environment and hardware; track runs (MLflow, W&B). Even then GPU non-determinism means report variance across seeds.

The open-ended round

ML system design

The framework matters more than the specific answer. Say the steps out loud.

SAY THESE STEPS OUT LOUD, IN ORDER1Clarifygoal, scale, latency2FrameML task + metric3Datalabels, leakage4Baselinesimple first5Modelfeatures, arch6Servebatch or online7Evaluateoffline → A/B8Monitordrift, retrainMost candidates jump to step 5. Spending the first minutes on 1–3 is what interviewers score highest.
A framework beats a clever model. Clarify and frame before touching architecture, and always propose a simple baseline before anything complex.
What framework do you use for ML system design?

1. Clarify the business goal and constraints (latency, scale). 2. Frame as an ML task and pick an offline metric tied to the business metric. 3. Data: sources, labels, leakage risks. 4. Features and model: start with a simple baseline. 5. Serving: batch or online, latency budget. 6. Evaluation: offline then A/B. 7. Monitoring and iteration.

Design a spam / fraud detector — key points?

Extreme imbalance, adversarial and drifting distribution, delayed labels, asymmetric costs. Tree boosting on behavioural features as baseline, a threshold tuned to the cost ratio, human review queue, frequent retraining.

Design a search ranking system — key points?

Retrieval (BM25 + dense embeddings) then learning-to-rank (pointwise / pairwise / listwise) with click data, corrected for position bias. Metrics: NDCG, MRR offline; CTR and success online.

Trick Should you start with the most powerful model?

No — start with a simple baseline. It sets the bar, exposes data problems early, and is often good enough. Interviewers listen for this explicitly.

Measuring what matters

Benchmark design

Anyone can train a model. The benchmark is what tells you whether it works — and most benchmarks are broken. These cards are about designing evaluation that catches lies before production does.

Questions

How would you design a benchmark for a new ML task?

I start from what success means to the people using it — a clinical decision, a maintenance saving — not from the loss function. Then I pick metrics that capture that, even if they're harder to compute than the easy ones.

Next, the evaluation data: split at the entity level, stratified along the axes where the model has to generalise, with deliberate edge cases. Then baselines — a trivial one and the current method — so every number has something to be compared against.

A classic cautionary example: adapting a language model to clinical notes can cut perplexity several-fold while exact-match accuracy on clinical questions barely moves. A headline metric without task-level evaluation and failure analysis tells the wrong story.

What makes a good evaluation dataset?

A few things I insist on:

  • Entity-level splits — by patient, vehicle or site, never by slice or window, or the model is tested on things it has effectively seen.
  • Stratification along the axes where generalisation matters: site, scanner, protocol, demographics, operating condition.
  • Hard and edge cases on purpose, not just whatever the random sample contained.
  • Multiple institutions if at all possible — single-site benchmarks overstate performance.
  • Enough samples that the confidence interval is narrower than the differences you want to detect.
How do you make model comparisons statistically rigorous?

Run each configuration with several seeds — three to five — and report mean ± standard deviation, not one lucky run. Compare models paired on the same test cases: a paired t-test if differences look normal, Wilcoxon signed-rank if not, or a paired bootstrap over test examples.

Report confidence intervals, not just p-values, and correct for multiple comparisons with Holm or Bonferroni when you test many models or metrics. Above all, look at the effect size: a significant 0.2-point gain may not matter to anyone.

One subtlety: with only five seeds, a two-sided Wilcoxon test can never reach p < 0.05 — the smallest possible p is 0.0625. So pairing over test examples, or a bootstrap, is usually the more useful test.

Trick Your model gets 0.92 Dice, but clinicians reject 30% of the contours. Is the benchmark wrong?

The metric is wrong for what matters. Dice measures volume overlap, which is dominated by the bulk of the structure, so it barely notices boundary errors — and boundaries are exactly what clinicians correct.

I'd add surface-distance metrics such as the 95th-percentile Hausdorff distance and average surface distance, and measure clinician editing time: a model with lower Dice can be more useful if edits take two minutes instead of twenty. And I'd stratify by structure — a 0.92 average can hide 0.70 on the one organ that matters most.

How do you do failure analysis on a benchmark?

Break the aggregate apart. I look at results by subgroup — anatomy, site, difficulty, operating condition — and at where errors cluster, for example error heat-maps over the image or the input space, and which specific classes get confused.

Then compare failure modes across models: if they fail on the same cases, the problem is likely the data or labels; if differently, an ensemble may help. Finally, I read the worst N cases myself. Systematic errors tell you far more than one more decimal of the average.

Trick Is a higher score on a public leaderboard always better?

No. Several things inflate leaderboard scores:

  • Test-set overfitting through repeated submissions and tuning.
  • Distribution mismatch — the benchmark isn't your production data.
  • Metric gaming — optimising Dice while boundary quality gets worse.
  • Contamination — the training data overlaps the test set, a real problem for LLMs trained on the web.

It's Goodhart's law: when a measure becomes a target, it stops being a good measure. Treat leaderboards as a filter, then evaluate on your own data.

How do you benchmark for domain shift and generalisation?

Hold out entire sites or institutions as an external test set, and use leave-one-site-out cross-validation to see how much performance varies. The key number is the drop from internal to external performance.

Test-time augmentation is a useful diagnostic for sensitivity to acquisition changes, and in production I'd keep monitoring metrics per site. A model validated only on its training distribution tells you nothing about deployment.

How would you benchmark an LLM-based agent?

The headline is task completion rate — binary success against objective criteria — broken down by complexity: simple tasks of 5–10 steps, medium of 10–50, complex of 50–200 or more. Underneath that I measure:

  • Tool-call accuracy: right tool, right parameters, correct reading of the result.
  • Error recovery: inject failures and see whether it recovers.
  • Context retention: does a constraint given at step 1 still hold at step 50?
  • Cost per successful completion, not per call.

Agents are non-deterministic, so every task runs three to five times and I report the spread.

Which existing agent benchmarks should you know?
  • SWE-bench (Verified, Pro): coding agents resolve real GitHub issues, judged by running the repository's tests.
  • WebArena: realistic tasks in self-hosted websites through a browser.
  • τ-bench: customer-service conversations where the agent must follow domain rules and policies.
  • AgentBench: many environments, broad but shallow.

The key point is that each reflects a specific task distribution, tool set and harness, so scores don't transfer directly to your deployment. You still need a custom evaluation on tasks that look like your production traffic.

Trick Can you evaluate an agent by scoring each of its responses?

No — agents succeed or fail at the task level. A brilliant intermediate answer followed by one wrong tool call is still a failed task.

Evaluate the whole execution trace: is state consistent across steps, does it stop at the right time — not too early, not too late — does it take unnecessary steps, and does it report its own success or failure correctly? For qualitative judgement, an LLM judge reading full traces works, ideally as a pairwise comparison of two candidate models on the same task.

How do you build a minimum viable evaluation set for an agent?
  • 20–30 tasks taken from production logs, or simulated from the inputs you expect.
  • 5–10 of them with injected failures at specific steps — a tool error, a missing file, a contradictory instruction.
  • Each task run at least three times.
  • Scored at the task level; step-level scores are for debugging only.
  • Cost per completed task recorded for every candidate model.

Report success-rate distributions, not single point estimates — with 30 tasks, one flip is more than three percentage points.

What failure modes are specific to agents?
  • Hallucinated actions: calling tools that don't exist, or with wrong parameters.
  • Loops: repeating the same failed action.
  • Context saturation: losing early constraints as the trace grows.
  • Termination failures: stopping early, or carrying on after the task is done.
  • Cascading errors: one wrong tool output poisons every later step.
  • Happy-path bias in the evaluation itself: testing only easy paths, and missing the failures that matter most in production.

Increasingly asked

Fairness, interpretability and safety

RELIABILITY DIAGRAMperfectoverconfidentpredicted probabilityactual frequencyFAIRNESS METRICS CONFLICTYou cannot satisfy all three at oncedemographic parity — equal positive ratesequalised odds — equal TPR and FPRcalibration — scores mean the same in each group(unless base rates are equal or the model is perfect)Removing the protected attribute ≠ fairPostcode, name and history act as proxies.You need the attribute to measure fairness at all.
Left: a model whose 0.9 predictions come true only 68% of the time is overconfident — fix it with temperature scaling. Right: fairness is a choice between definitions, not a box you tick.
How do you explain a model's prediction?

Global: feature importance, partial dependence. Local: SHAP (Shapley-value attributions), LIME, and for images saliency / Grad-CAM. Note they explain the model, not the world, and can be unstable.

Name some fairness definitions.

Demographic parity (equal positive rate across groups), equalised odds (equal TPR and FPR), calibration within groups. Except in trivial cases they can't all hold at once — you have to choose.

Trick Does removing the sensitive attribute make a model fair?

No. Proxies (postcode, name, purchase history) reintroduce it. You need the attribute to even measure fairness.

What is calibration and how do you fix it?

A calibrated model's 0.8 predictions are right 80% of the time. Check with a reliability diagram / ECE. Fix post hoc with temperature scaling, Platt scaling, or isotonic regression on held-out data.

Where boosting and forests start

Decision trees and random forests

The spoken answer — about thirty seconds

A decision tree splits the data greedily: at each node it tries every feature and threshold and keeps the one that most reduces impurity — Gini or entropy for classification, variance for regression. The leaves are boxes in feature space that predict a majority class or a mean, so trees need no scaling but can't extrapolate beyond the training range. A single deep tree overfits and is unstable, so I limit depth and minimum leaf size or prune it. Random forests fix the variance by averaging many deep trees trained on bootstrap samples with a random subset of features at each split; ExtraTrees go further by also randomising thresholds.

THE TREE CUTS FEATURE SPACE INTO BOXESexhaust temperature →vibration →temp ≤ 0.55 ?yesnovib ≤ 0.6 ?vib ≤ 0.35 ?okfaultokfault4 leaves = the 4 boxes on the leftIMPURITY OF A TWO-CLASS NODEentropy (max 1 bit)Gini (max 0.5)01share of class A in nodePick the split that mostreduces weighted impurity.Same shape, same choices.
A tree is a set of axis-aligned cuts. Each question splits one feature at one threshold; the leaves are boxes in feature space, each predicting its majority class (or mean value). Gini and entropy both peak for a 50/50 node and hit zero for a pure one, so they almost always choose the same split.

Questions

How does a decision tree choose each split?

Greedily. At a node it tries every feature and every candidate threshold (midpoints between sorted values), computes the impurity of the two children weighted by their size, and keeps the split with the largest drop in impurity. Then it recurses on each child until a stopping rule. It never revisits earlier splits, so the result is good, not optimal — finding the optimal tree is NP-hard.

Gini impurity vs entropy — formulas and difference?

Gini = 1 − Σ pₖ² : the chance two random samples from the node have different labels. Entropy = −Σ pₖ log₂ pₖ : bits needed to encode a label. For a 50/50 node Gini is 0.5 and entropy is 1; for a pure node both are 0. They pick the same split in the vast majority of cases; Gini is slightly cheaper (no logarithm), which is why it's the scikit-learn default.

Work out an information gain.

Parent: 10 samples, 5 fault and 5 ok → entropy 1.0. Split into left 4 (all ok, entropy 0) and right 6 (5 fault, 1 ok, entropy ≈ 0.65). Weighted child entropy = 0.4·0 + 0.6·0.65 ≈ 0.39. Information gain ≈ 1.0 − 0.39 = 0.61 bits. Being able to do this by hand is a common interview check.

Trick Does it matter much whether you use Gini or entropy?

Rarely. The curves have the same shape and almost always rank splits the same way. If an interviewer pushes, the honest answer is that tree depth and minimum leaf size matter far more than the impurity measure.

How does a regression tree work?

The same greedy splitting, but impurity is the variance (mean squared error) of the target in a node, and each leaf predicts the mean of its training targets (or the median with an absolute-error criterion). The result is a piecewise-constant function — a staircase.

Trick Can a tree predict a value outside the range it was trained on?

No. Every leaf predicts an average of training targets, so predictions are capped at the training range. If a catalyst degrades further than anything seen in training, a tree-based model keeps predicting the worst value it has seen. Linear terms, physics-based features or a different model are needed where extrapolation matters. This applies to random forests and boosting too.

How do you stop a tree from overfitting?

Pre-pruning limits growth: max_depth, min_samples_leaf, min_samples_split, max_leaf_nodes, min_impurity_decrease. Post-pruning grows a full tree then cuts back: cost-complexity pruning minimises error + α·(number of leaves), with α (ccp_alpha in scikit-learn) chosen by cross-validation. min_samples_leaf is usually the single most useful knob.

Trick A fully grown tree reaches 100% training accuracy. Good sign?

No — it's expected and meaningless. With no limits, a tree keeps splitting until every leaf is pure, memorising noise. Judge it only on validation data.

Why is a single tree considered unstable?

It has high variance: a small change in the data can change the top split, and every split below it changes too, giving a completely different tree. That instability is exactly what averaging many trees (bagging, random forests) exploits.

Trick Can a tree easily learn a diagonal boundary like x₁ > x₂?

Not easily. Each split is parallel to one axis, so a diagonal boundary needs a long staircase of splits and lots of data. If you suspect such a relationship, add the engineered feature x₁ − x₂ and a single split captures it.

How do trees handle categorical features and missing values?

Natively in some implementations (LightGBM, CatBoost, and recent scikit-learn versions can split categories into groups and route missing values to the better side). Otherwise you encode them: ordinal encoding often works well for trees; one-hot encoding a high-cardinality feature tends to hurt, because each binary column carries very little signal per split.

How does a random forest work?

Train many deep trees, each on a bootstrap sample of the rows, and at every split consider only a random subset of features (typically √p for classification, p/3 or all for regression). Average the predictions (or vote). The feature subsampling decorrelates the trees, so averaging cuts variance far more than plain bagging would.

Why does decorrelating the trees matter?

The variance of an average of B trees with variance σ² and pairwise correlation ρ is ρσ² + (1−ρ)σ²/B. Adding trees shrinks only the second term; the first stays. Lowering ρ — by restricting features per split — is what lets the forest keep improving.

Trick Does adding more trees to a random forest cause overfitting?

No. Test error levels off as trees are added; more trees only cost time and memory. That's unlike boosting, where more rounds do eventually overfit, which is why boosting needs early stopping.

What is out-of-bag error?

Each bootstrap sample leaves out about a third of the rows (the chance a row is never drawn is (1 − 1/n)ⁿ ≈ 37%). Predicting each row using only the trees that didn't see it gives a nearly free validation estimate — no separate hold-out needed. It isn't valid for time series or grouped data, for the same reasons random cross-validation isn't.

ExtraTrees vs random forest?

Extremely Randomised Trees pick the threshold for each candidate feature at random instead of searching for the best one, and by default train on the full dataset rather than bootstrap samples. Each tree is weaker but the trees are less correlated and much faster to build, so the ensemble often matches a random forest with lower variance — a good, cheap member for an ensemble.

Trick Are random forest probabilities well calibrated?

Not usually. Averaging many trees pulls predictions away from 0 and 1, so true positives often get 0.8 rather than 0.95. If you threshold on probabilities or report them, calibrate on held-out data (isotonic regression or Platt scaling).

When would you still use a single decision tree?

When the model must be explained or audited — a depth-3 tree can be read aloud as rules — or as a surrogate that approximates a complex model's behaviour for explanation. Also, because a trained tree is just nested if-statements, it compiles trivially to C for embedded targets.

Still the tabular workhorse

Gradient boosting and ensembles

The spoken answer — about thirty seconds

Gradient boosting builds shallow trees one after another, each fitting the gradient of the loss left by the trees before it. XGBoost uses first and second derivatives to score splits, with L2 on leaf weights and a minimum gain to split. LightGBM grows leaf-wise on binned features, so it is fast but needs num_leaves kept in check. I control overfitting with a modest learning rate and early stopping, limits on tree size, and row and column subsampling. To combine models I start with averaging probabilities, and only stack — with out-of-fold predictions — if it clearly beats the best single model.

STACKING — THE META-MODEL ONLY SEES OUT-OF-FOLD PREDICTIONSfold 1fold 2fold 3fold 4fold 5train on 4 folds, predict the held-out one→ every row gets an honest predictionExtraTreesOOF p₁XGBoostOOF p₂LightGBMOOF p₃meta-modellogistic regressionfinalBlendingmeta-model fit on a singleheld-out split — simpler, noisierSoft votingaverage probabilities, weightstuned on OOF — often enoughLeak to avoidmeta-model trained on in-foldpredictions learns to trust overfit
Three ways to combine models, in rising complexity: average their probabilities, fit a meta-model on one held-out split (blending), or fit it on out-of-fold predictions from every row (stacking). The out-of-fold step is what keeps stacking honest.

Questions

When do you reach for gradient-boosted trees?

Tabular data with mixed numeric and categorical features, up to millions of rows — sensor summaries, logs, engineering parameters. They usually beat neural networks there, need little preprocessing (no scaling, native missing values) and train in minutes. Neural networks win on raw images, audio, text and long raw sequences.

How does XGBoost choose a split?

It uses the first and second derivatives (gradient g and hessian h) of the loss for each row. For a candidate split, gain ≈ ½[G_L²/(H_L+λ) + G_R²/(H_R+λ) − (G_L+G_R)²/(H_L+H_R+λ)] − γ, where G and H are summed over each side. It takes the split with the highest gain and only keeps it if gain exceeds γ. λ shrinks leaf values; γ is a minimum gain to split.

XGBoost vs LightGBM vs CatBoost?

XGBoost: grows trees level by level; robust default. LightGBM: grows leaf-wise (always splits the best leaf) on histogram-binned features — much faster on large data, but overfits more easily on small data. CatBoost: handles categorical features natively with ordered target statistics, which avoids target leakage; strong out of the box.

Which regularisation knobs matter most?

learning_rate with n_estimators chosen by early stopping; tree size (max_depth or LightGBM's num_leaves); min_child_weight / min_data_in_leaf; row and column subsampling (subsample, colsample_bytree); L1/L2 on leaf weights (alpha, lambda); and gamma, the minimum gain to split.

Trick Does setting max_depth limit a LightGBM model?

Not by itself. LightGBM grows leaf-wise, so num_leaves is the main complexity control. A tree with max_depth = 7 can still have up to 128 leaves; keep num_leaves well below 2^max_depth on small data.

What is a sensible tuning order?

Fix a moderate learning rate (0.05–0.1) and use early stopping on a validation fold for the number of trees. Tune tree size and min-leaf size, then subsampling, then L1/L2. Finally lower the learning rate and raise the number of trees for the last bit of accuracy.

How do you read feature importance from a boosted model?

Three built-in kinds: split count (how often a feature is used), gain (total loss reduction it delivers) and cover. Better: permutation importance on validation data (drop in score when a feature is shuffled) and SHAP values, which give consistent per-prediction attributions.

Trick A feature tops the split-count importance. Is it the most useful?

Not necessarily. Continuous and high-cardinality features offer many split points, so they get used often even when each split gains little. Correlated features also share credit unpredictably. Check gain, permutation importance or SHAP before claiming a feature matters.

What are monotonic constraints and why do engineers like them?

You force the prediction to only increase (or decrease) with a feature, e.g. wear should never fall as operating hours rise. It removes physically impossible wiggles, makes the model easier to trust, and usually costs little accuracy.

Stacking vs blending vs voting?

Voting/averaging: average the models' probabilities, optionally weighted. Blending: train a meta-model on predictions for one held-out split. Stacking: train it on out-of-fold predictions for every training row, so it uses all the data. Stacking is the most data-efficient; averaging is the hardest to overfit.

Trick Why must stacking use out-of-fold predictions?

Because in-fold predictions are optimistic. A model predicting its own training rows looks better than it is, so the meta-model learns to trust whichever base model overfits most. Out-of-fold predictions are what each model would really produce on new data.

When does an ensemble actually help?

When the members make different errors. Three boosted-tree libraries on the same features are highly correlated, so the gain is often small; mixing model families (trees with a linear model or a neural network) or different feature sets helps more. Always compare the ensemble against its best single member.

How do you explain an ensemble result in an interview?

State, in order: the members and why each (e.g. ExtraTrees for variance, XGBoost and LightGBM for accuracy); how they were combined (averaged probabilities, weights tuned on out-of-fold predictions, or a meta-model); how the decision threshold was set if you optimised macro-F1; the validation scheme behind the number; and how much the ensemble beat the best single model. Precision about the combination method is what interviewers probe.

Trick Is a boosted model with 0.95 macro-F1 on a small dataset trustworthy?

Only with the right validation. On small data, report the mean and spread across folds rather than one split; group the folds if samples share an object or recording, and make sure thresholds and weights were tuned inside the cross-validation, not on the test set.

Spectra, windows and transfer functions

Signal processing: FFT, Welch and H1/H2

The spoken answer — about thirty seconds

Frequency resolution is fs over N — one over the record length — and zero-padding only interpolates. The FFT assumes the record repeats, so a signal that doesn't fit a whole number of cycles leaks energy across bins; a window like Hann tapers the edges to control it, and flat-top is used when amplitude accuracy matters. A single FFT of a random signal is noisy, so Welch's method averages windowed, overlapping segments. For a transfer function, H1 divides the cross-spectrum by the input auto-spectrum and is right when noise is on the output; H2 is right when noise is on the input; coherence tells you where to trust either.

SPECTRAL LEAKAGE10.5 cycles in the record · magnitude in dB, 60 dB rangerectangular windowenergy smears into every binHann windowwider peak, far lower sidelobesWELCH'S METHODsegments, 50% overlap, each windowedaverage |FFT|²variance ↓ ~ 1/segmentsΔf = fs / N = 1 / TResolution is set by recordlength; zero-padding only interpolates.Choosing a windowHann: general, random signalsflat-top: accurate amplitudesH1 = Gyx/Gxx · H2 = Gyy/GxyH1: noise on output (antiresonance)H2: noise on input (resonance)
The FFT assumes the record repeats forever. If it doesn't fit a whole number of cycles, the jump at the edges leaks energy across the spectrum; a window tapers the edges to contain it. Welch's method then averages many windowed segments so the estimate stops being noisy.

Questions

What does the FFT give you, and what sets its frequency resolution?

The discrete Fourier transform of N samples: amplitude and phase at N frequency bins from 0 to fs. Bin spacing is Δf = fs/N = 1/T, where T is the record length in seconds. Usable range is up to the Nyquist frequency fs/2.

Trick Does zero-padding improve frequency resolution?

No. It adds samples of zero, which interpolates the same spectrum on a finer grid — peaks look smoother and are easier to locate, but two close frequencies that weren't separable still aren't. Only a longer real record improves resolution.

What is spectral leakage?

The FFT treats the record as one period of an endlessly repeating signal. If a sine doesn't complete a whole number of cycles, the repeated record has a jump at the edges, and the sine's energy spreads into neighbouring bins and far-off sidelobes, hiding weaker components.

How do window functions help, and what do they cost?

They taper the record to zero at both ends, removing the edge jump, so sidelobes drop sharply. The cost is a wider main lobe (poorer resolution) and lost energy, which you correct with an amplitude or energy correction factor.

Hann vs Hamming vs flat-top — when each?

Hann: the general default, first sidelobe about −31 dB and sidelobes falling fast; good for random signals and Welch averaging. Hamming: lower first sidelobe (about −43 dB) but sidelobes fall slowly; good for separating close tones of similar level. Flat-top: very wide main lobe but amplitude error under about 0.01 dB; use when the exact amplitude of a tone matters, as in calibration. Rectangular is right only for transients that die out within the record, or signals periodic in the window.

Trick Can you remove aliasing after sampling?

No. Once a frequency above fs/2 has folded down, it is indistinguishable from a genuine low frequency. You need an analogue anti-aliasing low-pass filter before the ADC, or a higher sample rate.

What is a PSD and why not just take one FFT?

The power spectral density shows how a signal's power is distributed over frequency, in units per Hz. A single FFT periodogram of a random signal is very noisy: its standard deviation is about as large as the value itself, however long the record. You need averaging.

Explain Welch's method.

Split the record into segments (often 50% overlap with a Hann window), window each, take the FFT, and average the squared magnitudes. Variance falls roughly with the number of averages. The trade-off: shorter segments mean more averages but coarser Δf.

Why overlap segments by 50%?

The window down-weights each segment's edges, so data there would be under-used. Overlapping recovers it and gives more averages from the same record. Beyond about 50–67% overlap the extra segments are highly correlated and add little.

What is the cross-spectral density?

G_xy(f): the average of X*(f)·Y(f) across segments, for input x and output y. Its magnitude shows shared power at each frequency, and its phase the time or phase lag between them. It's the building block of frequency-response and coherence estimates.

What is coherence?

γ² = |G_xy|² / (G_xx·G_yy), between 0 and 1 at each frequency: the fraction of the output explained linearly by the input. Low coherence means noise, non-linearity, leakage or an unmeasured input. Check it before trusting any frequency-response estimate.

H1 vs H2 — which estimator, when?

H1 = G_yx / G_xx is unbiased when noise is on the output and biased low when the input is noisy. H2 = G_yy / G_xy is unbiased when noise is on the input and biased high with output noise. In a structural test, output SNR is worst at antiresonances, so H1 is better there; at resonances the shaker force drops and input noise dominates, so H2 is better. H1/H2 = γ², so where coherence is high they agree.

How does signal-to-noise ratio affect the choice?

Identify where the noise enters. If the input measurement is clean and the response sensor noisy, use H1; if the force or input signal is noisy, use H2; if both, consider Hv (a geometric-mean / total-least-squares estimate). Low SNR also calls for more averages, and coherence tells you where the estimate is unreliable.

What frequency-domain features would you build for a model?

Band powers from a Welch PSD in physically meaningful bands, dominant frequency and its amplitude, spectral centroid, and for vibration the kurtosis and crest factor (peak over RMS), which rise early with bearing faults. Order tracking normalises by shaft speed for rotating machinery.

Where ML meets the controller

Control, drift and sequence models

The spoken answer — about thirty seconds

A PID controller acts on the error between target and measurement: proportional for the error now, integral to remove steady offset, derivative for damping. ML usually replaces the calibrated maps and feedforward around that loop, or adds a virtual sensor, rather than the feedback itself. RL could learn a dosing policy, but it is hard to validate because exploration is unsafe and there are no stability guarantees, so it needs a simulator and a safety fallback. Catalysts age, so I'd handle gradual drift by making age a feature, monitoring residuals and retraining on recent data.

THE PID LOOPΣtargetePKp·eIKi·∫e dtDKd·de/dtplantengine + SCRysensor feedback (e.g. NOx)What each term doesP — reacts to the error now; leaves a steady offsetI — removes offset; can wind up when saturatedD — damps overshoot; amplifies sensor noiseML usually replaces the hand-tuned maps around it.DRIFT: THE SAME INPUT MEANS SOMETHING DIFFERENT OVER TIMEcatalyst efficiencymodel trained hereoperating hours →Gradual drift → make age a featureHours, mileage or a health index lets one modelcover the whole life. Retrain on recent windows,monitor residuals, and keep a rule-based fallback.
Top: a PID controller turns the error between target and measurement into an action. Bottom: as a catalyst ages, the same inputs produce different outputs, so a model frozen at launch slowly goes wrong.

Questions

Explain PID control in three sentences.

The controller computes the error between the setpoint and the measurement. Its output is Kp·e + Ki·∫e dt + Kd·de/dt: the proportional term reacts to the current error, the integral term to accumulated error, the derivative term to how fast the error is changing. Tuning the three gains trades speed against overshoot and stability.

Trick Why can't a P-only controller reach the setpoint exactly?

Because it needs a non-zero error to produce any output. If holding the target needs a constant actuator effort, the loop settles where the error is just large enough to produce it — a steady-state offset. The integral term accumulates error until the offset is gone.

What is integral wind-up?

When the actuator saturates (a valve fully open, a dosing limit reached), the error persists and the integral keeps growing. When conditions change, the huge stored integral causes a long overshoot. Fixes: clamp the integrator, or stop integrating while saturated.

Why is the derivative term often filtered or dropped?

Differentiating a noisy sensor amplifies high-frequency noise, making the actuator jitter. It's usually low-pass filtered or computed on the measurement rather than the error, to avoid a spike when the setpoint jumps.

In an emission-control system, what would ML replace?

Rarely the PID loop itself. More often the calibrated lookup maps and feedforward terms around it — e.g. how much reductant to dose for a given exhaust state — or a virtual sensor estimating a quantity that's expensive or slow to measure, or a model-predictive controller that plans ahead using a learned model. The PID stays as a robust feedback layer.

How would you formulate emission control as an RL problem?

State: sensor readings (exhaust temperature, flow, NOx upstream and downstream, catalyst temperature and age). Action: dosing rate or setpoint adjustments. Reward: minus NOx emitted, minus a penalty for reductant use and for ammonia slip, with hard limits as constraints. Training would happen in a simulator or on logged data.

Policy gradient or Q-learning for a continuous dosing command?

Q-learning needs a max over actions, which is awkward for continuous actions. Policy-gradient and actor-critic methods (PPO, SAC, TD3) output continuous actions directly, so they are the natural fit. With only logged data, use an offline method.

Why is RL hard to validate in a safety-critical controller?

Exploration is unsafe on real hardware; a learned policy has no stability or performance guarantee like a tuned PID; it can exploit simulator errors that don't exist in reality; behaviour on rare states is untested; and regulators need predictable, explainable behaviour. Mitigations: train in simulation, constrain actions, wrap it in a rule-based safety shield, evaluate offline, and test hardware-in-the-loop.

Trick Is a high simulated reward evidence that a controller is safe?

No. It shows the policy does well on the states and the simulator it saw. It says nothing about states it never visited or where the simulator is wrong, which is exactly where safety failures happen.

What is concept drift, and what kinds are there?

The relationship between inputs and the target changes over time. Types: sudden (a new sensor firmware), gradual or incremental (catalyst ageing, component wear), and recurring (seasons). Data drift — inputs changing while the relationship holds — is a different problem.

How do you detect drift in production?

Watch prediction residuals once ground truth arrives, with change detectors like Page-Hinkley or ADWIN; watch input distributions (PSI, KS tests); and compare against a physics model or a reference fleet. For slow drift, plot error against age or mileage, not just time.

How would you adapt a model to an ageing catalyst?

If ageing is measurable, add it as a feature — operating hours, thermal load history or an estimated health index — so one model spans the whole life. Otherwise retrain on a recent sliding window or weight recent data more, or update incrementally with an online learner. Validate each update before deploying.

Trick Does retraining only on recent data always help?

Not always. A model trained only on the last month can forget rare but important conditions — cold starts, winter — that happened earlier. Keep a representative replay set alongside recent data.

LSTM or temporal CNN for sequence prediction?

A TCN uses causal, dilated 1-D convolutions: training is fully parallel, gradients are stable, and the receptive field grows exponentially with depth but is fixed. An LSTM processes steps sequentially — slower to train, harder gradient flow — but carries a compact state, so inference on a stream is cheap per step and context is not hard-capped. TCNs often match or beat LSTMs on benchmarks; LSTMs remain attractive on microcontrollers for step-by-step streaming.

What is the receptive field of a TCN, and why does it matter?

With kernel size k and dilations doubling each layer (1, 2, 4…), the receptive field is roughly 1 + (k−1)(2^L − 1) steps after L layers. Anything further back is invisible, so choose depth to cover the slowest dynamics you care about, such as catalyst thermal lag.

What is a feedforward map plus a PID loop?

Feedforward: a calibrated lookup table (a map) that sets the actuator from the operating point — e.g. reductant dose from engine speed, load, exhaust temperature and flow — before any error appears. Feedback: a PID loop that corrects the remaining error using a sensor. The map does most of the work quickly; the PID cleans up what the map got wrong.

Trick If the feedforward map were perfect, would you still need the PID?

Yes. The map can't know about disturbances, sensor offsets, part-to-part variation or ageing. Feedback is what makes the system robust to everything the map didn't anticipate — which is also why ML usually improves or replaces the map rather than the feedback loop.

What is gain scheduling?

Using different PID gains at different operating points — looked up from a map of speed, load or temperature — because a plant behaves differently across its range. It's the classical way to handle non-linearity, and the natural place an ML model can provide smoother or better-tuned gains.

Where exactly would an ML model sit in that structure?

Three common places: replacing or correcting the feedforward map with a learned model that generalises better between calibration points; acting as a virtual sensor that estimates something not directly measured, like stored ammonia on the catalyst; or providing a learned plant model for a model-predictive controller. The PID feedback usually stays as the safety net.

Small data, honest uncertainty

Gaussian process regression

The spoken answer — about thirty seconds

A Gaussian process is a prior over functions defined by a kernel, which encodes how smooth the function is and how far correlations reach. Conditioning on data gives, in closed form, a mean prediction and a variance at every point — small near the data, widening away from it. I'd fit the kernel's length-scale, signal variance and noise by maximising the log marginal likelihood, which balances fit against complexity. GPs suit small, smooth, physical problems where uncertainty matters; the catch is cubic cost in the number of points, so beyond about ten thousand you need sparse approximations.

GP POSTERIOR: A MEAN AND AN HONEST BANDno data here →uncertainty widensmean ± 2σ · dots = training pointsKernel = prior on shapeRBF: smooth, length-scale ℓMatérn: rougher, more realistic+ noise σₙ², × signal varianceHyperparametersmaximise log marginallikelihood: fit − complexityCost O(n³)sparse GPs past ~10⁴ points
A GP gives a whole distribution over functions. Near observed points it is confident; between and beyond them the band widens. The kernel decides how smooth and how far-reaching the function is assumed to be.

Questions

What is Gaussian process regression?

A prior over functions: any finite set of function values is jointly Gaussian, defined by a mean function (often zero) and a kernel k(x, x′) giving the covariance between any two inputs. Conditioning on observed data gives a closed-form posterior mean and variance at every new point.

What does the kernel encode?

Your assumptions about the function: smoothness, length-scale (how far apart inputs must be before values become unrelated), periodicity, and noise level. RBF assumes infinitely smooth functions; Matérn (ν = 3/2 or 5/2) allows rougher, more physical behaviour; kernels can be added and multiplied to combine structure.

What are the RBF kernel's hyperparameters?

k(x, x′) = σ_f² · exp(−‖x − x′‖² / 2ℓ²), plus a noise term σ_n² on the diagonal. ℓ, the length-scale, sets how quickly correlation decays; σ_f² the vertical scale of variation; σ_n² the observation noise. With ARD, each input dimension gets its own ℓ, which doubles as a relevance measure.

How are hyperparameters fitted?

By maximising the log marginal likelihood of the data, integrating out the function. It has a data-fit term and a complexity penalty (the log-determinant of the covariance), so it automatically trades fit against flexibility — Occam's razor built in. Gradient-based, with several restarts because it can have multiple optima.

Why use a GP instead of a neural network?

Small data (tens to a few thousand points), smooth physical relationships, and a need for uncertainty that grows away from the data. Common in experimental science, calibration, surrogate modelling of expensive simulations, and Bayesian optimisation.

Trick Are GP uncertainties automatically trustworthy?

Only if the kernel fits the problem. A length-scale that is too long gives confidently wrong predictions; a stationary kernel on non-stationary data gives misleading bands. Check calibration on held-out data, as with any model.

What limits GPs at scale?

Exact inference inverts an n × n matrix: O(n³) time and O(n²) memory, so it becomes impractical past roughly 10,000 points. Sparse GPs use m ≪ n inducing points (about O(nm²)); structured kernels and GPU libraries (GPyTorch) push further.

What is a multi-output GP?

A GP that models several related outputs jointly, so learning one helps predict the others. The common form, the linear model of coregionalisation, writes the covariance as a product of an input kernel and a matrix of correlations between outputs. Useful when outputs are physically coupled, such as temperatures at several points along a combustor.

How do you present a Gaussian-process project in an interview?

Lead with the problem (for example, reconstructing a physical field from a few measurements), why a GP (small data, smooth behaviour, uncertainty needed), which kernel and how its hyperparameters were fitted, whether outputs were modelled jointly and why, and how the predicted uncertainty was checked against held-out or experimental data.

GP vs kernel ridge regression?

The posterior mean of a GP equals the kernel ridge regression solution with the same kernel and regularisation. What the GP adds is the predictive variance and a principled way, the marginal likelihood, to choose hyperparameters.

Knowing when the model doesn't know

Uncertainty and conformal prediction

The spoken answer — about thirty seconds

Uncertainty comes in two kinds: aleatoric, noise in the data, and epistemic, the model not having seen enough. Softmax scores aren't trustworthy uncertainty. Deep ensembles are the strong baseline, MC dropout the cheap one. Conformal prediction is the practical tool: it wraps any trained model, uses a held-out calibration set, and outputs prediction sets or intervals with a guaranteed coverage — say 90% — as long as the test data looks like the calibration data. The guarantee is on average, not per case, and it breaks under distribution shift.

SPLIT CONFORMAL PREDICTION — FOUR STEPS1 · splithold out acalibration set2 · scorenonconformity:1 − p(true class)3 · thresholdq̂ = the ⌈(n+1)(1−α)⌉/nquantile of scores4 · predictinclude every classwith score ≤ q̂CALIBRATION SCORESq̂ (90%)low score = model agrees with truthPrediction set for a new image{ melanoma, naevus } — two classes pass the thresholdbig set ⇒ the model is unsure; it says so honestlyGuarantee: P(true label ∈ set) ≥ 1 − αany model, any distribution — if data are exchangeable
Conformal prediction wraps any trained model. You don't retrain anything: a held-out calibration set tells you how large the prediction set must be to contain the truth 90% of the time.

Questions

Aleatoric vs epistemic uncertainty?

Aleatoric: noise in the data itself — a blurry scan, an ambiguous label. More data doesn't remove it.

Epistemic: the model's ignorance — inputs unlike the training data. More data, or the right data, does reduce it. Out-of-distribution inputs should show high epistemic uncertainty.

Trick Is a softmax probability of 0.98 a measure of confidence?

Not reliably. Softmax outputs are often overconfident, and a network can output 0.98 on an input unlike anything it was trained on. Calibration fixes the first problem on in-distribution data; it doesn't fix the second.

What is MC dropout?

Keep dropout switched on at test time, run the same input several times, and treat the spread of predictions as uncertainty. Cheap — no retraining — and an approximation to Bayesian inference. In practice it usually underestimates uncertainty compared with ensembles.

Why are deep ensembles the usual baseline?

Train several models from different random initialisations and average them. Disagreement between members is a strong uncertainty signal, and accuracy usually improves too. The cost is N times the training and inference.

What is conformal prediction?

A wrapper that turns any model's outputs into prediction sets (classification) or intervals (regression) with a guaranteed coverage rate, using a held-out calibration set. No assumptions about the model or the data distribution beyond exchangeability.

Walk through split conformal for classification.

Hold out n calibration examples. Score each with a nonconformity score, e.g. 1 − p(true class). Take q̂ as the ⌈(n+1)(1−α)⌉/n quantile of those scores. For a new input, include every class whose score is ≤ q̂.

Result: the set contains the true label with probability at least 1 − α.

Trick Does conformal guarantee 90% coverage for each patient?

No — the guarantee is marginal: 90% averaged over the population. A subgroup can be under-covered while the average holds. Conditional coverage per input is impossible in general; Mondrian (group-wise) conformal gives coverage per chosen group, such as per site or per class.

Trick Do you need to retrain the model to use conformal?

No. It's post-hoc. It needs only a calibration set the model didn't train on. That makes it practical for an already-deployed or third-party model.

How does conformal work for regression?

Score with the absolute residual |y − ŷ| on the calibration set, take the quantile q̂, and predict ŷ ± q̂. Those intervals are the same width everywhere; conformalised quantile regression (CQR) starts from quantile predictions so intervals widen where the data is noisier.

What breaks conformal's guarantee?

Distribution shift. The guarantee assumes calibration and test data are exchangeable. A new scanner, a new truck model or seasonal drift violates that. Fixes: recalibrate on recent data, weighted conformal under covariate shift, or adaptive conformal for time series.

How do you detect out-of-distribution inputs?

Baselines: maximum softmax probability, energy score, Mahalanobis distance in feature space, ensemble disagreement. Evaluate with AUROC between in- and out-of-distribution sets — ideally with realistic shifts, not just a different dataset.

What is selective prediction?

Let the model abstain when uncertain and hand those cases to a human. Plot a risk–coverage curve: error rate on accepted cases against the fraction accepted. In medicine and safety-critical systems, this is how uncertainty becomes a workflow.

Trick Is a well-calibrated model a model with good uncertainty?

Not necessarily. A model predicting the base rate for every input is perfectly calibrated and useless. You want calibration and sharpness — confident where it can be, uncertain where it should be.

Where would you use this in predictive maintenance?

Give an interval on remaining useful life instead of a point estimate, so maintenance is scheduled against the lower bound. Conformal intervals on RUL are a clean, defensible answer — and flag the distribution-shift caveat for new vehicle variants.

Sensors over time

Time series, anomaly detection and RUL

The spoken answer — about thirty seconds

For forecasting I always start from a naive baseline and gradient boosting on lag features, and only add deep models if they beat them on a time-based split. Anomaly detection is mostly unsupervised: model what normal looks like and flag large deviations, then set the threshold by how many alerts people can act on. For remaining useful life, I split by machine, not by window, cap the target early in life when there's no degradation to see, treat machines that haven't failed yet as censored, and penalise late predictions more than early ones.

ANOMALY DETECTION ON A SENSOR SIGNALpoint anomalylearn normal → flag large residual / reconstruction errorREMAINING USEFUL LIFEcapped at e.g. 125 cyclescycles →RULnowSplit by unit, not by rowWindows from one enginemust not appear in bothtrain and test.CensoringMost machines haven'tfailed yet. Their RUL is'at least t' → survival models.Late is worse than earlyPredicting failure too latecosts a breakdown; too earlycosts a part. Score asymmetrically.
Two questions about the same sensors. Anomaly detection asks 'is this unusual right now?'; RUL asks 'how long until it fails?'. Both live or die on how you split the data and what you count as an error.

Questions

What are the components of a time series?

Trend, seasonality (fixed-period patterns) and residual noise. Many classical models assume stationarity — constant mean and variance — so you difference or detrend first.

What baseline should any forecaster beat?

Naive (tomorrow = today) and seasonal naive (next Monday = last Monday). They're often surprisingly hard to beat, and reporting against them is what makes a result credible. MASE is literally error scaled by the naive forecast's error.

Trick Does a deep model usually beat gradient boosting on lag features?

Often not, on typical industrial tabular time series. LightGBM on lags, rolling means and calendar features is a very strong baseline. Deep models (TCN, LSTM, PatchTST) and foundation models (Chronos, TimesFM) earn their place with many related series or long, rich histories.

Which error metric for forecasting?

MAE (robust, interpretable), RMSE (punishes large misses), MASE (scale-free, comparable across series). Avoid MAPE when values approach zero — it explodes and is asymmetric.

Three types of anomaly?

Point: one reading far off. Contextual: normal value, wrong context (high load at 3 a.m.). Collective: each point fine, the sequence abnormal (a vibration pattern).

How do you detect anomalies with few or no labels?

Model normal behaviour and flag deviation: robust statistics (median and MAD rather than mean and std), Isolation Forest, forecast residuals, or autoencoder reconstruction error. Then set the threshold by the alert rate operators can actually handle.

Trick Does an autoencoder always reconstruct anomalies badly?

No. A powerful autoencoder can generalise well enough to reconstruct anomalies too, and if training data contains unlabelled anomalies it learns them as normal. Keep it constrained and clean the training set.

How do you evaluate anomaly detection?

Precision and recall at the operating threshold, precision@k, and the lead time — how early before the failure it fired. Labels are scarce, so get domain experts to review the top alerts.

Trick What is wrong with 'point-adjusted' F1?

It inflates scores badly. Point adjustment counts a whole anomalous segment as detected if any single point in it is flagged, so even random scores can look strong. Several published benchmarks were shown to be largely artefacts of it.

What is remaining useful life prediction?

Predict how many cycles or hours a component has before failure, from sensor history. Classic benchmark: NASA C-MAPSS turbofan engines, with run-to-failure trajectories.

Why cap the RUL target at a constant?

Early in life a healthy engine shows no degradation, so predicting 300 vs 250 cycles is guesswork. A piecewise-linear target — constant (e.g. 125) until degradation begins, then decreasing — matches what the sensors can actually reveal and trains better.

Trick Train/test split for RUL — by window or by unit?

By unit. Random windows from the same engine in both sets leak that engine's specific behaviour, and test scores look far better than they will in the field.

How do you handle machines that haven't failed?

They're right-censored: you know they lasted at least this long. Dropping them biases the model towards short lives. Survival analysis — Cox models, Weibull, deep survival models — uses them properly.

How do you set up features for multivariate sensors?

Fixed-length sliding windows; per-sensor normalisation, ideally per operating condition (load, ambient temperature) so the model sees degradation rather than regime changes; drop constant sensors.

Making models small and fast

Efficient inference and quantisation

The spoken answer — about thirty seconds

There are four levers. Quantisation stores weights and activations in fewer bits — int8 is usually near-lossless with post-training calibration, and 4-bit needs smarter methods or quantisation-aware training. Pruning removes weights, and only structured pruning reliably speeds things up. Distillation trains a small model to imitate a large one. Then compilers like TensorRT fuse operations and pick fast kernels. FLOPs aren't latency, so I always benchmark on the target device and re-check accuracy after each step.

QUANTISATION: A 7B MODEL, FEWER BITSfp3228 GBbf1614 GBint87 GBint43.5 GBq = round(x / s) + zs = scale, z = zero point.Per-channel scales beat one scale per tensor.Outlier activations are what break LLMs.THE TOOLBOXPTQquantise after training; small calibration setQATsimulate quantisation while trainingpruningremove weights; structured = real speed-updistillationsmall student mimics big teachercompileONNX → TensorRT / OpenVINO, op fusionmeasure on the target device: FLOPs ≠ latency
Smaller numbers, fewer weights, better kernels. Quantisation shrinks memory 2–8×; whether it also speeds things up depends on the hardware having fast low-precision kernels.

Questions

What is quantisation, mechanically?

Map floating-point values to low-bit integers with a scale and zero point: q = round(x/s) + z, and back as x ≈ s(q − z). Weights shrink 4× from fp32 to int8, and integer arithmetic is cheaper on hardware that supports it.

Symmetric vs asymmetric; per-tensor vs per-channel?

Symmetric fixes the zero point at 0 — simpler, good for weights. Asymmetric adds a zero point — better for skewed activations like post-ReLU. Per-channel gives each output channel its own scale and is noticeably more accurate for weights.

PTQ vs QAT?

Post-training quantisation: quantise a trained model using a small calibration set to pick ranges. Fast, no retraining; fine for int8 on most CNNs.

Quantisation-aware training: insert fake-quantise ops during fine-tuning so the model learns to tolerate rounding (straight-through estimator for gradients). Needed when PTQ loses too much, typically at 4 bits or for small, sensitive models.

Trick Does int8 always make inference faster?

No. Only if the hardware and runtime have int8 kernels for your ops. Weight-only quantisation mainly saves memory and bandwidth — which is why it speeds up LLM decoding, which is memory-bound — but adds dequantisation overhead on compute-bound workloads.

Why is quantising LLMs harder than CNNs?

A few activation channels have huge outliers, so one scale per tensor wastes almost all the integer range on them. Fixes: LLM.int8 (keep outliers in fp16), SmoothQuant (shift the difficulty from activations into weights), GPTQ and AWQ (error-aware weight quantisation to 4 bits).

Unstructured vs structured pruning?

Unstructured removes individual weights — high sparsity, little accuracy loss. Structured removes whole channels, heads or layers — the model genuinely gets smaller and faster.

Trick Does 90% unstructured sparsity make a model 10× faster?

Usually not at all on GPUs. Dense hardware still multiplies the zeros unless you have sparse kernels or special patterns (e.g. NVIDIA 2:4 sparsity). Structured pruning is what gives reliable speed-ups.

How does knowledge distillation work?

Train a small student to match a large teacher's soft output distribution, with temperature T > 1 to expose the 'dark knowledge' in wrong-class probabilities, usually mixed with the normal hard-label loss.

What do ONNX and TensorRT do?

ONNX is a portable model format. Runtimes like TensorRT, OpenVINO or TFLite then optimise the graph for a target: fuse ops (conv + BN + ReLU into one kernel), choose fast kernels, use fp16/int8, plan memory. Often a 2–5× gain without touching accuracy.

Latency vs throughput?

Latency: time for one request (watch p95/p99, not just the mean). Throughput: requests per second. Batching raises throughput and usually hurts latency. Real-time perception cares about latency; offline scoring cares about throughput.

Trick A model with half the FLOPs — half the latency?

Not necessarily. Latency depends on memory traffic, kernel efficiency and parallelism too. Depthwise convolutions have few FLOPs but low arithmetic intensity, so they can run slower than expected. Always measure on the target device.

How do you benchmark inference properly?

On the target hardware, with warm-up runs, synchronised timing on GPU, realistic input sizes and batch, many iterations, and percentiles reported. And check accuracy after every optimisation step.

What constraints matter on embedded automotive hardware?

Fixed memory and power budgets, int8 NPUs with limited operator support, deterministic real-time deadlines, and safety certification. Design for the accelerator's supported ops from the start, rather than converting at the end.

How do you describe model-optimisation work precisely?

Name the levers precisely: 'post-training int8 quantisation with per-channel weights and a 500-image calibration set, exported through ONNX to TensorRT, latency from X to Y ms on Z hardware, accuracy drop under N points'. Precision of vocabulary is what interviewers listen for.

From PyTorch to an ECU

THE EXPORT PATHPyTorchmodel.eval()ONNXfixed shapes, opsetC codegenerated or hand-writtenECUstatic memory, WCETonnxruntime vs PyTorchC vs onnxruntimeon target vs C on PCsame golden input vectors at every step · compare outputs within a stated toleranceTESTING LADDERMILmodel in the loopmodel + plant simSILsoftware in the loopgenerated C on PCPILprocessor in the loopC on target CPUHILhardware in the loopreal ECU, simulated engineeach rung swaps one simulated piece for the real one — find bugs where they are cheapest
Every conversion is a chance to silently change the model. So the same test vectors run through each stage and the outputs are compared, then the code climbs the in-the-loop ladder from pure simulation to the real control unit.
Walk through the path from a trained PyTorch model to code on an ECU.

Put the model in eval mode and export to ONNX with fixed input shapes and a chosen opset. Check it with onnxruntime against PyTorch on golden test vectors. Generate C code from the ONNX graph — or hand-write it for a small network — with static buffers and, if needed, fixed-point arithmetic. Compare the C output against onnxruntime on the same vectors, then on the target processor, and climb MIL → SIL → PIL → HIL before it controls anything.

What do you check when calling torch.onnx.export?

model.eval() first, so dropout is off and batch norm uses running statistics. Fixed input shapes unless you truly need dynamic axes — embedded code generators want static shapes. An opset your target toolchain supports. Operators the toolchain supports — avoid exotic layers. Then run onnx.checker and look at the graph (e.g. in Netron) to see what was actually exported.

Trick The export ran without errors. Is the ONNX model correct?

Not necessarily. Tracing records one path through the Python code, so data-dependent if statements and loops are frozen to the branch taken by the example input. A model left in training mode exports with dropout and batch statistics. Only a numerical comparison against PyTorch on varied inputs proves equivalence.

How do you verify that each conversion step preserved the model?

Keep a fixed set of golden vectors — real inputs covering the operating range plus edge cases — with PyTorch's outputs. Run them through onnxruntime, the generated C on a PC, and the C on the target, and compare with a stated tolerance (e.g. max absolute error below 1e-5 for float, a few LSBs for fixed-point). Automate it so every re-export is checked.

How do you actually get from ONNX to C?

Options, roughly from simplest to most industrial: hand-write the C for a small MLP or GRU (a few matrix–vector products and activations — fully transparent); open-source generators such as onnx2c; compilers with ahead-of-time C output such as Apache TVM; TensorFlow Lite Micro if you go via TFLite; and in automotive, often MATLAB/Simulink — import the network, then generate C with Embedded Coder — because the rest of the control software already lives there. Name what the team uses and why.

What constraints does code running on an ECU have that a PC does not?

No dynamic memory allocation — all buffers static and sized at compile time. A bounded, predictable worst-case execution time that fits the control task's period (e.g. every 10 ms). Limited RAM and flash. Sometimes no or slow floating point. Coding standards such as MISRA C, integration as a software component in an AUTOSAR architecture, and functional-safety processes (ISO 26262).

How big is a small MLP in memory?

Count it: 20 inputs → 64 → 64 → 1 has 20·64 + 64·64 + 64·1 = 5,440 weights plus 129 biases ≈ 5,600 parameters — about 22 KB in float32 or 5.6 KB in int8, plus a few hundred bytes of activation buffers. Doing this arithmetic out loud shows you design for the target from the start.

What changes if the ECU has no floating-point unit?

Use fixed-point arithmetic: represent values as integers with an implied binary point (Q-format, e.g. Q15), choose scales per layer from the observed ranges, use wider accumulators for sums, and saturate rather than overflow. It's the same idea as int8 quantisation, applied by hand or by the code generator — and it must be re-verified against the float model.

Trick Will the float32 C code give bit-identical results to PyTorch?

Usually not exactly. Different operation order, fused multiply-add, and library implementations of exp or tanh cause differences around 1e-6 to 1e-7. That's fine if you verify within a tolerance — a test expecting bit-exact equality will fail for the wrong reason.

How do you run a recurrent model on an ECU?

Export a single-step function — inputs and previous hidden state in, output and new hidden state out — and call it once per control cycle, keeping the state in a static buffer. Define what happens at start-up and after a sensor fault (reset the state). A TCN instead keeps a ring buffer of the last N inputs.

What are MIL, SIL, PIL and HIL?

Stages of in-the-loop testing. MIL: the model runs with a simulated plant. SIL: the generated C code runs on a PC against the simulator. PIL: the code runs on the target processor, checking numerics and timing. HIL: the real ECU runs against a real-time simulation of the engine and sensors. Each step replaces one simulated piece with the real one.

Which model would you choose knowing it must run on an ECU?

Decide the target first: available memory, cycle time, floating point or not, supported operators. Then prefer the smallest model that meets accuracy — gradient-boosted trees (which compile to nested if-statements), a small MLP, or a GRU — over a large network you'd have to compress later. Simplicity also makes verification and safety arguments easier.

Perception for vehicles

Sensor fusion: camera, radar and LiDAR

The spoken answer — about thirty seconds

Each sensor fails differently: cameras tell you what something is but not how far, radar gives range and velocity through bad weather but is sparse, and LiDAR gives precise 3D shape. Fusion can happen on raw data, on features, or on object lists. Today's default is feature-level fusion in a bird's-eye-view grid. For tracking, a Kalman filter predicts each object forward and corrects with every sensor's measurement, weighted by its noise. And none of it works without precise calibration and time sync.

THREE SENSORS, THREE STRENGTHScameraradarLiDARmeasuresappearancerange, velocity3D shapegood atwhat it isspeed, weatherdistanceweak atdepth, nightsparse, coarsefog, costWHERE TO FUSEearlyraw data / pointsprecise, needs perfect calibrationmid · BEVfeatures in bird's-eye viewtoday's default (BEVFusion)lateobject listsrobust, modular, loses detailTRACKING: KALMAN FILTER LOOPpredictmotion model, P growsassociateHungarian + gatingupdatecorrect, P shrinksper-sensor noise Rweights each update
Fusion exists because every sensor fails differently. Radar sees speed through fog, LiDAR sees shape, cameras see what the thing is. Bird's-eye-view fusion and a Kalman tracker are the two ideas to explain well.

Questions

Camera vs radar vs LiDAR in one breath each?

Camera: rich appearance, cheap, poor direct depth and weak at night or in glare. Radar: measures range and radial velocity directly, works in rain and fog, but sparse and low angular resolution. LiDAR: precise 3D points, degrades in heavy rain or fog, expensive, sparse at long range.

How does automotive FMCW radar measure range and speed?

It transmits frequency-modulated chirps. The frequency difference between sent and received signal gives range; the phase change across successive chirps gives radial velocity (Doppler); differences across the antenna array give angle. FFTs turn these into a range–Doppler–angle cube, then detections.

Trick Are radar point clouds like LiDAR point clouds?

No. They're far sparser and noisier, with multipath ghosts and clutter, but each point carries velocity, which LiDAR doesn't. 4D imaging radar adds elevation and density, narrowing the gap.

Early, mid or late fusion?

Early: combine raw data — most information, needs exact calibration and sync. Late: each sensor detects objects, then merge lists — modular and robust to a sensor failing, but loses evidence that was weak in each sensor alone. Mid/feature-level, typically in BEV, is the current default.

What is BEV and why is it popular?

Bird's-eye view: a top-down grid around the car. LiDAR and radar map into it naturally; camera features are 'lifted' into it using predicted depth (Lift-Splat-Shoot) or attention (BEVFormer). A shared BEV space makes fusion, planning and multi-camera reasoning simple.

What has to be right before fusion works?

Calibration: intrinsics for each camera, extrinsics (rotation and translation) between every sensor. Time synchronisation: at 30 m/s, 30 ms of misalignment is almost a metre. Plus ego-motion compensation for LiDAR sweeps.

Trick Does adding a sensor always improve the system?

No. A miscalibrated or unsynchronised sensor injects confident errors, and a fusion network can learn to over-rely on one modality and fail when it drops out. Train with sensor dropout and test degraded modes.

Explain the Kalman filter.

Track a state (position, velocity) and its uncertainty P. Predict with a motion model — uncertainty grows. Update with a measurement — the Kalman gain weights prediction against measurement by their uncertainties, and P shrinks. Fusion falls out naturally: each sensor has its own noise covariance R.

Trick Is the Kalman filter optimal for any system?

Only for linear dynamics with Gaussian noise. For non-linear motion or measurements (radar's polar coordinates, turning cars) you use the extended KF (linearise) or unscented KF (sigma points), or particle filters for multi-modal beliefs.

How do you associate detections with tracks?

Compute a cost between each track's prediction and each detection (distance, IoU, Mahalanobis), discard implausible pairs with a gate, and solve the assignment with the Hungarian algorithm. Unmatched detections start tentative tracks; unmatched tracks age out.

How does a network consume a point cloud?

Points are unordered. PointNet applies a shared MLP per point then a symmetric max-pool, so order doesn't matter. Faster in practice: voxelise or group into vertical pillars (PointPillars) and use 2D/3D convolutions.

How are 3D detectors evaluated?

3D mAP over IoU or centre-distance thresholds; nuScenes adds NDS, combining mAP with errors in translation, scale, orientation, velocity and attributes. Tracking uses AMOTA and ID switches.

Why is camera-only 3D detection hard?

Depth is ambiguous from one image, and depth error grows with distance. Multi-view geometry, temporal stereo and learned depth help; radar or LiDAR resolve it directly — which is the core argument for fusion.

Pre-trained once, adapted everywhere

Vision foundation models, VLMs and VLAs

The spoken answer — about thirty seconds

Vision foundation models are pre-trained on huge data and adapted cheaply. CLIP learns a shared space for images and text with a contrastive loss, which gives zero-shot classification. DINOv2 learns strong visual features with no labels, and SAM produces masks from a click. A vision-language model plugs a vision encoder into an LLM through a small projector. A VLA uses the same recipe but outputs actions instead of text — usually as action chunks, because a large model can't run a fast control loop on its own.

CLIP: CONTRASTIVE IMAGE–TEXT TRAININGimg 1txt 1img 2txt 2img 3txt 3img 4txt 4pull matching pairs together (diagonal),push every other pair apartVLM → VLAimageViT encoderprojectorMLPLLMimage tokens + texttextVLMactionsVLAsame backbone; a VLAdecodes motor commandsinstead of wordsThe three families to nameCLIP / SigLIP — image–text embeddings, zero-shot classificationDINOv2 — self-supervised visual features · SAM — promptable masksLLaVA-style VLMs · RT-2, OpenVLA, π0 — vision-language-action
Shared embeddings, then a language model on top, then actions. CLIP aligns pictures and text; a VLM feeds image tokens into an LLM; a VLA uses the same recipe to output robot or vehicle actions.

Questions

What makes a model a 'vision foundation model'?

Pre-trained on huge, broad data, usually with self-supervision or weak supervision from captions, and then adapted to many tasks with little labelled data. Examples: CLIP and SigLIP (image–text), DINOv2 (self-supervised features), SAM (segmentation).

How is CLIP trained?

An image encoder and a text encoder map a batch of image–caption pairs into one space. A symmetric contrastive (InfoNCE) loss raises the similarity of the true pairs — the diagonal — and lowers all others. SigLIP replaces the softmax with a per-pair sigmoid loss, which scales better.

How does zero-shot classification with CLIP work?

Embed text prompts like 'a photo of a {class}' for every class, embed the image, and pick the closest. No training on those classes. Prompt wording and ensembling several templates noticeably change accuracy.

Trick Is CLIP good at counting and spatial relations?

No — notably weak. Contrastive training rewards matching the gist of a caption, so 'three dogs left of a cat' and 'a cat left of three dogs' embed similarly. Many VLMs inherit this weakness from their CLIP-style encoder.

What is the standard VLM architecture?

A pre-trained vision encoder (ViT, often CLIP/SigLIP), a projector (MLP or Q-Former) mapping patch features into the LLM's token space, and an LLM. Training: first align the projector on caption data with both models frozen, then instruction-tune on visual Q&A. LLaVA is the reference design.

Trick Does a VLM see the full-resolution image?

Usually not. Images are resized to the encoder's input size (e.g. 336 or 448 px), so small text and fine defects vanish. Higher-resolution models tile the image into crops, at a large token cost.

What is SAM?

Segment Anything: a heavy image encoder run once per image, plus a light prompt encoder and mask decoder that respond to points, boxes or masks in real time. Trained on over a billion masks. Gives class-agnostic masks — it knows 'an object is here', not what it is.

What is open-vocabulary detection?

Detecting objects named by arbitrary text, not a fixed class list. Grounding DINO and OWL-ViT align region features with text embeddings. Useful for rare classes and for auto-labelling data.

What is a VLA?

Vision-language-action model: a VLM whose output is robot or vehicle actions. RT-2 and OpenVLA discretise actions into tokens the LLM predicts; π0 adds a flow-matching action head for smooth continuous control. Trained on large teleoperation datasets such as Open X-Embodiment.

Trick Can a 7B-parameter VLA run a control loop at 50 Hz?

Not directly. A forward pass takes far too long. Systems predict action chunks — several future steps at once — or use a slow VLM for high-level decisions with a fast low-level controller underneath.

Linear probe, fine-tune, or PEFT on a foundation model?

Linear probe on frozen features: fastest, tests representation quality, fine for small data. Full fine-tuning: best when data is plentiful and the domain differs. LoRA or adapters: most of the gain at a fraction of the cost.

Trick Do foundation models transfer to medical or industrial images?

Partly. Features trained on web photos often miss what matters in X-rays or weld defects. Domain-specific pre-training (e.g. on medical images) or fine-tuning usually wins; always compare against a supervised baseline.

What is object hallucination in VLMs?

Describing objects that aren't in the image, driven by language priors ('a kitchen usually has a fridge'). Measured with benchmarks like POPE; reduced with grounding, better data and preference tuning.

Learning to act from demonstrations

Imitation learning and deeper RL

The spoken answer — about thirty seconds

Behaviour cloning is supervised learning on expert demonstrations — simple, but the policy drifts: one mistake takes it to a state the expert never showed it, and errors compound. DAgger fixes that by having the expert label the states the policy actually visits. When the expert's actions are multimodal, you need a policy that models a distribution, like a diffusion policy. Offline RL learns from logged data without exploring, but has to stop the value function from trusting actions it has never seen. In practice you pre-train by imitation and fine-tune with RL.

BEHAVIOUR CLONING DRIFTSexpertpolicysmall error → unfamiliar state→ bigger error → ...error grows ~T² with horizon TDAgger FIXES ITrun policycollect its statesask expertlabel those statesaggregateadd to datasetretrainon everythingthe policy learns to recover from its own mistakesOffline RLlearn from a fixed log;penalise unseen actions (CQL)Multimodal actionsaverage of 'left' and 'right'= crash → diffusion policySim-to-realdomain randomisation,system ID, fine-tune on real
Copying an expert works until the policy makes its first mistake. It then reaches states the expert never visited, and errors compound. DAgger, recovery data and offline RL are the standard remedies.

Questions

What is behaviour cloning?

Supervised learning on expert demonstrations: input the state, predict the expert's action. Simple, stable, needs no reward function. The default first step for driving and robot manipulation.

Why does behaviour cloning fail on long tasks?

Compounding error from covariate shift. The policy trains on expert states but runs on its own; one small mistake leads to an unfamiliar state, where it makes a bigger mistake. Error grows roughly with the square of the horizon.

Trick Will collecting more expert demonstrations fix that?

Only partly. More perfect demos still never show the policy how to recover from being off course. You need recovery data: DAgger, noise injected into the expert's driving (as in DART), or deliberate perturbations.

How does DAgger work?

Roll out the current policy, have the expert label the states it actually visits, add those to the dataset, retrain, repeat. It trains on the policy's own state distribution, cutting error growth to roughly linear. The cost: an expert available to label on demand.

What goes wrong when the expert behaviour is multimodal?

Mean-squared-error regression averages the modes — passing an obstacle on the left or the right becomes driving straight into it. Use policies that model a distribution: mixtures, discretised actions, diffusion policies, or action chunking with a generative head (ACT).

Inverse RL and GAIL?

Inverse RL infers the reward the expert seems to optimise, then runs RL on it — generalises better than copying actions but is expensive. GAIL trains a discriminator to tell expert from policy behaviour and uses it as the reward, adversarially.

What is offline RL?

Learn a policy from a fixed dataset of logged experience with no further interaction — attractive when exploring is dangerous or expensive, as with real vehicles or patients.

Trick Can you just run DQN or SAC on a logged dataset?

No — it usually fails. The Q-function overestimates the value of actions absent from the data, and the policy chases those errors, with no environment to correct them. Offline methods constrain this: CQL penalises unseen actions, IQL avoids querying them, BCQ stays close to the logged behaviour.

State the Bellman equation.

Q(s, a) = r + γ · max over a′ of Q(s′, a′): the value of an action is the immediate reward plus the discounted value of the best next action. Q-learning moves Q towards this target.

What two tricks made DQN work?

An experience replay buffer to break correlation between consecutive samples, and a target network updated slowly so the regression target doesn't chase itself. Double DQN then reduced overestimation.

What is SAC and when do you use it?

Soft actor-critic: off-policy actor-critic for continuous actions that maximises reward plus policy entropy, so it keeps exploring and is robust. A standard choice for robotic control in simulation.

What is reward hacking?

The agent maximises the reward you wrote, not what you meant — circling to collect points, exploiting a simulator bug. Shaped or learned rewards are especially prone. Mitigate with careful reward design, constraints and watching actual behaviour, not just the curve.

How do you get a policy from simulation to the real world?

Domain randomisation of physics, sensor noise and visuals so reality looks like one more variation; system identification to match simulator parameters; then fine-tuning on a small amount of real data.

Model-free vs model-based RL?

Model-free learns a policy or value directly from experience — simple, sample-hungry. Model-based learns the dynamics and plans with them (MPC, Dreamer) — far more sample-efficient, but model errors compound over long plans.

When imitation, when RL?

Imitation when good demonstrations exist and a reward is hard to write — usually the case for driving. RL when a reward is clear and you can simulate cheaply. In practice: pre-train by imitation, then fine-tune with RL or offline RL.