Assignment & Project Guide: Day-by-Day Assignments
Beginner-friendly tasks, three-tier hints, fill-in READMEs and full solutions for Days 2–15 and the GenAI Project Ladder. How this part works with the book - Page references. Where this part says “Book pages 65, 84” it m
Beginner-friendly tasks, three-tier hints, fill-in READMEs and full solutions for Days 2–15 and the GenAI Project Ladder.
How this part works with the book
- Page references. Where this part says “Book pages 65, 84” it means pages of Parts I–III of this volume.
- It replaces the old Assignment Companion. The standard format, acceptance criteria (“You are done when…”), dataset sheet, GitHub layout, rubric and Break-it table now live once, in the day pages and in the end-matter (GitHub Submission System p. 379, Self-Rubric p. 380, Deliberate Debugging p. 382).
- Glossary. Wherever a page says “see the glossary”, use the book’s Glossary (p. 325) plus the extra terms below.
- Solutions. The Solutions Appendix (p. 384) holds runnable versions. Where it differs from a worked solution inside a day chapter (for example the Days 7–8 Telco imputer fix), prefer the appendix.
Extra glossary terms (not in the book’s Glossary)
| Term | Plain-English meaning |
|---|---|
| Missing values (NaN) | Empty cells in your data. |
| Encoding / one-hot | Turning words into numbers; one-hot = one new 0/1 column per category. |
| Stratify | Keep the same class ratio in train and test. |
| ROC-AUC | How well the model separates the classes (1.0 perfect, 0.5 random). |
| Pipeline / ColumnTransformer | A chain of steps applied safely and in order / lets different columns get different steps. |
| k-Means elbow | Plot of inertia vs k used to pick k; inertia = how tight the clusters are. |
| Term | Plain-English meaning |
|---|---|
| Gradient check | Comparing your analytic gradient with (L(w+e) − L(w−e)) / 2e. |
| state_dict | The dictionary of a model’s weights; the recommended way to save a model. |
| MLP | Network that sees a flat list of pixels (a CNN scans small patches instead). |
| Causal mask | Blocks future words so each word sees only itself and earlier ones. |
| Chunking | Cutting documents into small pieces before embedding and retrieval. |
How this guide works
Every day has two levels. Do Level 1 first. Only do Level 2 if you have time and energy.
| Level | Name | Who it is for | What it gives you |
|---|---|---|---|
| Level 1 | Core (Must do) | Everyone | You finish the assignment and understand it |
| Level 2 | Expert Challenge (Optional) | When Level 1 feels easy | Skills that make you stand out |
You do NOT need Level 2 to complete the course. A finished Level 1 beats an unfinished Level 2 every time. Anything the book marks as required is in Level 1, never hidden in Level 2.
Each day is laid out the same way
- Goal in plain words - what you are doing and why
- Words you need - short definitions, no jargon
- Level 1 - Must do - small numbered steps
- You are done when… - a clear finish line (the acceptance checklist)
- If you get stuck - the most common problems and their fixes 6. Hints - three tiers, open one at a time
- Fill-in README - sentences with blanks to complete
- Level 2 - Expert Challenges - optional extras
- Solutions - complete code for every day in the appendix at the end
How to use Hints and Solutions
| Stage | What to do |
|---|---|
| Try first | Spend at least 20 minutes on the Level 1 steps alone |
| Hint 1 | A gentle nudge: tells you where to look |
| Hint 2 | More specific: tells you which function or idea |
| Hint 3 | Almost the answer: shows the key line |
| Solution | Full working code in the Solutions Appendix. Read it, close it, then type your own version |
Never copy a solution. If you looked at it, close it and rewrite it from memory. That is where the learning happens.
How much to trust the solution code
Each solution carries the status the source guide gave it. TESTED means it was run on the exact generated data from the book. VERIFY LOCALLY means it needs an external download (Titanic, fraud, churn, MNIST, a sentence-transformers model), so run it yourself and expect your numbers to differ a little. Where this guide added a small starter that the source did not contain, it is marked ADDED STARTER (not run).
The golden rules for beginners
- Type the code yourself. Do not copy-paste. Typing teaches you.
- Run small pieces. Run one cell at a time and look at the output.
- Print shapes and heads.
print(x.shape)anddf.head()solve half of all bugs. - Stuck for 15 minutes? Take a break, then read the error message from the bottom line up.
- One day = one folder = one README. Small and finished is the goal.
- Test set = once. Tune with validation or cross-validation; touch the test set at the very end.
Setup checklist (do once)
□ Install Python 3.10 or newer □ Run: pip install numpy pandas matplotlib scikit-learn jupyter torch torchvision seaborn □ Days 7–8 embeddings: pip install sentence-transformers (Day 13 optional BERT: pip install transformers ) □ Open a notebook: jupyter notebook (or use VS Code) □ Create a GitHub account and an empty repo called ml-dl-fundamentals □ Create one folder per day, e.g. Day-01-NumPy-Pandas (full list in the GitHub section)
Git in 3 commands (do this at the end of every day)
git add .
git commit -m "Finish Days 2–3"
git pushThe 3 passes (a simple work rhythm)
| Pass | What you do |
|---|---|
| 1. Make it work | Run the smallest useful version, get the right shape or answer |
| 2. Understand it | Explain each important line in your own words; check shapes and failure cases |
| 3. Tidy it | Add plot titles, write the README, use seeds and relative paths, Restart and Run All |
Tidy checklist (use for every day)
□ Notebook has a title and short headings □ Kernel → Restart and Run All works with no red errors □ Every plot has a title, axis labels and (if needed) a legend □ README has a results table and at least 3 sentences of insight □ Big data files are NOT uploaded to GitHub
Datasets - one source of truth
Never use two names for one file. The Telco data downloads as WA_Fn-UseC_-Telco-Customer-Churn.csv but the book code reads telco.csv: rename the file or change the path, and note your choice in the README.
| Dataset | Source | File the code expects | Used on |
|---|---|---|---|
| Titanic | Kaggle “Titanic” training file | titanic.csv | Days 2–3 (and Ladder Stage 1) |
| Generated regression | Made in code with fixed seeds (100 pts Day 4; 60 pts Day 5) | - | Days 2, 3 |
| Credit Card Fraud | Kaggle “Credit Card Fraud Detection” (284,807 rows, 492 fraud) | creditcard.csv | Day 6 (Stage 3) |
| Telco Churn | Kaggle “Telco Customer Churn” (7,043 rows, ~27% churn) | telco.csv | Days 7–8 |
| Datase t | Source | File the code expects | Used on |
|---|---|---|---|
| Moons | sklearn.datasets.make_moons | - | Days 6, 7 |
| MNIST | torchvision.datasets.MNIST (60k train + 10k test) | - | Days 8, 10 |
External CSVs are inputs, not deliverables: do not commit them. MNIST downloads into data/; keep data/ in .gitignore.
Difficulty: Beginner | Book pages: 65, 84; recipe 89-91
Goal in plain words
Learn to do fast math on many numbers at once (NumPy) and to clean a messy table (Pandas). Every later day uses these tools.
Words you need
Array, shape, vectorization, DataFrame, NaN, encoding (see the glossary). Cosine similarity = a score from -1 to 1 saying how similar two lists of numbers are (1 = same direction). GroupBy = split a table into groups and summarize each one.
Level 1 - Must do
Assignment A - Cosine similarity (no loops)
- Write
cosine_sim_matrix(A, B)using row normalization:A /np.linalg.norm(A, axis=1, keepdims=True). The function itself must contain no Python loop. - Test by hand:
a=[1,0],b=[1,1]should give about 0.707. - Make two random matrices:
A = np.random.rand(4, 8)andB =np.random.rand(5, 8). - Compute
A_norm @ B_norm.Tand check the shape is (4, 5). - Optional: write a slow loop version in a separate cell, only to prove the fast one is correct with
np.allclose.
Assignment B - Titanic cleaning (use the book's order)
- Load
titanic.csvand look:df.head(),df.shape,df.info(),df.isna().sum(). - Fill missing Age with the median and missing Embarked with the most common value.
- Drop
Cabin,Ticket,Name,PassengerId. Write a one-line reason for each. - Turn Sex into numbers (male=0, female=1). One-hot encode Embarked with
pd.get_dummies(..., drop_first=True). - Check there are zero missing values, then save with
df.to_csv("titanic_clean.csv", index=False). - Use
groupbyon Sex and on Pclass: who survived more, women or men? Which class?
You are done when…
□ cosine_sim_matrix(A, B) returns shape (n, m) for A (n, d) and B (m, d); the function has no loop □ Every cosine value is between -1 and 1, and cosine_sim_matrix(A, A) is about 1 on the diagonal □ np.allclose between the fast and loop versions is True □ titanic_clean.csv has zero missing values and only numeric columns □ Each dropped column has a one-line reason □ README lists 3 things you found in the data
If you get stuck
| Problem | Fix |
|---|---|
| “shapes not aligned” | Print A.shape and B.shape; use B.T for the pairwise multiplication |
| KeyError: 'Age' | Print df.columns; check spelling and capital letters |
| Model complains about text | A column is still words; encode it before numeric modeling |
| NaNs remain | Re-run df.isna().sum() and check the two fills before saving |
Hints
- Hint 1: Think in rows. Normalize each row first; after normalization, cosine becomes a dot product.
- Hint 2: Use
np.linalg.normwithaxis=1andkeepdims=True; usepd.get_dummiesfor Embarked. - Hint 3:
A_norm @ B_norm.Tgives every pair at once;df.groupby("Sex")["Survived"].mean()answers “who survived more?”
Fill-in README
I cleaned the Titanic data by dropping __ columns and filling missing with the and with the . Women survived at about % and men at about %. First class passengers survived than third class. My cosine similarity matrix has shape and my function uses __ loops.
Level 2 - Expert Challenges (optional)
- Loop vs vectorized: compare against a deliberately slow nested loop with
np.allcloseand time both. - Zero-vector safety: handle an all-zeros row without dividing by zero.
- Plot the similarity matrix with
plt.imshowand a colorbar. - Chart the story: survival by sex, survival by class, age histogram.
- Safety net: add
assert df.isna().sum().sum() == 0so the notebook fails loudly.
Full code: see Solution - Days 2–3 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Intermediate | Book pages: 103; recipe 112
Goal in plain words
Teach a computer to draw the best straight line through points by making small corrections again and again. That process is gradient descent. Picture a hill in fog: the hill height is the loss, your step size is the learning rate.
Words you need
Loss (MSE), learning rate, epoch, gradient descent (see the glossary). dw / db = how much the loss changes if you nudge w or b a little.
Level 1 - Must do
- Generate the book's data:
np.random.seed(42),X = 2 * np.random.rand(100,1),y = 4 + 3 * X + np.random.randn(100, 1). - Start with
w = 0.0,b = 0.0,lr = 0.1,epochs = 1000. - In a loop, do five things: predict (
w * X + b), error (y_pred - y), loss (mean of error squared), gradientsdwanddb, then updatew -= lr * dw,b -= lr * db. - Store the loss after every epoch in a list.
- Plot the loss curve (it should fall and flatten) and the data points with your fitted line.
- Fit
LinearRegression()from scikit-learn and compare its w and b with yours in a small table.
You are done when…
□ Loss decreases clearly, then flattens □ w is near 3 and b near 4 (the book run gives about 2.77 and 4.21, because noise nudges the answer) □ Scratch w and b are close to scikit-learn's □ The loop uses NumPy only; the loss curve and fitted line are saved □ README explains dw and db in plain words
If you get stuck
| Problem | Fix |
|---|---|
| Loss goes UP or becomes nan | Learning rate too big; try 0.01 |
| Loss barely moves | Learning rate too small, or too few epochs |
| Shape error | Print X.shape and y.shape; both should be (100, 1) |
| Scratch and sklearn differ | Check the gradient formulas and the update direction |
Hints
- Hint 1: Predict first:
y_pred = w * X + b. Then compute the error and the MSE. - Hint 2: For
dwthe error is multiplied by X;dbuses the error without X. Both start with(2/n) * sum(...). - Hint 3: Update against the slope:
w -= lr * dwandb -= lr * db. In sklearn,model.coef_[0][0]is w andmodel.intercept_[0]is b.
Fill-in README
My gradient descent found w = __ and b = (true values 3 and 4). scikit-learn found w = and b = . `dw` tells me and `db` tells me . The loss curve . When I made the learning rate too large, __.
Level 2 - Expert Challenges (optional)
- Learning-rate lab: run lr = 0.001, 0.01, 0.1, 0.5, 1.5 and plot all loss curves; label “too slow”, “good”, “explodes”.
- Wrap everything into
fit(X, y, lr, epochs)that returnsw, b, losses. - Many features: rewrite with
y_pred = X @ w + bfor 3 input columns. - Check the math: confirm your gradient against
(L(w+e) - L(w-e)) / (2e).
Full code: see Solution - Day 4 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Intermediate | Book pages: 126-129
Goal in plain words
See with your own eyes how a model can be too simple, just right or too wild, and learn the tools that keep it under control. Overfitting is the student who memorizes past exam answers and fails a new exam.
Words you need
*Overfitting, underfitting, train/validation, Ridge (L2), Lasso (L1), cross-validation, data leakage (see the glossary). Polynomial degree* = how curvy the model is allowed to be.
Level 1 - Must do
- Generate the book's 60-point cubic data:
np.random.seed(0),X =np.sort(np.random.rand(60,1)*6-3, axis=0),y = (0.5*X 3 - X 2 + 2*X +np.random.randn(60,1)*3).ravel(). - Split exactly:
train_test_split(X, y, test_size=0.3, random_state=1). - For every degree 1 to 15 fit
make_pipeline(PolynomialFeatures(d),StandardScaler(), LinearRegression())and record train and validation MSE. - Plot both errors against degree. Validation should show a minimum around degree 3 and rise again. Name the underfit and overfit zones.
Required: regularization at degree 15
- Compare plain
LinearRegression(),Ridge(alpha=1)andLasso(alpha=0.1,max_iter=50000)on validation MSE.
Required: 5-fold cross-validation
- Run
cross_val_score(..., cv=5, scoring="neg_mean_squared_error")for all four: Deg3 Linear, Deg15 Linear, Deg15 Ridge(alpha=1), Deg15 Lasso(alpha=0.1, max_iter=50000). - Flip the sign (multiply by -1) and report mean and standard deviation for all four in a 4-row table.
You are done when…
□ Degrees 1-15 are all evaluated; train error generally falls while validation error is U-shaped □ Underfitting and overfitting are explicitly identified □ Ridge and Lasso are both in the degree-15 comparison; the CV table has all four models □ No scaling is fitted on the full dataset before splitting (keep it inside the pipeline) □ README contains 3-4 lines of conclusions
If you get stuck
| Problem | Fix |
|---|---|
| Lasso warning | Use max_iter=50000 as in the book |
| Huge degree-15 Linear error | Expected; this IS the overfitting example |
| Unsure about the conclusion | Compare validation error and CV mean/std, not the training score |
| Leakage worry | Keep preprocessing inside the pipeline so each fold learns scaling from its own training part |
Hints
- Hint 1: Loop over
range(1, 16)and keep two error lists. - Hint 2: Build
make_pipeline(PolynomialFeatures(d), StandardScaler(),reg); best degree isnp.argmin(val_err) + 1. - Hint 3: Loop over the four CV models; sklearn gives negative scores, so put a minus sign in front.
Fill-in README
Training error kept going __ as degree increased, but validation error went down until degree and then went . This shows . At degree 15, (Ridge/Lasso) did than plain Linear because regularization . In 5-fold CV the best model was with mean error (std __).
Level 2 - Expert Challenges (optional)
- Shade “Underfit / Good / Overfit” zones with a dashed line at the best degree.
- Draw the fitted curves for degrees 1, 3 and 15 over the data.
- Try Ridge alpha = 0.01, 1, 100 and describe what happens.
- Leakage demo: scale on ALL data vs train only and document the difference.
- Learning curve: plot error against training set size.
Full code: see Solution - Day 5 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Intermediate | Book pages: 147
Goal in plain words
Learn why “99% accuracy” can be a useless score, and how to judge a model when one class is very rare (fraud). Fire alarm picture: high recall = it catches almost every fire; high precision = when it rings, there really is a fire.
Words you need
Imbalanced data, precision, recall, F1, ROC-AUC, confusion matrix, stratify (see the glossary). Random Forest = many trees voting (less wobbly). *Gradient Boosting* = trees added one by one, each fixing the last one's errors.
Level 1 - Must do
- Load
creditcard.csv(targetClass) and print the fraud ratio: about 0.17% (492 of 284,807). - Split with
train_test_split(..., test_size=0.2, stratify=y,random_state=42). - Fit
StandardScaleronX_train[["Amount","Time"]]only, then transform train and test. - Train Logistic Regression (
class_weight="balanced"), Random Forest (class_weight="balanced") and Gradient Boosting. - For each model print the confusion matrix and compute precision, recall, F1 and ROC-AUC (AUC needs
predict_proba(X_test)[:, 1]). - Put the 3 models x 4 metrics into one DataFrame.
- Answer in the README: best recall, best precision, and which model you would give a bank (3 lines).
You are done when…
□ The split uses stratify=y and the scaler is fitted on train only □ You have a 3-row x 4-metric table and one confusion matrix per model □ You can explain why accuracy alone would be misleading (it is not the headline metric) □ README answers best recall, best precision and the bank choice
If you get stuck
| Problem | Fix |
|---|---|
| Boosting is slow | Use a smaller sample (keep all fraud rows) or HistGradientBoostingClassifier |
| AUC looks wrong | Use predictproba(Xtest)[:, 1], not predict |
| Confusion matrix confusing | sklearn layout is [[TN, FP], [FN, TP]] |
| Fraud count disappears | You forgot stratify=y, or your sample dropped the fraud rows |
Hints
- Hint 1: Fraud is rare, so preserve the class ratio when splitting.
- Hint 2: Probabilities go to ROC-AUC; predicted labels go to the confusion matrix and precision/recall/F1.
- Hint 3: Loop over a dictionary of the three models: fit, predict,
predict_proba(...)[:, 1], then collect the four scores.
Fill-in README
Only __% of transactions are fraud, so a model that always says “not fraud” gets % accuracy but % recall. My best recall was (model: ). My best precision was (model: ). For a bank I would choose because missing fraud costs while a false alarm only __.
Level 2 - Expert Challenges (optional)
- Dumb baseline: show “always predict not-fraud” first (great accuracy, zero recall).
- Draw ROC and precision-recall curves for all three models.
- Threshold tuning: try 0.3 / 0.5 / 0.7 and show the precision-recall trade-off.
- SMOTE on the TRAIN set only, then compare.
- Show the top 10 Random Forest feature importances.
Full code: see Solution - Day 6 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Intermediate | Book pages: 155-176
Goal in plain words
Do four small checkpoints so every Days 7–8 idea is used once (k-NN, k-Means, PCA, embeddings), then build your first complete machine learning project: predict which phone customers will leave (churn) and explain why. A Pipeline is a conveyor belt: clean, scale, encode, predict, always in the same order, always learning only from training data.
Words you need
*k-NN, k-Means, elbow, PCA, embedding, cosine similarity, Pipeline, ColumnTransformer, stratified CV, feature importance, churn (see the glossary). Inertia* = how tight the k-Means clusters are.
Level 1 - Must do
Parts A-B - Distance + k-NN checkpoint
- By hand, for P1=(25, 6) and P2=(30, 8), compute Euclidean, Manhattan and cosine values.
- Make or reuse a tiny labeled matrix; run
StandardScalerthenKNeighborsClassifier(n_neighbors=5). - Write one sentence on why scaling changes neighbor distances.
Part C - k-Means checkpoint
- Take the Telco numeric columns
tenure,MonthlyCharges,TotalCharges(convert TotalCharges first) and scale them. - Run
KMeansfor k = 1..10 withn_init=10,random_state=42; save an elbow plot (inertia_vs k). - Choose a candidate k and record the cluster labels and centers.
Part D - PCA checkpoint
- Use the same scaled matrix; run
PCA(n_components=2). - Record
X2.shapeandexplained_variance_ratio_. - Write one sentence on what the two components mean at a high level (they are not original columns).
Part E - embeddings checkpoint
- Embed “How to reset my password”, “Best pizza recipes”, “Change account login credentials” with
all-MiniLM-L6-v2. - Embed the query “I forgot my password”, compute cosine similarity (your Days 2–3 function), find the top match.
- Record the embedding shape and the winning sentence.
Part F - Mini Project 1: Telco Customer Churn
- Load
telco.csv; print shape,info()and the churn ratio (about 27%). - Convert
TotalChargeswithpd.to_numeric(..., errors="coerce"); fill the blanks inside the pipeline (no leakage). - Drop
customerID; map Churn Yes/No to 1/0. - Split 80/20 with
stratify=y,random_state=42. - Build a
ColumnTransformer: scale the number columns, one-hot encode the text columns. - Train Logistic Regression and Random Forest, each inside a
Pipeline. - Run 5-fold stratified CV; compare recall, precision, F1 and ROC-AUC. Pick the stronger model.
- Evaluate that model on the test set once.
- Show the top features that drive churn (Random Forest importances) as a bar chart.
- Write the README: problem, dataset, approach, results, insights, how to run.
You are done when…
□ Parts A-B show distance methods need scaling; Part C has an elbow plot for k = 1..10 □ Part D records X2.shape and explained_variance_ratio_; Part E reproduces the semantic-search idea □ Telco uses Pipeline + ColumnTransformer and compares Logistic Regression vs Random Forest with 5-fold stratified CV □ Telco reports recall, precision, F1, ROC-AUC; the test set is used once after model selection □ Feature-importance chart is included and the README explains in plain words why customers leave
If you get stuck
| Problem | Fix |
|---|---|
| Telco file is not found | Rename the download to telco.csv OR change the path in pd.read_csv |
| TotalCharges is text | pd.to_numeric(errors="coerce"), then let an imputer fill the blanks inside the pipeline |
| Distance results look odd | Scale the numeric features first |
| Scores suspiciously perfect | Check for target leakage (Churn must not be in X) and keep preprocessing in the Pipeline |
| Feature names look ugly | Use pipeline.namedsteps["pre"].getfeaturenamesout() |
Hints
- Hint 1: For k-NN and k-Means, standardize before distances or cluster assignment.
- Hint 2: The elbow is
inertia_versus k; PCA exposesexplained_variance_ratio_; embeddings reuse your Days 2–3 cosine. - Hint 3: For Telco keep every preprocessing step inside
ColumnTransformer/Pipelineand do not look at test performance until the end.
Fill-in README
Checkpoints: scaling matters for k-NN because __. My k-Means elbow suggests k = . PCA kept of the variance in 2 components. The embedding winner was . Telco: customers, % churn. Best model with ROC-AUC and recall on the test set. Customers with contracts, tenure and internet are most likely to leave. Recommendation: __.
Level 2 - Expert Challenges (optional)
- EDA first: churn by contract type, tenure histogram by churn, monthly charges by churn.
- Add Gradient Boosting and report mean +/- std from CV.
GridSearchCVon the Random Forest.- Save the pipeline with joblib and write a
predict_one(customer)example. - Business value: estimate the money saved by contacting the riskiest 20%.
Full code: see Solution - Days 7–8 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Intermediate | Book pages: 201-210
Goal in plain words
Build a tiny neural network using only NumPy so nothing is hidden. After this, PyTorch will feel like a shortcut, not magic. Forward pass = make a guess. Loss = how wrong. Backprop = who is to blame. Update = fix the weights a little.
Words you need
*Neuron, activation (ReLU, sigmoid, tanh), forward pass, loss (BCE), backpropagation, hidden layer, He initialization, gradient check* (see the glossary).
Level 1 - Must do
- Make the Moons data:
make_moons(n_samples=1000, noise=0.2,random_state=42), split 80/20 (random_state=42), reshape labels to (n, 1). - Write
relu,relu_grad,sigmoidandbce(with a tiny epsilon solog(0)never happens). - Initialize W1 with He initialization (
randn * sqrt(2/n_in)), biases at zero, W2 with the book's small-random pattern. - Loop: forward (layer 1, ReLU, layer 2, sigmoid), loss, backward (
dW2, db2, dW1,db1), update (W -= lr * dW). - Record train and test loss and accuracy; plot the loss curve.
- Gradient check before updating weights: compare the analytic
dW1[0,0]with(L(w+eps) - L(w-eps)) / (2*eps). - Required experiments: hidden size 2, 4, 16, 64; learning rate 0.001, 0.01, 0.1, 1.0; ReLU vs tanh. Record each in a table.
- Remove the hidden layer and report the accuracy (the linear/logistic baseline).
- Write observations for every experiment in the README (not just a screenshot of numbers).
You are done when…
□ Moons uses 1,000 samples and noise=0.2; loss decreases over training □ Numerical and analytic gradients agree closely (about 6 decimals in the book example) □ Hidden size, learning rate and tanh/ReLU experiments are recorded, with a README observation for each □ Without the hidden layer, accuracy drops to about 85% as the book explains □ You can explain forward and backward in your own words
If you get stuck
| Problem | Fix |
|---|---|
| Loss is nan | Lower the learning rate; add epsilon inside the log; avoid log(0) |
| Accuracy stays near 50% | Check y has shape (n, 1), not (n,) |
| Gradient mismatch | Check matrix shapes and the ReLU derivative; use the central difference exactly |
| Wrong gradient shape | A gradient has the same shape as its parameter (dW1 is (2, 16)) |
Hints
- Hint 1: Write the shapes on paper first: X (n,2), W1 (2,16), hidden (n,16), W2 (16,1), output (n,1).
- Hint 2: Start backward at
dZ2 = A2 - y, then walk back one layer at a time; ReLU passes gradient only where the input was positive. - Hint 3: For the gradient check, nudge
W1[0,0]by +eps and -eps, recompute the loss both times, and compare with the analytic value.
Fill-in README
My network has __ inputs, hidden neurons and output. It reached % test accuracy. The loss went from to . Gradient check: analytic , numeric . Backpropagation means . Without a hidden layer I got about % because the boundary can only be a . Bigger hidden size ; a learning rate of 1.0 ; tanh vs ReLU __.
Level 2 - Expert Challenges (optional)
- Plot the decision boundary the network learned.
- Wrap everything in a
NeuralNetclass with.fit()and.predict(). - Add a second hidden layer and generalize backprop.
- Keep a debug journal: every bug and how you fixed it.
Full code: see Solution - Days 9–10 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Intermediate | Book pages: 212-233
Goal in plain words
Redo the Days 9–10 network with PyTorch, which computes gradients for you, then compare six optimizer runs and save your model.
Words you need
*Tensor, Dataset, DataLoader, nn.Module, autograd, optimizer (SGD, Adam), batch, state_dict* (see the glossary). The 5-line step to memorize: zero_grad(), forward, loss, backward(), step().
Level 1 - Must do
- Make 2,000 Moons samples (
noise=0.25), 80/20 split; featuresfloat32, labelsfloat32with shape (B, 1). - Wrap in
TensorDataset+DataLoader: trainbatch_size=32, shuffle=True; validationbatch_size=256, shuffle=False. - Model:
nn.Sequential(nn.Linear(2,16), nn.ReLU(), nn.Linear(16,1)); loss:nn.BCEWithLogitsLoss(). - Training loop in the book order:
zero_grad→ forward → loss →backward→step, withmodel.train(). - Validation with
model.eval()andtorch.no_grad().
Required: the six-run optimizer experiment
- Run all 6 combinations: SGD and Adam, each with learning rate 0.1, 0.01, 0.001 (fresh model per run).
- Record train loss and validation loss by epoch, plus final validation accuracy, for every run.
- Plot all six runs together; fill the 6-row table (optimizer, LR, final train loss, final val loss, val acc).
- Explain in plain English: speed of convergence, sensitivity to learning rate, any instability.
- Save the selected model:
torch.save(model.state_dict(), "model.pt").
You are done when…
□ All 6 runs are present (SGD x 3 rates, Adam x 3 rates) with train and validation loss logged □ All six curves are plotted together □ model.train() / eval() and torch.no_grad() are used in the right places □ state_dict is saved □ README explains what changed with optimizer and learning rate
If you get stuck
| Problem | Fix |
|---|---|
| Loss does not change | Did you call zero_grad(), backward() and step()? |
| Shape error in the loss | Make labels .float().view(-1, 1) for BCEWithLogitsLoss |
| Validation looks random | Use model.eval() and torch.no_grad() |
| Device mismatch | Move both model and batches to the same device |
| Problem | Fix |
|---|---|
| Training gets worse | Gradients accumulate unless zero_grad() is called each batch |
Hints
- Hint 1: Follow the order: Tensor → Dataset → DataLoader → Model → Loss → Optimizer → Training loop → Validation.
- Hint 2:
BCEWithLogitsLossalready contains the sigmoid, so the model's last layer outputs raw logits. - Hint 3: Use a fresh model per combination (reset the seed) so the six runs compare fairly.
Fill-in README
PyTorch handles ___ automatically with `loss.backward()`. `zerograd() is needed because ____. model.eval()` is used during validation because __. SGD was sensitive to learning rate than Adam; the most stable run was . My saved weights are in __.
Level 2 - Expert Challenges (optional)
- Count parameters:
sum(p.numel() for p in model.parameters()). - Early stopping that restores the best state.
- Run on CUDA when available.
- Rewrite the model as
class Net(nn.Module).
Full code: see Solution - Day 11 in the Solutions Appendix. Try Level 1 and the hints first.
Note: the book's example code (p. 228) runs Adam at 0.0001, 0.001 and 0.01, while its assignment spec (p. 234) asks for 0.1, 0.01 and 0.001 for both optimizers. This guide follows the spec; if your results differ from p. 228, that is why.
Difficulty: Intermediate | Book pages: 235-252
Goal in plain words
Teach a computer to read handwritten digits with two kinds of networks and find out which is better. An MLP sees one long list of pixels; a CNN scans small patches like a magnifying glass, so it understands shapes.
Words you need
MLP, CNN, dropout, early stopping, batch, epoch, confusion matrix, logits (see the glossary). Weight sharing = the same small filter is reused everywhere in the image.
Level 1 - Must do
- Load MNIST with torchvision and normalize (mean 0.1307, std 0.3081).
- Split the 60k training set into 55k train / 5k validation with
manual_seed(42); keep the 10k test set untouched. - MLP: Flatten → 784→256 → ReLU → Dropout(0.3) → 256→128 → ReLU → Dropout(0.3) → 128→10.
- Small CNN: Conv(1→16, k3, p1) → ReLU → MaxPool(2) → Conv(16→32, k3, p1) → ReLU → MaxPool(2) → Flatten(1568) → Linear(128) → ReLU → Dropout → Linear(10).
- Train both with
CrossEntropyLossand the 5-line step; track train/validation loss and validation accuracy each epoch. - Use early stopping and restore the best weights; then test both once on the test set.
Required: comparison and error analysis
- Report parameters, validation accuracy, test accuracy and epochs stopped for MLP and CNN.
- Save the train/validation loss curves for both models, and the CNN test confusion matrix.
- Display and analyze at least 5 wrong predictions (the book shows 8).
- Write why the CNN and MLP behave differently: spatial structure + weight sharing vs flattening.
You are done when…
□ Split is exactly 55k / 5k / 10k; dropout is in both the MLP and the CNN classifier □ Early stopping restores the best weights; the test set is used only after training □ CNN confusion matrix is saved; at least 5 mistakes are shown □ MLP is around 97-98%, CNN around 99%+; both are in the README table □ README explains spatial structure / shared filters as the reason for the difference
If you get stuck
| Problem | Fix |
|---|---|
| “mat1 and mat2 shapes cannot be multiplied” | Wrong flatten size; print the shape after the conv layers (should be 1568) |
| “Expected 4D input” | Images need shape (B, 1, 28, 28) |
| CrossEntropy complains | Labels must be integer class numbers with shape (B,); do not add softmax yourself |
| Validation fluctuates | Check model.eval() and dropout behavior |
| Forgot best weights | Restore the best_state saved by early stopping before testing |
Hints
- Hint 1: The MLP starts with
nn.Flatten()because the image must become 784 features. - Hint 2: Two padded 3x3 conv/pool blocks make 28 → 14 → 7, so flatten = 32 7 7 = 1568.
- Hint 3: Use
test_loaderonly after training and validation decisions are complete; never tune on test.
Fill-in README
Split: train __ / val / test . MLP: parameters, test accuracy . CNN: parameters, test accuracy . The CNN performed because it keeps the structure of the image. Dropout helps by . The digits most often confused were and __.
Level 2 - Expert Challenges (optional)
- Visualize the first-layer CNN filters.
- Small data augmentation (random rotations): does accuracy improve?
- Add BatchNorm and compare.
- Demo cell: load a digit you draw yourself and predict it.
Full code: see Solution - Day 12 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Advanced | Book pages: 266-284
Goal in plain words
Understand the idea behind ChatGPT, Claude and other language models: every word looks at the other words and decides which are important. Library picture: your Query is what you are looking for, each book's Key is its label, the Value is the content inside.
Words you need
*Attention, Q/K/V, softmax, causal mask, multi-head, positional encoding, residual, LayerNorm (see the glossary). Formula: Attention = softmax( Q × K-transpose / sqrt(d_k) ) × V*.
Level 1 - Must do
- Write a
SelfAttentionmodule with threenn.Linear(d_model, d_k,bias=False)layers for Q, K, V. - In
forward:scores = Q @ K.transpose(-2, -1) / sqrt(d_k), row-wise softmax (dim=-1), returnweights @ Vand the weights. - Test with
x = torch.randn(1, 6, 16)(1 sentence, 6 words, 16 numbers each);d_model = d_k = 16. - Check output shape (1, 6, 16), weights shape (1, 6, 6), and that every row of the weights sums to about 1.
- Save a heatmap with the six labels
The cat sat on the mat.
Required: causal-mask check
- Build
mask = torch.tril(torch.ones(T, T)).unsqueeze(0)and runattn(x,mask=mask). - Confirm everything above the diagonal (future tokens) is exactly zero; record it in the README.
Required: Transformer block explanation
- Draw the block: Multi-Head Attention → Add/Residual → LayerNorm → FFN → Add/Residual → LayerNorm.
- Label the key tensor shapes; explain Q, K and V in your own words (do not copy the book).
You are done when…
□ Q, K, V are each (B, T, d_k); QK^T is (B, T, T); rows of the softmax weights sum to about 1 □ Causal mask makes all future-token weights zero □ Heatmap is saved and analyzed in 5 lines; the Transformer block diagram is included □ README explains Q/K/V in your own words
If you get stuck
| Problem | Fix |
|---|---|
| Shape error in @ | Transpose K with K.transpose(-2, -1) |
| Rows do not sum to 1 | Apply softmax on the last dimension: F.softmax(scores, dim=-1) |
| Heatmap looks random | Normal! Untrained weights have no meaning; it only proves the code runs |
| Mask broadcasts wrongly | Use a lower-triangular mask shaped (1, T, T) |
| Future weights non-zero | Apply the mask to the scores BEFORE softmax, using masked_fill(..., -inf) |
Hints
- Hint 1: Write the shape after every major line: X, Q/K/V, scores, weights, out.
- Hint 2: The formula is exactly
softmax(QK^T / sqrt(d_k)) V. - Hint 3: The causal mask goes on the scores before softmax;
-infbecomes zero probability after softmax.
Fill-in README
Attention lets each word __. Q is , K is , V is _. We divide by sqrt(dk) because __. Each row of the attention matrix sums to because of . With the causal mask the largest future weight is . Multi-head attention helps because __.
Level 2 - Expert Challenges (optional)
- Load pretrained BERT and plot real attention for a sentence; write 4-5 lines on what “it” attends to.
- Implement 4-head multi-head attention and concatenate.
- Repeat the small numeric example from book p. 265 with a calculator.
- Build the full Transformer block at the concept level shown in the book.
Full code: see Solution - Day 13 in the Solutions Appendix. Try Level 1 and the hints first.
Difficulty: Intermediate | Book pages: 289-292
Goal in plain words
Rebuild one model by yourself from a blank file, explain it clearly, make it reproducible and publish it. This is your portfolio piece. The 15-day story: DATA → MODEL → LOSS → OPTIMIZE → EVALUATE → fix overfitting → repeat.
Words you need
Capstone, seed, reproducible, requirements.txt, .gitignore, error analysis (see the glossary). Feynman test = explain it so simply that a friend with no ML background can follow.
Choose your path (pick exactly one)
| Path | Project | Difficulty | Good if… |
|---|---|---|---|
| A | Linear or logistic regression from scratch (NumPy) | Beginner / Intermediate | You want strong fundamentals |
| B | 2-layer neural network from scratch (NumPy) | Intermediate | You loved Days 9–10 |
| C | MNIST CNN in PyTorch | Intermediate | You want practical deep learning |
| D | Self-attention + tiny text classifier / mini Transformer block | Advanced | You want GenAI readiness |
The book says: “Recommended for your GenAI goal: C or D. If short on time: C.” If unsure, pick C.
Level 1 - Must do
Step 1 - Rebuild from a blank file (about 2 hours)
- Close all notes and videos and start from a blank file.
- Write the skeleton in comments first: imports/seed/device → data → model → loss/optimizer → train/validation → test → plots → save model.
- Fill in each part yourself. Stuck for 10 minutes? Look up only the one function you need.
- Keep a list called “Things I had to look up” - it is honest and valuable.
Step 2 - Get results
- Final test result.
- Loss curve image and confusion matrix image (when they fit your model) saved to
results/.
Step 3 - Explain it in 6 short parts (3 to 6 simple sentences each)
| # | Part | Starter |
|---|---|---|
| 1 | Problem | “This project teaches a computer to __ because __.” |
| 2 | Input / Output | “The input is __ with shape . The output is __.” |
| 3 | How the model works | “The data goes through __, then , then __.” |
| 4 | Loss function | “I used __ loss because it __.” |
| 5 | Training | “I trained with __ optimizer, learning rate , batch size , for __ epochs.” |
| 6 | Evaluation | “The model got __ accuracy. It struggled with . Next time I would __.” |
Step 4 - Tidy the code □ Meaningful names (train_loader, not dl1) and a short docstring on each function □ Seeds set, relative paths only; Restart and Run All works □ requirements.txt created (torch, numpy, matplotlib) □ .gitignore includes data/ , *.pt, __pycache__/, .ipynb_checkpoints/
Step 5 - README (use the template in the extras section) Problem, dataset, model/approach, training setup, results table + 2 images, failure cases, what I learned, things I had to look up, how to run, future improvements.
Step 6 - Publish □ Push to GitHub with all 10 day folders □ Update the root README table (Day, Topic, What I built, Key result)
You are done when…
□ Rebuild started from a blank file; seed set; results reproducible; test set not used for tuning □ README has results, plots, failure cases, run instructions and the six-part explanation □ Code has no absolute paths; repository contains all 10 day folders and is on GitHub □ You told someone about it (post, friend or blog)
If you get stuck
| Problem | Fix |
|---|---|
| Don't know where to start | Copy the 8 skeleton comments and fill one at a time |
| Copied tutorial | Delete it and rebuild the skeleton from memory |
| README has no results | Add the result table and plots before publishing |
| Problem | Fix |
|---|---|
| Only accuracy reported | Use the metric and error analysis taught by your chosen path |
| Notebook is messy | Restart & Run All before pushing |
| Large files committed | Use .gitignore and download instructions instead |
Hints
- Hint 1: Start with the skeleton and fill one section at a time.
- Hint 2: Use the exact model/data pattern from the book day you chose (Day 4, 6, 8 or 9).
- Hint 3: Explain every part in plain language; the Feynman test is required by the book.
Fill-in README
This project teaches a computer to __ because . The input is with shape ; the output is . I used loss because it . I trained with , learning rate , batch size , for epochs. The model got accuracy and struggled with . Things I had to look up: __.
Level 2 - Expert Challenges (optional)
- Short LinkedIn/blog post following the book template.
- Add one more model or a hyperparameter comparison.
- A small ablation that stays within the book's concepts.
- CNN path: filter visualization or data augmentation.
Skeleton and checkpoints: see Solution - Days 14–15 in the Solutions Appendix.