Introduction to Robot Learning · Lecture 4 of 25 · CMU 16-831

ML / DL Refresher, Part 2

A single straight line cannot tell two simple patterns apart. The fix — stack layers, bend them with a nonlinearity, and learn by tracing blame backwards — is the engine under every CNN, transformer, and diffusion model your robot will ever run.

Prerequisites: Part 1 (a linear model + a loss) and a little matrix arithmetic. No calculus assumed — we build the chain rule by hand.
10
Chapters
5
Simulations
3
Code Labs

Chapter 0: A Line Can't Learn XOR

Part 1 left you with a powerful tool: a linear model that draws a straight boundary and slides it around to minimize a loss. For a huge number of problems that is enough. For an embarrassingly simple one, it is hopeless — and that failure is the entire reason deep learning exists.

Here is the simple problem. XOR ("exclusive or"): four points on a square. The two diagonal corners (0,0) and (1,1) are class A; the other two corners (0,1) and (1,0) are class B. Try to separate A from B with one straight line. You can't. No line, at any angle, puts both A's on one side and both B's on the other. The pattern is not linearly separable.

The wall a linear model hits. A linear model computes w·x + b and thresholds it — that is literally a line (or a flat plane in higher dimensions). Stack two linear models and you get… another line: W₂(W₁x) = (W₂W₁)x. Depth alone buys you nothing. To bend the boundary you need a nonlinearity between the layers.

The fix is two ideas working together, and you should hold them as a pair for the whole lesson:

With one hidden layer of two units and a nonlinearity in between, XOR becomes trivially separable. The network reshapes the input space until a line can cut it. Watch it happen.

XOR — one line fails, a hidden layer succeeds

The four XOR points are colored by class. Drag the line angle slider with Linear selected: no angle separates the colors. Switch to Hidden layer + nonlinearity and the learned boundary curves to wrap the diagonal — the same data, now separable.

Line angle 45°
Linear: try every angle — none works.
Why this is the right place to start. Today's lecture is the deep-learning half of the refresher. Every model we'll meet — the MLP, the CNN, the RNN/LSTM, the transformer, even a diffusion model — is the same recipe: stack differentiable layers, bend them with nonlinearities, define a loss, and push gradients backwards to fit the weights. Master the MLP and backprop in the next four chapters and everything after is a variation on the theme.

Why does stacking two linear layers with nothing in between fail to separate XOR?

Chapter 1: The MLP — Shapes Flowing Through Layers

The multilayer perceptron (MLP), also called a fully connected network, is the plainest deep network: a stack of layers where each layer is a matrix multiply, a bias add, and an activation. Nothing about it is mysterious once you track the shapes.

One layer takes an input vector and produces an output vector. If the input has d_in numbers and the output has d_out numbers, the layer holds a weight matrix W of shape (d_out, d_in) and a bias b of shape (d_out,). The layer computes:

z = W x + b   →   a = φ(z)

Here z is the pre-activation (the raw linear output) and a is the activation after the nonlinearity φ bends it. The next layer eats a as its input. That is the whole architecture — a relay race of vectors.

Trace the shapes through a tiny net

Say we feed a single image flattened to 784 numbers (a 28×28 digit) through a network with one hidden layer of 128 units and a 10-way output (the ten digits):

StepOperationShape inShape out
inputflatten image28×28(784,)
layer 1W₁ x + b₁, then ReLU(784,)(128,)
layer 2W₂ a₁ + b₂, then softmax(128,)(10,)

So W₁ is (128, 784) and W₂ is (10, 128). The output is a 10-vector of class scores; softmax turns those scores into probabilities that sum to 1. With a whole batch of N images at once, you stack the inputs into a (N, 784) matrix and every layer just processes all rows in one matrix multiply — same math, one extra dimension.

The mental model. An MLP is "matrix multiply → bend → matrix multiply → bend → …". Each hidden layer is a new coordinate system for the data — by the last layer, the network has reshaped the input so a simple linear readout can solve the task. That is exactly the XOR trick from Chapter 0, scaled up.

Now build the forward pass yourself, the same two-layer net but on tiny numbers you can verify by hand.

In a fully connected layer with input dimension 784 and output dimension 128, what is the shape of the weight matrix W?

Chapter 2: Activations — the Bend, and the Vanishing Gradient

The activation function is the small nonlinear function we put after each layer's linear step. It is what lets the network bend. But the choice of activation has a giant consequence for training — one that took the field two decades to fully appreciate.

Three classics:

Why does this matter so much? Because of training. When we push gradients backwards (Chapter 3), each layer multiplies the incoming gradient by the slope of its activation. Look at the slopes:

ActivationOutput rangeMax slopeSlope far from 0
Sigmoid(0, 1)0.25→ 0 (saturates)
Tanh(−1, 1)1.0→ 0 (saturates)
ReLU[0, ∞)1.01.0 (if active), 0 (if dead)
The vanishing gradient. Sigmoid's slope never exceeds 0.25, and it collapses toward zero whenever the input is large in magnitude (the curve goes flat). Stack ten sigmoid layers and the backward gradient gets multiplied by ten numbers each ≤ 0.25 — that is at most 0.25100.000001. The gradient reaching the early layers is essentially zero, so those layers never learn. ReLU's slope is exactly 1 wherever the unit is active, so it passes the gradient through undiminished. This single fact is why deep networks trained well only after ReLU became standard.

ReLU's one flaw: a unit whose input is always negative outputs 0 forever and its slope is 0, so it stops learning — a dead neuron. Variants like Leaky ReLU (a tiny slope below zero) patch this.

Activations and their gradients — watch sigmoid saturate

Pick an activation. The teal curve is the function; the warm curve is its slope (the gradient multiplier). Notice how sigmoid's slope flattens to nearly zero away from the center — that is the gradient vanishing — while ReLU's slope is a flat 1 on the right.

Showing sigmoid.
Why are deep networks of sigmoid hidden units hard to train?

Chapter 3: Backpropagation — Tracing Blame Backwards

We can run a forward pass and get a loss. Now the hard question: how should each weight change to make the loss smaller? The answer is the gradient — how much the loss moves when you nudge each weight. Backpropagation is the efficient algorithm for computing every one of those gradients in a single backward sweep, using the chain rule.

The chain rule says: if the loss depends on a, and a depends on z, and z depends on w, then the loss's sensitivity to w is the product of the local sensitivities along the path:

∂L/∂w = (∂L/∂a) · (∂a/∂z) · (∂z/∂w)

Think of it as tracing blame backwards through the computation: the loss blames its input, which blames its input, all the way back to the weights. Each step multiplies in one local slope. A computational graph is just the picture of this — nodes for operations, edges for "depends on" — and backprop walks that graph in reverse.

A complete backprop by hand

Let us do a real one, all numbers, no hand-waving. A net with one input, one hidden unit (ReLU), and one output, trained to match a target with squared-error loss. The numbers:

x = 2,  w₁ = 0.5,  w₂ = −1,  target y = 1

Forward pass — push the input through:

QuantityFormulaValue
z₁ (hidden pre-act)w₁ · x0.5 · 2 = 1.0
a (hidden, ReLU)max(0, z₁)max(0, 1.0) = 1.0
ŷ (output)w₂ · a−1 · 1.0 = −1.0
L (loss)½(ŷ − y)²½(−1 − 1)² = 2.0

Backward pass — now trace blame from L back to each weight. Start at the loss and multiply in local slopes:

GradientChainValue
∂L/∂ŷŷ − y−1 − 1 = −2.0
∂L/∂w₂(∂L/∂ŷ) · a−2.0 · 1.0 = −2.0
∂L/∂a(∂L/∂ŷ) · w₂−2.0 · (−1) = 2.0
∂L/∂z₁(∂L/∂a) · ReLU′(z₁)2.0 · 1 = 2.0
∂L/∂w₁(∂L/∂z₁) · x2.0 · 2 = 4.0

Note ReLU′(z₁) = 1 here because z₁ = 1.0 > 0 (the unit is active). Had z₁ been negative, that slope would be 0 and the gradient would stop dead at that unit — the dead-neuron problem made concrete. With these gradients, a step of gradient descent nudges w₁ down by 4·(learning rate) and w₂ down by −2·(learning rate) (i.e. it grows), shrinking the loss.

The one idea. Backprop is not a new kind of calculus. It is the chain rule applied with bookkeeping: compute every local slope on the forward pass, then sweep backwards multiplying them together, reusing shared sub-results so the whole thing costs about the same as one forward pass. That efficiency is why training billion-parameter networks is even possible.

The computational graph — forward values, backward gradients

The same tiny net. Press Forward to flow values left→right (teal). Press Backward to flow gradients right→left (warm). Drag w₁ negative and re-run: the ReLU dies, its slope becomes 0, and the gradient to w₁ is killed at the hidden node.

w₁ 0.5
Ready.

Trust nothing on faith. The cleanest way to check a hand-derived gradient is to compare it against a finite difference: nudge the weight by a tiny h, see how much the loss changes, divide. Let's do exactly that — you compute one gradient by the chain rule and the lab confirms it matches the numerical slope.

In the worked example, the loss was 2.0 and ∂L/∂w₁ came out to 4.0. What does that 4.0 tell you?

Chapter 4: Optimizers — How the Weights Actually Move

Backprop hands us a gradient. An optimizer decides what to do with it — how big a step to take and in what direction. The recipe behind GPT and every robot policy uses one word for this: SGD, stochastic gradient descent. But the modern default is Adam, and understanding the ladder from one to the other is worth ten minutes.

Plain SGD

Stochastic gradient descent takes a step downhill, scaled by the learning rate η (eta):

w ← w − η · ∂L/∂w

"Stochastic" means we compute the gradient on a small random mini-batch rather than the whole dataset — cheaper, and the noise actually helps escape bad spots. The catch: in a long narrow valley, plain SGD zig-zags across the walls and crawls down the floor.

Momentum

Momentum fixes the zig-zag by accumulating a running average of past gradients — a velocity. Like a ball rolling downhill, it builds speed in the consistent direction and damps the side-to-side wobble:

v ← β v + ∂L/∂w   →   w ← w − η v

The β (around 0.9) controls how much memory the velocity has. Down the valley floor the gradients agree, so velocity accumulates and you accelerate; across the walls they cancel, so the wobble dies.

Adam

Adam adds a second trick: per-parameter learning rates. It tracks not just the average gradient (like momentum) but also the average squared gradient, and divides the step by the square root of that. Parameters with consistently large gradients get smaller steps; quiet ones get larger steps. The effect is that Adam mostly "just works" across very different scales without hand-tuning — which is why it is the lazy-but-correct default for deep nets.

The ladder. SGD = step downhill. + Momentum = remember your direction (escape zig-zag). + Per-parameter scaling = Adam (auto-tune the step for each weight). Each rung removes a specific failure of the rung below it.

Optimizer race on a stretched bowl — SGD vs Momentum vs Adam

Three optimizers descend the same elongated loss valley from the same start. SGD zig-zags; Momentum rolls through; Adam rescales each axis. Push the learning rate up until plain SGD diverges (flies off the bowl) — Adam usually survives.

Learning rate η 0.12
Ready.

Numbers, not pictures, settle arguments. The lab below runs one optimizer step on a stretched quadratic and lets you compare a momentum update against a plain SGD update from the same point. You write the momentum velocity rule.

What does Adam add on top of momentum?

Chapter 5: CNNs — Baking In the Right Bias for Images

An MLP can classify an image: flatten it to a vector and go. But for a 200×200 color image that flattened vector has 120,000 numbers, and the first layer alone would need billions of weights — and it would have to learn from scratch that a cat in the top-left looks the same as a cat in the bottom-right. The convolutional neural network (CNN) fixes both problems by baking in two inductive biases — assumptions about the data built into the architecture.

Two knobs control the slide: stride (how far the kernel jumps each step) and padding (zeros added around the border so the output stays a convenient size). Larger stride → smaller output. After convolutions, a pooling layer downsamples (e.g. take the max of each 2×2 block) to shrink the map and add a little position-invariance. The classic early example, LeNet (1998), stacked exactly this: conv → pool → conv → pool → fully connected.

Equivariant vs. invariant. A convolution is equivariant to translation: move the input, the feature map moves with it (f(shift(x)) = shift(f(x))). Pooling and the final readout make the classification invariant: move the cat, still "cat" (f(shift(x)) = f(x)). You can get these properties two ways — design them into the architecture (the CNN way) or teach them with data augmentation (show the model shifted/rotated copies).

A convolution sliding over an image

A 3×3 edge-detector kernel slides across a small image. The highlighted patch on the left is multiplied element-wise by the kernel and summed into one output pixel on the right (the feature map). Step through it, and change the stride to see the output shrink.

Stride 1
Press Step to slide the kernel.
What is the key advantage of weight sharing in a convolution?

Chapter 6: Sequences — RNN, LSTM, and the Transformer

Images have spatial structure; sequences (text, sensor streams, robot trajectories) have temporal structure. The job is to summarize "everything relevant so far" so you can predict what comes next.

RNNs and the long-memory problem

A recurrent neural network (RNN) processes a sequence one step at a time, carrying a hidden state — a running summary of the past — and updating it at each new input. Elegant, but it has the same disease we met in Chapter 2: to learn a dependency between step 1 and step 100, the gradient must propagate back through 100 multiplications, so it vanishes (or, with large weights, explodes). RNNs forget the distant past.

The LSTM (long short-term memory) patches this by adding a separate cell state — a memory highway — with learnable gates that decide what to write, keep, and read. Information can flow far down the highway without being repeatedly squashed, so gradients survive longer.

The transformer: drop recurrence, attend to everything

The transformer throws out recurrence entirely. Instead of passing a summary step by step, it lets every position look directly at every other position through attention. The mechanism, self-attention: from each token's embedding, three vectors are made by separate linear layers — a query (Q), a key (K), and a value (V). The dot product of one token's query with another's key is a score: "how much should I attend to you?" Those scores are scaled, passed through softmax so they sum to 1, and used to take a weighted average of the values.

Because attention has no built-in notion of order, transformers add a positional embedding to each token. Each encoder layer is then: multi-head self-attention → a small fully connected network, both wrapped with residual connections (add the input back to the output) and layer normalization. The decoder is similar but also runs cross-attention to the encoder's output and generates one token at a time — it is autoregressive.

Why the transformer won. It is almost embarrassingly simple — matrix multiplies, ReLU, softmax, with very little inductive bias — and that simplicity makes it highly scalable and parallel. CNNs are stuck with a local window; RNN/LSTMs train slowly and still struggle with long range; a plain MLP has too many parameters and can't take variable-length input. Attention has none of those limits, which is why it now powers GPT, PaLM, LLaMA — and increasingly robot policies.

Self-attention — which words does "it" look at?

A short sentence. Click a token to make it the query; the bars show its softmax attention weights over all tokens (the keys). Notice the weights always sum to 1 — attention is a weighted average, and it can reach any position directly, near or far.

Click a token above.

For the full story of each piece, this site has dedicated lessons: the Transformer and the Vision Transformer (attention applied to image patches — the bridge between this chapter and Chapter 5).

In self-attention, what do the softmax attention weights for a single query token always satisfy?

Chapter 7: Unsupervised & Generative Models

So far every model had labels. Unsupervised learning finds structure in unlabeled data. The lecture lists three flavors: clustering (group similar points — e.g. K-means, fit by the EM algorithm: assign points to the nearest center, then move each center to its points' mean, repeat), dimension reduction (compress to fewer numbers while keeping the variance — PCA, or nonlinear t-SNE for visualization), and generative models.

A generative model learns the distribution of the data so it can sample new examples. The lecture frames it with Feynman's motto, inverted: "What I understand, I can create." This matters enormously for robots — imitation learning is literally a conditional generative model of expert actions, and generative models can manufacture training simulations.

Three dominant paradigms, each trading off the same "impossible triangle" of coverage, speed, and quality:

ModelCore ideaKnown weakness
VAEEncoder maps data to a latent distribution; decoder reconstructs. Trained to maximize a lower bound (the ELBO) on the data likelihood, with a KL term regularizing the latent toward a Gaussian. Uses the reparameterization trick to backprop through sampling.Samples tend to be blurry.
GANA two-player game: a generator makes fakes, a discriminator tries to spot them. They co-improve.Unstable training — mode collapse, vanishing gradients, hard to reach equilibrium.
DiffusionGradually corrupt data into noise (forward), then learn to reverse it step by step. Unlike VAE/GAN the latent has the same dimension as the data.Slow to sample (many denoising steps).
The reparameterization trick, in one breath. You cannot backprop through "draw a random sample." So instead of sampling the latent directly, a VAE writes the sample as mean + std × ε where ε is fixed external noise. Now the randomness sits outside the network, the mean and std are smooth functions of the weights, and gradients flow right through. The same idea reappears in the forward diffusion process.

VAE latent space — one Gaussian dial, smoothly morphing samples

A toy 1-D latent. Drag the latent z slider; the decoder maps it to a generated shape. Because the VAE regularizes the latent toward a smooth Gaussian, nearby z values produce nearby outputs — that smoothness is what lets you interpolate and sample novel data.

Latent z 0.00
z = 0: the mean shape.

The site expands each of these: VAE / VQ-VAE, GANs, Diffusion, and Flow Matching.

Why does a VAE need the reparameterization trick?

Chapter 8: Uncertainty — Knowing When You Don't Know

A robot that confidently grasps thin air is worse than one that says "I'm not sure, let me look again." So the lecture closes with a topic that is life-or-death for embodied systems: uncertainty quantification (UQ) — getting a network to report how confident it is, not just what it predicts.

Two flavors of uncertainty, and the difference matters:

The lecture's toolbox for estimating it:

MethodIdea
Bayesian neural nets / Gaussian processesPut a distribution over the weights/functions; predict a distribution, not a point.
Dropout at test timeRandomly drop units and predict many times; the spread of predictions is the uncertainty.
EnsemblesTrain several networks; where they disagree, you are uncertain.
Conformal predictionFor any black-box predictor, calibrate a score so the output is a set guaranteed to contain the truth with probability 1−α.
And the flip side: DNNs are fragile. The lecture ends on a warning — a tiny, carefully chosen perturbation, invisible to you, can flip a classifier's answer. That is why DNN verification (proving a network behaves on a whole region of inputs, via reachability or optimization) is an active field. For a robot, "usually right" is not the same as "safe."

Ensemble uncertainty — confident where they agree, uncertain where they don't

Five networks (faint lines) fit the same training points (warm dots). Where data is dense they agree — low epistemic uncertainty (narrow teal band). Drag the data gap slider to remove a region: out there the models fan out, and the band balloons — the ensemble knows it doesn't know.

Data gap width 0.30
A gap in the data makes the models disagree there.
An ensemble of five networks agrees tightly on familiar inputs but fans out wildly on a never-seen input. The wide spread signals which kind of uncertainty?

Chapter 9: Connections & Cheat Sheet

You now own the deep-learning toolkit the rest of 16-831 assumes. Notice the single thread running through all of it: every model is differentiable layers + a nonlinearity + a loss, fit by backprop and an optimizer. CNNs, transformers, VAEs, diffusion — each just changes which layers and which loss. The machinery never changes.

MLP
matmul → nonlinearity, stacked. The atom of every other model.
↓ add the locality + weight-sharing bias
CNN
Convolutions for images; translation equivariance for free.
↓ need temporal structure instead
RNN / LSTM
Hidden state carries the past; LSTM gates fight vanishing gradients.
↓ drop recurrence, attend to everything
Transformer
Self-attention; scalable, parallel, almost no inductive bias.
↓ learn the data distribution, not a label
Generative (VAE/GAN/Diffusion)
Sample new data; the engine under imitation learning.
↓ report confidence, prove safety
Uncertainty & Verification
Ensembles/dropout/conformal; know when you don't know.
Cheat sheet — what you now own.
  • Why depth + nonlinearity = stacked linear maps collapse to one line; a nonlinearity between layers lets the boundary bend (XOR).
  • MLP = matmul → bias → activation, repeated; track shapes: W is (d_out, d_in).
  • Activations = sigmoid/tanh saturate (slope→0, vanishing gradient); ReLU = max(0,z), slope 1 when active, can "die".
  • Backprop = the chain rule + bookkeeping; sweep backwards multiplying local slopes; costs ~one forward pass.
  • Optimizers = SGD (step downhill) → + momentum (escape zig-zag) → Adam (per-parameter step). Verify gradients with finite differences.
  • CNN = locality + weight sharing → translation equivariance; stride, padding, pooling.
  • RNN/LSTM = sequential hidden state; LSTM cell-state highway beats vanishing gradients.
  • Transformer = Q·K scores → softmax → weighted V; positional embeddings; residual + layernorm; scalable.
  • Generative = VAE (ELBO, reparameterization), GAN (two-player game), Diffusion (corrupt then reverse).
  • Uncertainty = aleatoric (irreducible) vs epistemic (ignorance, shrinks with data); ensembles/dropout/conformal; DNNs are fragile.

Where to go next on this site

This lesson is Lecture 4 of the 16-831 series. Continue with Lecture 5 — MDPs & Imitation Learning, where the discounted return and policy from Lecture 1 meet the deep networks you just built. To review the supervised-learning half, see Lecture 3 — ML / DL Refresher, Part 1. The earlier lectures: Lecture 1 — What Is Robot Learning? and Lecture 2 — Robot Learning Overview.

Companion Gleams that go deeper on each architecture in this lecture:

The test of this lesson. Open the original Lecture 4 slides. You should be able to explain, from memory: why depth needs a nonlinearity, the shapes through an MLP, a full backprop by hand, the SGD→momentum→Adam ladder, what makes a CNN translation-equivariant, why the transformer beat RNNs, the three generative paradigms, and why a robot needs to quantify its own uncertainty. If you can, you are ready for the imitation-learning topic group.

"What I understand, I can create." — the generative-modeling inversion of Feynman