Almost everyone who “bounces off” machine learning does so for the same reason: they tried to learn the algorithms before they had the language the algorithms are written in. That language is three branches of mathematics — linear algebra, calculus, and probability/statistics — plus a small, fixed toolbox of software. You do not need to become a mathematician. You need fluency: the ability to look at \(\nabla_\vw \, \tfrac{1}{2}\norm{\mX\vw-\vy}^2 = \mX\tp(\mX\vw-\vy)\) and read it as a sentence rather than a wall of symbols.

Machine learning is, almost entirely, optimizing a function of many variables. Linear algebra is how we represent the data and parameters compactly; calculus is how we improve the parameters; probability is how we reason about uncertainty in the data and the model. Every later phase is a variation on this theme.

How to study Phase 0

Resist the urge to “complete” mathematics. Learn each concept to the depth where you can (a) explain it in words, (b) compute a small example by hand, and (c) reproduce it in NumPy. Use 3Blue1Brown for geometric intuition, then Mathematics for Machine Learning (free PDF) for rigor, then code. Spend roughly 40% linear algebra, 25% calculus, 25% probability/stats, 10% tooling.

Linear algebra

Vectors: the atoms

A vector \(\vx \in \R^n\) is an ordered list of \(n\) numbers. In ML it is almost always a data point (a row of features) or a set of parameters. Two complementary pictures matter:

  • Geometric: an arrow from the origin to a point in \(n\)-dimensional space.

  • Data: “this house = [1800 sq ft, 3 beds, 1995 built, …]”.

The dot product (inner product) of \(\vx,\vy\in\R^n\) is \(\vx\tp\vy = \sum_{i=1}^n x_i y_i = \norm{\vx}\,\norm{\vy}\cos\theta\), where \(\theta\) is the angle between them. It measures alignment: positive when the vectors point similarly, zero when orthogonal, negative when opposed.

The dot product is the single most important operation in ML. A neuron computes \(\vw\tp\vx + b\) — a dot product of weights and inputs. “Similarity” in embeddings, recommender systems, and attention is a (normalized) dot product. When you see cosine similarity in a vector database, it is just \(\frac{\vx\tp\vy}{\norm{\vx}\norm{\vy}}\).

Norms: measuring size

A norm measures the length of a vector. The three you must know: \[\norm{\vx}_1 = \sum_i \abs{x_i}\ (\text{L1, ``Manhattan''}),\quad \norm{\vx}_2 = \sqrt{\textstyle\sum_i x_i^2}\ (\text{L2, ``Euclidean''}),\quad \norm{\vx}_\infty = \max_i \abs{x_i}.\] For matrices, the Frobenius norm \(\norm{\mA}_F = \sqrt{\sum_{i,j} A_{ij}^2}\) is the L2 norm of the flattened matrix. These reappear immediately in Phase 1 as regularizers: L2 (Ridge) shrinks weights smoothly, L1 (Lasso) drives some weights exactly to zero.

Matrices and matrix multiplication

A matrix \(\mA \in \R^{m\times n}\) is a grid of numbers, and is best understood as a linear transformation from \(\R^n\) to \(\R^m\). The product \(\mA\vx\) is a new vector; \((\mA\mB)\) composes two transformations.

For \(\mA\in\R^{m\times k}\), \(\mB\in\R^{k\times n}\), the product \(\mathbf{C}=\mA\mB\in\R^{m\times n}\) has entries \(C_{ij}=\sum_{\ell=1}^{k} A_{i\ell}B_{\ell j}\). The inner dimension \(k\) must match. Matrix multiplication is associative (\(\mA(\mB\mathbf{C})=(\mA\mB)\mathbf{C}\)) and distributive, but not commutative (\(\mA\mB \neq \mB\mA\) in general).

Three ways to read \(\mA\mB\), each useful: (1) entry \((i,j)\) = row \(i\) of \(\mA\) dotted with column \(j\) of \(\mB\); (2) each column of the output is \(\mA\) applied to the corresponding column of \(\mB\); (3) the output is a sum of outer products. A forward pass through a neural-network layer is exactly \(\mX\mW\) — a batch of inputs times a weight matrix. ML is batched matrix multiplication.

Let \(\mA=\begin{psmallmatrix}1&2\\0&1\end{psmallmatrix}\), \(\mB=\begin{psmallmatrix}3&1\\2&4\end{psmallmatrix}\). Then \[\mA\mB=\begin{psmallmatrix} 1\cdot3+2\cdot2 & 1\cdot1+2\cdot4\\ 0\cdot3+1\cdot2 & 0\cdot1+1\cdot4\end{psmallmatrix}=\begin{psmallmatrix}7&9\\2&4\end{psmallmatrix}.\] Check non-commutativity: \(\mB\mA=\begin{psmallmatrix}3&7\\2&8\end{psmallmatrix}\neq\mA\mB\). The matrix \(\mA\) is a shear: it leaves the \(x\)-axis fixed and slides points right in proportion to their height.

Transpose, identity, inverse

The transpose \(\mA\tp\) swaps rows and columns: \((\mA\tp)_{ij}=A_{ji}\), with \((\mA\mB)\tp=\mB\tp\mA\tp\). The identity \(\mI\) has ones on the diagonal and acts as the “do nothing” transform: \(\mI\vx=\vx\). The inverse \(\mA^{-1}\) (when it exists, for square \(\mA\)) undoes the transform: \(\mA^{-1}\mA=\mI\).

In code you almost never compute an explicit inverse. To solve \(\mA\vx=\vb\), call , not . The former is faster, more numerically stable, and avoids amplifying round-off error. Forming \(\mA^{-1}\) is a red flag in numerical code.

Rank, determinant, and what can go wrong

The rank of a matrix is the number of linearly independent columns — the dimension of the space its outputs actually span. A matrix is full rank when no column is a combination of the others. The determinant \(\det(\mA)\) measures how the transform scales volume; \(\det(\mA)=0\) means the transform collapses space into a lower dimension (and the matrix is singular / non-invertible).

Rank deficiency is the geometry behind multicollinearity in regression: if two features are perfectly correlated, the data matrix is rank-deficient, \(\mX\tp\mX\) is singular, and the normal equation has no unique solution. Regularization (adding \(\lambda\mI\)) is partly a fix for this — it nudges the matrix back to full rank.

Eigenvalues, eigenvectors, and eigendecomposition

For a square matrix \(\mA\), a nonzero vector \(\vv\) is an eigenvector with eigenvalue \(\lambda\) if \[\mA\vv = \lambda\vv.\] The transform \(\mA\) acts on \(\vv\) by pure scaling — no rotation. Eigenvectors are the “natural axes” of the transformation.

If \(\mA\in\R^{n\times n}\) has \(n\) independent eigenvectors, it admits an eigendecomposition \(\mA = \mathbf{Q}\boldsymbol{\Lambda}\mathbf{Q}^{-1}\), where columns of \(\mathbf{Q}\) are eigenvectors and \(\boldsymbol{\Lambda}=\diag(\lambda_1,\dots,\lambda_n)\). For a symmetric matrix, \(\mathbf{Q}\) is orthogonal (\(\mathbf{Q}^{-1}=\mathbf{Q}\tp\)), giving \(\mA=\mathbf{Q}\boldsymbol{\Lambda}\mathbf{Q}\tp\) — the spectral theorem.

Covariance matrices are symmetric and positive semi-definite; their eigenvectors are the principal axes of the data cloud and their eigenvalues are the variance along each axis. That is exactly PCA (Phase 1). In optimization, the eigenvalues of the Hessian tell you the curvature of the loss surface — large spread of eigenvalues (high condition number) is precisely why plain gradient descent zig-zags and why we need momentum and adaptive methods (Phase 2).

Singular Value Decomposition (SVD)

SVD generalizes eigendecomposition to any matrix, square or not. Every \(\mA\in\R^{m\times n}\) factors as \[\mA = \mathbf{U}\boldsymbol{\Sigma}\mathbf{V}\tp,\] where \(\mathbf{U}\in\R^{m\times m}\) and \(\mathbf{V}\in\R^{n\times n}\) are orthogonal, and \(\boldsymbol{\Sigma}\) is diagonal with non-negative singular values \(\sigma_1\ge\sigma_2\ge\dots\ge 0\). Geometrically every linear map is a rotation, then a scaling, then another rotation.

SVD is the Swiss-army knife of applied linear algebra. Keeping only the top-\(k\) singular values gives the best rank-\(k\) approximation of a matrix (Eckart–Young theorem). This single fact powers PCA, latent semantic analysis, recommender systems (low-rank matrix factorization), image compression, and the “intrinsic dimension” intuition behind LoRA fine-tuning in Phase 4.

A grayscale image is a matrix of pixel intensities. Compute its SVD, keep the largest \(k\) singular values, and reconstruct \(\mA_k=\mathbf{U}_{:,:k}\boldsymbol{\Sigma}_{:k,:k}\mathbf{V}_{:,:k}\tp\). With \(k\) far smaller than the image dimensions you recover a recognizable image using a fraction of the numbers — a vivid demonstration that real data lives near a low-dimensional subspace.

import numpy as np
U, s, Vt = np.linalg.svd(A, full_matrices=False)   # A is (m, n)
k = 30
A_k = (U[:, :k] * s[:k]) @ Vt[:k, :]               # rank-k reconstruction
energy = s[:k].sum() / s.sum()                      # fraction of "energy" kept

Vector spaces, basis, and projection

A basis is a minimal set of vectors whose linear combinations generate a space; coordinates are just the coefficients in some basis. Projection onto a subspace finds the closest point in that subspace — the geometric heart of least-squares regression. The projection of \(\vy\) onto the column space of \(\mX\) is \(\hat\vy = \mX(\mX\tp\mX)^{-1}\mX\tp\vy\); the residual \(\vy-\hat\vy\) is orthogonal to that space. That orthogonality is the normal equation you will derive in Phase 1.

  • 3Blue1Brown — “Essence of Linear Algebra” (watch the whole series; it builds the geometric picture better than any text).

  • Mathematics for Machine Learning, Ch. 2–4 (free PDF).

  • Gilbert Strang, MIT 18.06 lectures — the classic deep dive; his treatment of the four fundamental subspaces and SVD is definitive.

Calculus

Derivatives and the chain rule

The derivative \(f'(x)\) is the instantaneous rate of change — the slope of the tangent line. The chain rule composes rates of change: \[\frac{d}{dx} f(g(x)) = f'(g(x))\,g'(x).\]

The chain rule, applied mechanically across the layers of a network, is backpropagation (Phase 2). If you understand \(\frac{dz}{dx}=\frac{dz}{dy}\frac{dy}{dx}\) deeply, you already understand the core of deep learning; the rest is bookkeeping over many variables.

Partial derivatives, gradients, Jacobians, Hessians

For a function \(f(\vx)\) of several variables, the partial derivative \(\partial f/\partial x_i\) varies one input while holding the rest fixed. Collecting them gives the gradient: \[\nabla f(\vx) = \Big(\tfrac{\partial f}{\partial x_1}, \dots, \tfrac{\partial f}{\partial x_n}\Big)\tp \in \R^n.\]

The gradient points in the direction of steepest ascent of \(f\), and its negative points toward steepest descent. Its magnitude is the rate of steepest change. This is the entire justification for gradient descent: to decrease a loss, step in the direction \(-\nabla f\).

For a vector-valued function \(\mathbf{f}:\R^n\to\R^m\), the Jacobian \(\mathbf{J}\in\R^{m\times n}\) collects all partials \(J_{ij}=\partial f_i/\partial x_j\). The Hessian \(\mathbf{H}\in\R^{n\times n}\) collects second partials \(H_{ij}=\partial^2 f/\partial x_i\partial x_j\) and describes curvature.

Gradient = slope (first order, “which way is downhill”). Hessian = curvature (second order, “how sharply the slope changes”). First-order methods (SGD, Adam) use only gradients because the Hessian is enormous for deep nets (\(n\) can be billions). But knowing the Hessian exists explains why learning rates matter, why some directions need momentum, and why ill-conditioned losses are hard.

Gradients you will use constantly

Memorize these matrix-calculus identities; they cover most of classical ML. \[\begin{align*} \nabla_\vx (\va\tp\vx) &= \va, & \nabla_\vx (\vx\tp\mA\vx) &= (\mA+\mA\tp)\vx, \\ \nabla_\vx \tfrac{1}{2}\norm{\vx}_2^2 &= \vx, & \nabla_\vw \tfrac{1}{2}\norm{\mX\vw-\vy}_2^2 &= \mX\tp(\mX\vw-\vy). \end{align*}\]

Let \(L(\vw)=\tfrac12\norm{\mX\vw-\vy}_2^2=\tfrac12(\mX\vw-\vy)\tp(\mX\vw-\vy)\). Expand: \[L=\tfrac12\big(\vw\tp\mX\tp\mX\vw - 2\vw\tp\mX\tp\vy + \vy\tp\vy\big).\] Differentiate term by term using the identities above: \[\nabla_\vw L = \mX\tp\mX\vw - \mX\tp\vy = \mX\tp(\mX\vw-\vy).\] Setting \(\nabla_\vw L=\mathbf{0}\) yields the normal equation \(\mX\tp\mX\vw=\mX\tp\vy\), i.e. \(\vw=(\mX\tp\mX)^{-1}\mX\tp\vy\). You just derived linear regression’s closed form — and the projection formula from the previous section.

Why gradient descent works

Gradient descent iterates \(\vw_{t+1}=\vw_t-\eta\,\nabla f(\vw_t)\). The first-order Taylor expansion explains it: near \(\vw_t\), \(f(\vw_t+\Delta)\approx f(\vw_t)+\nabla f(\vw_t)\tp\Delta\). Choosing \(\Delta=-\eta\nabla f\) makes the inner product as negative as possible (for small step), so \(f\) decreases. The step size \(\eta\) (learning rate) trades speed against the risk of overshooting — too large and you diverge, too small and you crawl.

The negative gradient is the steepest descent direction only locally. On curved or ill-conditioned surfaces, naive steps zig-zag across valleys. This is the practical reason momentum, RMSProp, and Adam exist (Phase 2). Also: gradient descent finds a local minimum, not necessarily the global one — though for the convex losses of Phase 1 (linear/logistic regression), local = global.

  • 3Blue1Brown — “Essence of Calculus”.

  • Mathematics for Machine Learning, Ch. 5 (Vector Calculus) — the matrix-calculus reference for ML.

  • The Matrix Cookbook (free PDF) — a lookup table of gradient identities.

Probability & statistics

Random variables and distributions

A random variable maps outcomes to numbers. You must know these distributions and where each shows up:

Distribution Models Shows up in ML as
Bernoulli\((p)\) a single yes/no trial binary classification target
Binomial\((n,p)\) # successes in \(n\) trials counts, A/B test conversions
Categorical one of \(K\) classes softmax output, multiclass labels
Gaussian\((\mu,\sigma^2)\) symmetric continuous noise errors, weight init, latent spaces
Poisson\((\lambda)\) event counts per interval arrivals, rare-event counts
Exponential\((\lambda)\) waiting time between events survival, time-to-event

The Gaussian (normal) density is \(\;p(x)=\frac{1}{\sqrt{2\pi\sigma^2}}\exp\!\big(-\frac{(x-\mu)^2}{2\sigma^2}\big)\). It is the default model for noise (justified by the Central Limit Theorem), the basis of the squared-error loss (negative log-likelihood of Gaussian noise is MSE), and the standard prior/latent in VAEs and diffusion models (Phase 5).

Expectation, variance, covariance, correlation

\[\E[X]=\sum_x x\,p(x)\ \text{(or }\textstyle\int x\,p(x)\,dx),\quad \Var(X)=\E[(X-\E X)^2]=\E[X^2]-(\E X)^2.\] For two variables, covariance \(\Cov(X,Y)=\E[(X-\E X)(Y-\E Y)]\) measures co-movement, and correlation \(\rho=\Cov(X,Y)/(\sigma_X\sigma_Y)\in[-1,1]\) is its scale-free version. The covariance matrix \(\mS\) of a random vector collects all pairwise covariances; it is symmetric PSD, and its eigen-structure is PCA.

Correlation measures linear association only. Two variables can be strongly dependent yet have \(\rho=0\) (e.g. \(Y=X^2\) with \(X\) symmetric about 0). And of course correlation is not causation — a lesson with real teeth once you start interpreting feature importances and “the model says X drives Y”.

Conditional probability and Bayes’ theorem

\[\Prob(A\mid B)=\frac{\Prob(A\cap B)}{\Prob(B)},\qquad \underbrace{\Prob(\theta\mid \text{data})}_{\text{posterior}}=\frac{\overbrace{\Prob(\text{data}\mid\theta)}^{\text{likelihood}}\,\overbrace{\Prob(\theta)}^{\text{prior}}}{\underbrace{\Prob(\text{data})}_{\text{evidence}}}.\]

Bayes’ theorem is how you update beliefs with evidence. It is the engine behind Naive Bayes classifiers, the Bayesian view of regularization (a prior on weights), Bayesian hyperparameter optimization (Phase 1), and the conceptual frame for nearly all probabilistic modeling. Internalize “posterior \(\propto\) likelihood \(\times\) prior.”

A disease affects 1 in 1000 people. A test is 99% accurate (both sensitivity and specificity). You test positive — what is the chance you are sick? Let \(D\) = disease, \(+\) = positive. \[\Prob(D\mid+)=\frac{\Prob(+\mid D)\Prob(D)}{\Prob(+\mid D)\Prob(D)+\Prob(+\mid\lnot D)\Prob(\lnot D)} =\frac{0.99\cdot0.001}{0.99\cdot0.001+0.01\cdot0.999}\approx 0.09.\] Only 9%. The rare base rate dominates. This is the same trap as evaluating a classifier on a heavily imbalanced dataset by accuracy alone (Phase 1) — and why precision/recall exist.

MLE and MAP estimation

Given data and a parametric model, Maximum Likelihood Estimation (MLE) chooses parameters that make the observed data most probable: \[\hat{\vtheta}_{\text{MLE}}=\argmax_{\vtheta} \prod_i p(x_i\mid\vtheta)=\argmax_{\vtheta} \sum_i \log p(x_i\mid\vtheta).\] Maximum A Posteriori (MAP) adds a prior: \(\hat{\vtheta}_{\text{MAP}}=\argmax_{\vtheta} \big[\sum_i\log p(x_i\mid\vtheta)+\log p(\vtheta)\big]\).

Most loss functions are disguised negative log-likelihoods. Gaussian noise \(\Rightarrow\) MLE = least squares (MSE). Bernoulli/categorical labels \(\Rightarrow\) MLE = cross-entropy. A Gaussian prior on weights \(\Rightarrow\) MAP = L2 regularization (Ridge); a Laplace prior \(\Rightarrow\) L1 (Lasso). Seeing losses this way unifies half of Phases 1 and 2.

Inferential statistics: CLT, intervals, hypothesis tests

The Central Limit Theorem states that the mean of many independent samples is approximately Gaussian, regardless of the underlying distribution. This is why averages are well-behaved and why error bars work. A confidence interval quantifies uncertainty in an estimate; a \(p\)-value is the probability of seeing data at least as extreme as observed if the null hypothesis were true.

A \(p\)-value is not the probability that the null hypothesis is true, and “\(p<0.05\)” is not proof of importance. In ML this matters most when you compare models: a 0.2% accuracy bump on one test split may be noise. Use cross-validation and, where stakes are high, statistical tests on the per-fold results before declaring a winner (Phase 1).

  • StatQuest (Josh Starmer) — the most intuitive stats/ML explainers on the internet.

  • Khan Academy — Statistics & Probability (for systematic coverage and practice problems).

  • Mathematics for Machine Learning, Ch. 6 (Probability & Distributions).

Tooling: the scientific Python stack

You already program well, so this is about idioms, not syntax. The goal is to think in vectorized array operations, not Python loops.

NumPy — the foundation

NumPy’s is the substrate everything else builds on. The two ideas that separate beginners from fluent users are vectorization and broadcasting.

Broadcasting lets arrays of different shapes combine without explicit loops by virtually stretching size-1 dimensions. Standardizing a data matrix is one line: . Internalizing broadcasting rules (align shapes from the right; dimensions must be equal or one of them 1) is the single highest-leverage NumPy skill.

import numpy as np
X = np.random.randn(1000, 5)          # 1000 samples, 5 features
mu, sigma = X.mean(axis=0), X.std(axis=0)   # shape (5,)
Xz = (X - mu) / sigma                  # broadcast (1000,5)-(5,) -> (1000,5)

# Vectorized vs. loop: compute pairwise squared distances to a centroid
c = X.mean(0)
d2 = ((X - c) ** 2).sum(axis=1)        # shape (1000,), no Python loop

The most common silent bug in ML code is a shape mismatch that broadcasts “successfully” into the wrong thing (e.g. a vector subtracted from an column produces an matrix). Print obsessively. A second classic: views vs. copies — slicing returns a view, so in-place edits can mutate the original array.

Pandas — tabular data

Pandas s handle real-world messy tables: mixed types, missing values, joins, group-bys. Learn , indexing with /, , , and handling (, ). You will live in Pandas during the Phase 1 EDA and feature-engineering work.

Matplotlib & Seaborn — seeing the data

Plotting is not decoration; it is debugging. Always look at your data and your model’s errors. Histograms reveal skew and outliers, scatter plots reveal relationships, residual plots reveal model misfit, and learning curves reveal over/underfitting (Phase 1). Seaborn sits on Matplotlib for fast statistical plots (, of a correlation matrix).

Jupyter / Colab, Git, and a little SQL

  • Jupyter / Colab: interactive exploration. Colab gives free GPUs (vital from Phase 3). Beware hidden state from out-of-order cell execution — restart-and-run-all before trusting a notebook.

  • Git: version every experiment. Commit notebooks and configs; keep large data and model weights out of the repo (use , DVC, or a model registry later in Phase 7).

  • SQL: you are likely already strong here. For ML it is the data-wrangling front door — , , , window functions for feature aggregation pull training sets straight from warehouses.

Treat notebooks as a lab notebook, not production code. Explore in Jupyter, then refactor the keeper logic into importable modules with functions and tests. This discipline pays off enormously by Phase 7, when notebooks must become pipelines.

Checkpoint project

Goal: implement gradient descent with no ML libraries and see it work, cementing the calculus–optimization link that underlies every later phase.

Part A — 1D warm-up. Minimize \(f(w)=w^2\) (or a quartic with two minima to observe local minima). Implement the update \(w \leftarrow w-\eta f'(w)\) by hand-deriving \(f'\). Plot \(f\) and overlay the sequence of iterates as points connected by arrows (as in the figure above).

Part B — 2D bowl. Minimize \(f(\vw)=\tfrac12\vw\tp\mA\vw\) for a \(2\times2\) symmetric positive-definite \(\mA\) (so the level sets are ellipses). Derive \(\nabla f=\mA\vw\). Draw a contour plot and trace the descent path. Make \(\mA\) ill-conditioned (e.g. eigenvalues 1 and 20) and watch the path zig-zag — you have now seen why conditioning and momentum matter.

Part C — real loss, real data. Fit a line \(y=w_0+w_1 x\) to noisy synthetic data by minimizing MSE via gradient descent. Verify your solution matches the closed-form normal equation \(\vw=(\mX\tp\mX)^{-1}\mX\tp\vy\). Plot the loss vs. iteration (it should decrease smoothly) and the fitted line over the data.

Deliverables: a clean notebook or repo with (1) the descent-path figure, (2) the contour/zig-zag figure, (3) the loss curve, (4) a short paragraph explaining what the learning rate does and what you observed when it was too large.

Stretch goals: add momentum and compare convergence; sweep \(\eta\) and plot final loss vs. \(\eta\); implement everything with explicit shapes asserted ().

import numpy as np

def gradient_descent(grad_fn, w0, lr=0.1, steps=100):
    """Generic GD; grad_fn(w) returns the gradient at w."""
    w = np.array(w0, dtype=float)
    history = [w.copy()]
    for _ in range(steps):
        w = w - lr * grad_fn(w)
        history.append(w.copy())
    return w, np.array(history)

# Part C: linear regression via GD, then check vs. the normal equation.
rng = np.random.default_rng(0)
X = np.c_[np.ones(200), rng.uniform(-3, 3, 200)]   # design matrix (200,2)
w_true = np.array([1.5, -2.0])
y = X @ w_true + 0.5 * rng.standard_normal(200)

grad = lambda w: X.T @ (X @ w - y) / len(y)         # MSE gradient
w_gd, hist = gradient_descent(grad, [0.0, 0.0], lr=0.05, steps=500)
w_closed = np.linalg.solve(X.T @ X, X.T @ y)         # normal equation
print("GD     :", w_gd)
print("closed :", w_closed)        # should match to a few decimals

Phase 0 self-check

Before moving to Phase 1, you should be able to, without notes:

  • Explain what \(\mA\vx\) does geometrically and compute a small matrix product by hand.

  • State what eigenvectors/eigenvalues and the SVD are, and name one ML use of each.

  • Derive the gradient of the least-squares loss and the normal equation.

  • Explain why \(-\nabla f\) is the descent direction and what the learning rate controls.

  • Recover MSE and cross-entropy as negative log-likelihoods, and L2/L1 as MAP priors.

  • Apply Bayes’ theorem to a base-rate problem and interpret the result.

  • Vectorize a computation with NumPy broadcasting instead of a Python loop.

If two or three of these feel shaky, that is normal — revisit just those, then proceed. You do not need mastery of all of mathematics; you need enough fluency that the notation in Phase 1 and 2 reads as meaning rather than noise. The remaining gaps will close through use.