RR Skillverse · Free Learning Handbook
RR Skillverse Module 2 of 12 Theory Handbook Finance + AI + Security

Module 2 — Deep Neural Networks

Same theory-first structure as Module 1: for every technique below, what it is, why it exists — the specific limitation of what came before it — what else you could use instead, and a real financial example. Module 1 built a logistic-regression baseline; every concept here exists because that baseline has a specific, nameable limit, and this module builds the tool that addresses it.

Why neural networks, and why now

Module 1's logistic regression is one linear decision boundary. It cannot represent an interaction like "risk is high when debt-to-income is high and credit history is short, but only above a combined threshold" without someone manually engineering that exact interaction term first. That specific gap — not fashion, not hype — is why Module 2 exists.

The panel, not the interviewer

Logistic regression is one interviewer with a fixed checklist. A neural network is a panel of specialists (hidden neurons), each attuned to a different combination of signals, with a final layer combining their opinions.

Pixels aren't ratios

A cheque image is not "16 financial ratios" — meaning lives in local spatial patterns. This is the specific reason Module 2 also introduces CNNs, not just deeper tabular networks.

A second kind of attack

Module 1 showed training data can be poisoned. Module 2 shows a cleanly trained model can still be fooled at prediction time — a different attack surface entirely.

CONCEPT 1

The Perceptron

The smallest possible neural unit — and the historical dead end that explains why depth matters.

Overview
🧮 Math & Algorithm
What it is

A perceptron computes a weighted sum of its inputs plus a bias, then applies a threshold: fire (1) if the sum crosses zero, stay silent (0) otherwise. Every neuron in every network in this entire course — up to and including transformers in Module 4 — is a descendant of this one idea.

Why it exists — the history
1958
Frank Rosenblatt, at the Cornell Aeronautical Laboratory, built the perceptron as a physical machine (the "Mark I Perceptron") intended to learn visual pattern recognition — and it came with real learning rule: adjust weights toward the correct answer after every mistake.
1969
Marvin Minsky and Seymour Papert published Perceptrons, mathematically proving a single perceptron cannot learn XOR — or any pattern that isn't linearly separable. This result is widely credited with triggering the first "AI winter": funding and interest in neural networks collapsed for over a decade, because the community initially over-generalised the result to mean neural networks in general were a dead end — not just single-layer ones.
1986
The backpropagation algorithm (Lesson 4) showed how to train networks with multiple stacked layers, which sidesteps the XOR limitation entirely — the field's real answer to Minsky and Papert's critique, decades later.

✓ What it teaches

  • The exact atomic computation (weighted sum + threshold) every later layer reuses
  • Why depth, not just width, was historically necessary

✗ What it cannot do alone

  • Represent any pattern that isn't linearly separable — including XOR, and by extension most interesting financial risk interactions
REAL-WORLD FINANCIAL EXAMPLE
A single perceptron behaves exactly like Module 1's logistic regression at its core — one straight decision boundary. The XOR failure is a toy example, but it stands in for real cases like "flag as risky only when DTI is high and credit history is short, not when only one is true" — a pattern one straight line cannot separate.
⬇ Run this lesson in the notebook
z = w·x + b; ŷ = 1 if z≥0 else 0
Update: w ← w + η(y−ŷ)x
z = w·x + b — same linear combination as logistic regression, but thresholded hard at 0 instead of passed through a sigmoid.
Perceptron update rule: only fires when the prediction is wrong (y−ŷ ≠ 0); nudges weights toward the input that was misclassified, scaled by learning rate η.
Provably converges only if the data is linearly separable (Perceptron Convergence Theorem, 1962) — XOR is not, which is exactly why it loops forever without settling, the historical trigger for multi-layer networks.
CONCEPT 2

ANN Architecture (Feedforward Networks)

Stacking neurons to fix what one perceptron structurally cannot do.

Overview
🧮 Math & Algorithm
What it is

An Artificial Neural Network (ANN) stacks layers of neurons: an input layer, one or more hidden layers, and an output layer. Each layer's output feeds the next layer's input — literally the perceptron equation, repeated and composed.

Why it exists — the history
1986
Rumelhart, Hinton and Williams published the paper that popularised backpropagation (building on earlier, less-noticed work by others through the 1960s–70s), finally giving the field a practical way to train networks with hidden layers. This is the direct technical answer to the 1969 XOR critique — depth solves what a single perceptron cannot.
1989
The Universal Approximation Theorem (Cybenko, and later Hornik) proved that even a single hidden layer, given enough neurons, can approximate essentially any continuous function — a mathematical answer to "why does adding layers/width actually help?"
Alternatives — and why an ANN here
OptionTrade-off
Logistic regression (Module 1)Fast, interpretable, but one linear boundary only
Tree-based models (Random Forest, XGBoost)Capture non-linear interactions well and often win on small-to-medium tabular data with far less tuning than a neural net
ANNCan represent arbitrary non-linear interactions given enough capacity and data — the trade-off is needing more data, more tuning, and losing easy interpretability

✓ Use it when

  • You suspect genuine feature interactions a linear model can't capture
  • You have enough data to support the extra capacity without overfitting

✗ Don't reach for it when

  • The dataset is small and the relationship is plausibly linear — Module 2's own notebook shows the ANN losing to logistic regression on RR Finance's real 800-row dataset. That is the honest lesson, not a bug: check the simple model first.
REAL-WORLD FINANCIAL EXAMPLE
A large bank with millions of loan records and genuinely complex, interacting risk factors may see a real ANN advantage. A small credit union with a few hundred well-understood cases very often does not — capacity without enough data to fill it just overfits.
⬇ Run this lesson in the notebook
Layer: a⁽ˡ⁾ = f(W⁽ˡ⁾a⁽ˡ⁻¹⁾ + b⁽ˡ⁾)
Each layer is a linear step (W·a + b) followed by a non-linear activation f — stack enough of these and the network can approximate arbitrarily complex decision boundaries (Universal Approximation Theorem), which a single perceptron cannot.
Without the non-linear f between layers, stacking linear layers would collapse mathematically into one single linear layer — depth would buy nothing. The non-linearity is what makes depth meaningful.
Loss for RR Finance's binary task is the same log-loss / binary cross-entropy as Module 1's logistic regression — the ANN is a more flexible function producing the probability that log-loss then scores.
CONCEPT 3

Activation Functions

Without them, depth is mathematically pointless.

Overview
🧮 Math & Algorithm
What it is

An activation function is a non-linear transformation applied after each layer's weighted sum. ReLU (rectified linear unit) is the modern default for hidden layers; Sigmoid and Softmax are used on output layers for binary and multi-class probabilities respectively.

Why it exists — the critical fact
The mathematical reason, not a historical one
Stacking any number of purely linear layers collapses mathematically into a single linear layer — matrix multiplication composed with matrix multiplication is still just a matrix multiplication. Depth buys you nothing at all without a non-linearity between layers. This is why activation functions aren't an optional add-on; they're the entire reason stacking layers works.
2010s
Early networks mostly used Sigmoid or Tanh for hidden layers, but both suffer from vanishing gradients in deep networks — their derivative is near zero for large inputs, so gradient signal shrinks toward nothing as it propagates backward through many layers. ReLU (popularised heavily after Nair & Hinton, 2010, and its central role in AlexNet, 2012) doesn't saturate for positive inputs, which was a major practical unlock for training genuinely deep networks.

✓ Where each belongs

  • ReLU: hidden layers, by default
  • Sigmoid: output layer, binary classification (e.g. default probability)
  • Softmax: output layer, multi-class classification (e.g. 10 cheque digits)

✗ Common mistakes

  • Using Sigmoid in deep hidden layers — invites vanishing gradients
  • Forgetting Softmax must operate on a vector of scores, not a single number
REAL-WORLD FINANCIAL EXAMPLE
The output activation determines what the network's number even means: Sigmoid on RR Finance's default classifier gives a genuine probability of default; Softmax on the cheque-digit reader gives a probability distribution across all 10 possible digits, which must sum to exactly 1.
⬇ Run this lesson in the notebook
Sigmoid: σ(z)=1/(1+e⁻ᶻ)  ReLU: max(0,z)  Softmax: eᶻⁱ/Σeᶻʲ
Sigmoid squashes to (0,1) but saturates (near-zero gradient) for large |z| — this is what causes vanishing gradients in deep sigmoid networks.
ReLU = max(0,z) has gradient exactly 1 for z>0 and 0 for z≤0 — cheap to compute, doesn't saturate on the positive side, which is why it became the default for hidden layers.
Softmax turns a vector of raw scores into a probability distribution that sums to 1 — eᶻⁱ amplifies the largest score relative to the others, dividing by the sum normalises it.
CONCEPT 4

Backpropagation

How a network figures out which direction to move millions of weights from one number.

Overview
🧮 Math & Algorithm
What it is

Backpropagation is the chain-rule-based algorithm that computes how much each weight in the network contributed to the final error, working backward from the output layer to the input layer, so gradient descent (next lesson) knows which direction to nudge every weight.

Why it exists — the history
1970 → 1986
The mathematical technique (reverse-mode automatic differentiation) existed earlier — Seppo Linnainmaa's 1970 thesis is often cited as the first clear general formulation — but it took Rumelhart, Hinton and Williams' 1986 paper to demonstrate its power specifically for training multi-layer neural networks and popularise it across the field. Before this, there was no practical, general way to train a network with hidden layers at all — which is a large part of why the field stalled through the 1970s after the perceptron's XOR limitation was exposed.
Alternatives — and why backprop won
OptionTrade-off
Numerical differentiation (perturb each weight, remeasure loss)Conceptually simple, but requires a full forward pass per weight — computationally impossible at the scale of millions of parameters
Backpropagation (reverse-mode autodiff)Computes gradients for every weight in roughly the cost of one extra forward pass, regardless of how many parameters there are — the only reason training large networks is computationally feasible at all
The gradient check, made concrete
The notebook derives backprop by hand on a tiny network, then verifies the result against numerical differentiation — the same debugging technique real deep-learning engineers use when a training run behaves unexpectedly. Trusting a mechanism you've verified once, by hand, is different from trusting a black box you've never opened.
REAL-WORLD FINANCIAL EXAMPLE
Every .backward() call in every model trained across this entire 12-module course — the cheque-digit CNN here, the fine-tuned LLM in Module 4 — runs on exactly this mechanism. Understanding it once means every later "training is unstable" or "loss exploded" problem has a mechanism you can actually reason about, not just a button you press and hope.
⬇ Run this lesson in the notebook
∂L/∂w⁽ˡ⁾ = ∂L/∂a⁽ᴸ⁾ · ∂a⁽ᴸ⁾/∂a⁽ᴸ⁻¹⁾ ··· ∂a⁽ˡ⁾/∂w⁽ˡ⁾
This is just the chain rule from calculus, applied layer by layer, back-to-front: to know how much a weight deep inside the network affects the final loss, multiply together how much each layer's output affects the next layer's output, all the way to the loss.
Computed once forward (get the prediction) and once backward (get every gradient) — vastly cheaper than perturbing each weight individually and re-running the forward pass (numerical gradient checking), which is why backprop made deep networks practical.
A numerical gradient check (∂L/∂w ≈ [L(w+ε)−L(w−ε)]/2ε) is the way you verify backprop's analytical gradient is actually correct — small ε, compare the two, they should nearly match.
CONCEPT 5

Gradient Descent & Optimizers

Backprop tells you the direction. Optimizers decide how far, and whether to remember the last step.

Overview
🧮 Math & Algorithm
What it is

Given a gradient, an optimizer decides the actual weight update. SGD takes a fixed-size step in the gradient's direction; Momentum adds memory of previous steps to smooth noisy updates; RMSprop and Adam adapt the step size per parameter based on recent gradient behaviour.

Why it exists — the history
1951
Robbins and Monro's stochastic approximation method is the mathematical ancestor of SGD — using noisy, sampled gradients instead of the full dataset at every step, which is what makes training on huge datasets tractable at all.
1999 → 2012
Momentum (Polyak, 1964; popularised for deep learning by Sutskever et al., 2013) smooths the noisy path SGD takes. RMSprop (introduced informally by Geoffrey Hinton in a 2012 lecture, never formally published as a standalone paper) adapts the learning rate per parameter using a running average of recent squared gradients.
2014
Kingma and Ba published Adam ("Adaptive Moment Estimation"), combining Momentum's smoothing with RMSprop's per-parameter adaptation — it became, and largely remains, the default first choice across the field.
Alternatives — how to choose
OptimizerWhen it's the right call
SGD (plain)Simple, sometimes generalises better with careful tuning — common in some published vision benchmarks
SGD + MomentumA strong, well-understood default when you have time to tune the learning rate
RMSpropGood on noisy or non-stationary problems (originally motivated by RNN training)
AdamThe reasonable first choice with minimal tuning — used throughout this course's default training loops
Free lunches don't exist here
"Just increase the learning rate to train faster" is not free — push it too high with plain SGD and training visibly oscillates or diverges. The notebook demonstrates this directly by comparing all four optimizers on identical starting weights.
REAL-WORLD FINANCIAL EXAMPLE
A poorly chosen optimizer or learning rate on a production model-retraining job doesn't just train slower — it can converge to a measurably worse model or fail to converge at all, wasting real compute budget on a nightly or weekly retraining pipeline.
⬇ Run this lesson in the notebook
SGD: w ← w − η∇L
Momentum: v←βv+∇L; w←w−ηv
Adam: combines momentum + per-parameter adaptive step size
η (learning rate) — step size in the direction that reduces loss fastest (−∇L, the negative gradient). Too large overshoots; too small crawls.
Momentum keeps a running average (v) of past gradients, so the optimiser keeps moving in a consistent direction rather than zig-zagging across a narrow valley in the loss surface.
Adam additionally tracks a per-parameter estimate of gradient variance, shrinking the step size for parameters whose gradients are noisy/large and enlarging it for stable/small ones — usually the fastest, most robust default of the three.
CONCEPT 6

Batch Normalisation & Dropout

Two different problems, both fixed by deliberately adding a bit of controlled disruption.

Overview
🧮 Math & Algorithm
What it is

BatchNorm normalises each layer's activations to zero mean/unit variance per mini-batch (then lets the network re-learn an optimal scale), stabilising training. Dropout randomly zeroes a fraction of activations during training only, preventing the network from over-relying on any single neuron.

Why they exist — the history
2012
Dropout was introduced by Hinton and colleagues (including Srivastava, in the fuller 2014 paper), directly motivated by overfitting in networks with many parameters relative to available data — a random subset of neurons is disabled each step, forcing redundancy rather than reliance on any one path.
2015
Batch Normalisation (Ioffe and Szegedy) addressed a different problem: as training progresses, the distribution of each layer's inputs keeps shifting ("internal covariate shift" was the original explanation, though later research debated the precise mechanism), making deep networks slow and unstable to train. Normalising activations within each mini-batch measurably sped up and stabilised training of much deeper networks than were previously practical.
The bug this lesson exists to prevent
Both layers behave differently in training vs. evaluation mode. Forgetting model.eval() before inference leaves Dropout randomly zeroing activations and BatchNorm using batch statistics instead of learned running statistics — silently corrupting predictions in a way that produces no error message, just quietly wrong numbers. This is one of the most common real-world PyTorch bugs, and the notebook demonstrates it directly rather than just warning about it.
REAL-WORLD FINANCIAL EXAMPLE
A cheque-digit reader that memorises training-set quirks (a specific scanner's artefacts, a particular pen's ink) instead of learning generalisable digit shapes will fail unpredictably in production on a different scanner or a different branch's equipment — exactly the overfitting failure Dropout exists to reduce.
⬇ Run this lesson in the notebook
BatchNorm: x̂=(x−μ_B)/√(σ²_B+ε);  y=γx̂+β
Dropout: zero each unit with probability p (train only)
BatchNorm re-centres and re-scales each layer's activations to mean 0, variance 1 using the current mini-batch's statistics (μ_B, σ²_B), then lets the network learn its own preferred scale/shift back (γ, β) — stabilises training against shifting input distributions layer to layer.
Dropout randomly zeroes a fraction p of units on each training step, forcing the network to not rely on any single unit — a form of implicit ensembling. It's switched OFF at evaluation time (all units active, outputs scaled to compensate) — the exact train/eval-mode bug this module demonstrated.
CONCEPT 7

CNN Foundations: Convolution, Padding, Stride, Pooling

Why images need a fundamentally different architecture than tables do.

Overview
🧮 Math & Algorithm
What it is

A convolution slides a small, learnable filter across an image, computing a local dot product at every position — the same pattern-detector is reused everywhere in the image, rather than learning a completely separate weight for every pixel. Pooling then downsamples, keeping the strongest signal in each small region.

Why it exists — the history
1980
Kunihiko Fukushima's Neocognitron introduced the core idea of local receptive fields and shared weights, inspired by biological studies of the visual cortex (Hubel and Wiesel's 1960s work on cat vision).
1989 → 1998
Yann LeCun and colleagues built LeNet, applying backpropagation to convolutional networks for handwritten digit recognition — used commercially to read handwritten cheque amounts at scale for U.S. banks in the 1990s. This is not a coincidental example: it's the literal historical origin of the CNN, applied to the exact same problem this module's lab recreates.
2012
AlexNet (Krizhevsky, Sutskever, Hinton) combined CNNs with GPU training and ReLU at a much larger scale, decisively winning the ImageNet competition and triggering the modern deep-learning boom in computer vision.
Why not just a fully-connected (ANN) layer on the image?
OptionTrade-off
Flatten the image, feed a plain ANNA 28×28 image needs 784 separate weights per neuron, with zero spatial reuse — pixel (0,0) is treated as no more related to pixel (0,1) than to pixel (27,27), throwing away the one thing that makes an image an image
ConvolutionA 3×3 filter (9 weights) is reused at every position — far fewer parameters, and pattern detection becomes position-independent by construction
REAL-WORLD FINANCIAL EXAMPLE
RR Finance's cheque-digit reader in this module's lab is the exact same problem LeNet solved commercially for U.S. banks in the 1990s — reading a handwritten amount off a scanned cheque, at scale, automatically.
⬇ Run this lesson in the notebook
Conv output size = ⌊(W − F + 2P)/S⌋ + 1
(conv[i,j] = Σ kernel · input patch)
Convolution slides a small learned kernel/filter across the image, computing a dot product between the kernel and each local patch — the same kernel is reused everywhere, which is why CNNs need far fewer parameters than a fully-connected layer over raw pixels.
W, F, P, S — input width, kernel size, padding, stride. Padding preserves spatial size at the edges; stride controls how far the kernel jumps each step (larger stride = smaller, coarser output).
Pooling (e.g. max-pool) downsamples by taking the max (or average) over small windows — reduces spatial size and gives a small amount of translation invariance (a digit shifted by 1 pixel still pools to a similar value).
CONCEPT 8 · LAB

Building and Training a CNN

RR Finance's cheque-digit reader, built from the pieces above.

What it is

The lab combines everything so far — convolution, pooling, BatchNorm, Dropout, ReLU, Softmax, backprop, Adam — into one trained model that classifies a 28×28 handwritten digit image into one of 10 classes, using the standard MNIST dataset as a stand-in for real cheque-digit crops.

Why MNIST specifically
1998
MNIST was assembled by Yann LeCun, Corinna Cortes and Christopher Burges from NIST handwriting samples, explicitly as a benchmark for exactly this task — it has been the field's standard "hello world" for image classification for over two decades, precisely because it's clean, well-labelled, and directly tied to the historical cheque-reading use case.

✓ What this lab teaches

  • How the architectural pieces (Lessons 3–7) compose into one trainable system
  • Why the flattened size before the final layer follows directly from the pooling arithmetic (28→14→7)

✗ What it doesn't cover yet

  • Real cheque images have scan noise, skew, and varied handwriting the clean MNIST set doesn't — Module 8 (Multimodal AI) extends this exact pattern to messier real-world document data
REAL-WORLD FINANCIAL EXAMPLE
Automated, auditable digit recognition reduces manual keying error and cost in cheque processing — this lab's architecture, training loop and evaluation approach transfer directly once real, labelled cheque-digit crops are available.
⬇ Run this lesson in the notebook
CONCEPT 9

Transfer Learning

Reusing what a network already learned, when you don't have millions of your own labelled images.

What it is

Instead of training a CNN from scratch, load a network already trained on a large general dataset (e.g. ImageNet), freeze its early layers (which tend to have learned general-purpose features like edges and textures), and only retrain the final layer(s) for your specific task.

Why it exists — the motivating problem
2014 onward
As CNNs like VGGNet and later ResNet (He et al., 2015) were trained on ImageNet's 1.2 million labelled images, researchers noticed their early layers learned remarkably general features — edges, textures, simple shapes — reusable across almost any image task. Fine-tuning only the later layers on a much smaller, task-specific dataset became standard practice, because most organisations will never have anywhere close to ImageNet-scale labelled data for their specific problem.

✓ Use it when

  • You have a new image task but limited labelled data — exactly RR Finance's real-world cheque-digit situation, where labelled crops are expensive and slow to collect under confidentiality constraints

✗ Be careful when

  • Freezing too much prevents adaptation to real quirks (paper texture, ink variation, scan skew)
  • Freezing too little re-introduces the "not enough data" problem transfer learning was meant to solve — how much to freeze is itself a hyperparameter to validate
REAL-WORLD FINANCIAL EXAMPLE
RR Finance may only have a few thousand real, labelled cheque-digit crops — nowhere near enough to train a deep CNN from zero reliably. Starting from a network that already understands "edges and shapes in general" and only teaching it the last mile to "these specific ten digit classes" is the practical answer.
⬇ Run this lesson in the notebook
CONCEPT 10 · CYBERSECURITY

Adversarial Examples: FGSM & PGD

Fooling a correctly trained model, without ever touching its training data.

Overview
🧮 Math & Algorithm
What it is

An adversarial example is an input deliberately perturbed by a tiny, often visually imperceptible amount, crafted specifically to cause a correctly-trained model to misclassify it with high confidence — using the model's own gradients against it.

Why it exists — the history
2013
Szegedy and colleagues ("Intriguing properties of neural networks") first demonstrated that state-of-the-art image classifiers could be fooled by perturbations invisible to the human eye — a genuinely surprising result at the time, since the networks were otherwise performing extremely well.
2015
Goodfellow, Shlens and Szegedy introduced FGSM (Fast Gradient Sign Method) — a single gradient step in the direction that increases the model's loss the fastest, moving every pixel by exactly ±ε.
2017
Madry and colleagues introduced PGD (Projected Gradient Descent) — FGSM applied iteratively with a smaller step size, projecting the perturbation back within the ε budget after each step. PGD became the standard benchmark attack for evaluating model robustness, precisely because it is generally stronger than a single FGSM step.
This is a different attack surface than Module 1's poisoning
AttackWhen it happensWhat the attacker needs
Data poisoning (Module 1)Training timeAbility to influence training data — never touches the deployed model
Adversarial examples (this lesson)Inference timeAccess to (or the ability to estimate) the trained model's gradients, plus a small perturbation budget
The security lesson
The attacker here needs no access to training data and no ability to retrain the model — only the ability to query gradients and a small perturbation budget. This is exactly why adversarial robustness is treated as a distinct concern from data provenance, with its own dedicated attention in Module 11's black-box (query-only) attack scenarios, where the attacker can't even see gradients directly.
REAL-WORLD FINANCIAL EXAMPLE
If RR Finance's cheque-digit reader — or any production image classifier used for document fraud detection or ID verification — can be fooled by adversarial pixel noise, an attacker could manipulate an amount or bypass a check without an obvious visual red flag for a human reviewer.
⬇ Run this lesson in the notebook
FGSM: x' = x + ε·sign(∇ₓL(x,y))
PGD: iterate FGSM step, clip to ε-ball, repeat
FGSM takes one step in the direction that most increases the loss (∇ₓL — gradient with respect to the input pixels, not the weights), scaled by a small ε so the perturbation is imperceptible but the prediction flips.
sign(·) takes only the direction of each pixel's gradient (+1/−1), not its magnitude — a deliberate simplification that makes the attack a single fast step rather than a full gradient descent.
PGD repeats a small version of this step many times, projecting (clipping) back into the allowed ε-ball each iteration — a much stronger, iterative version of the same idea, which is why adversarial training beat FGSM but only partially beat PGD in this module's results.
CONCEPT 11 · CYBERSECURITY

Adversarial Training

The first defence — and an honest look at its limits.

What it is

Adversarial training generates adversarial examples during training and includes them in the training loss, alongside clean examples — explicitly teaching the model to classify attacked inputs correctly too, not just clean ones.

Why it exists — the history
2015 → 2017
Proposed alongside FGSM itself (Goodfellow et al., 2015) as the natural direct defence, then substantially strengthened by Madry et al.'s 2017 formulation using PGD-generated adversarial examples during training — often still referred to as "Madry-style" adversarial training, and broadly considered one of the most reliable (though computationally expensive) defences available today.
Read the robustness numbers honestly
A model adversarially trained against FGSM is not automatically robust against PGD — a different, stronger attack. The notebook measures this directly rather than assuming it: expect a real, visible improvement under the attack the model was trained against, and a smaller, more modest improvement against a different or stronger one. This gap is not a flaw in the exercise — it is the genuine, well-documented state of adversarial robustness research, and exactly why "the model was adversarially trained" is treated as one layer of defence, not a solved problem, mirroring Module 1's layered poisoning defence.
REAL-WORLD FINANCIAL EXAMPLE
A more robust cheque-digit reader degrades more gracefully under real-world noisy conditions (poor scans, compression artefacts) as well as deliberate manipulation — reducing both fraud risk and false-alarm operational cost, though never eliminating either.
⬇ Run this lesson in the notebook

Module 2 hand-off

The notebook benchmarks its ANN against Module 1's exact saved baseline, trains and saves a cheque-digit CNN, and produces a measured (not assumed) adversarial-robustness comparison. Module 3 reuses the same skeleton one more time — business problem → representation → model → cybersecurity angle → lab — this time for text instead of tables or pixels.