C.W.K.
Stream
Lesson 05 of 07 · published

Building a Classifier: MNIST

~10 min · sequential

Level 0Keras Apprentice
0 XP0/97 lessons0/20 achievements
0/120 XP to next level120 XP to go0% complete

The whole pipeline in one screen

This is the canonical deep-learning "Hello World": classify handwritten digits 0–9 from the MNIST dataset. What makes it worth your time isn't the dataset — it's that the full Keras workflow fits on one screen, and every project you ever build reuses these same six steps in the same order (the Code section is the complete script).

  1. Loadkeras.datasets.mnist.load_data() hands back train/test splits as NumPy arrays, no download plumbing.
  2. Normalize — divide pixels by 255 so values land in [0, 1]. Skip this and training is sluggish or unstable; it's the single most common omission.
  3. Build — the Sequential stack from the last lessons: Flatten → Dense(relu) → Dropout → Dense(softmax).
  4. Compile — wire up the optimizer (adam), the loss (sparse_categorical_crossentropy, because labels are plain integers), and the metric to watch.
  5. Trainfit() with a validation_split so you watch generalization, not just memorization.
  6. Evaluate — score on the held-out test set you never trained on.

Five epochs gets you ~97–98% test accuracy. The loss choice in step 4 is the subtle one: sparse_categorical_crossentropy expects integer labels like 3, whereas categorical_crossentropy expects one-hot vectors like [0,0,0,1,0,...]. Pick the wrong one and Keras throws a shape error — which is exactly the failure mode the exercise asks you to trigger on purpose.

Code

Complete MNIST classifier: load → normalize → build → compile → fit → evaluate·python
import keras
from keras import layers

# 1. Load data
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# 2. Normalize pixel values to [0, 1]
x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0

# 3. Build model
model = keras.Sequential([
    keras.Input(shape=(28, 28)),
    layers.Flatten(),
    layers.Dense(128, activation="relu"),
    layers.Dropout(0.2),
    layers.Dense(10, activation="softmax"),
])

# 4. Compile
model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"],
)

# 5. Train
model.fit(x_train, y_train, epochs=5, validation_split=0.1)

# 6. Evaluate
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test accuracy: {test_acc:.4f}")  # ~97.5%

External links

Exercise

Implement the MNIST classifier above. Achieve ≥97% test accuracy. Now break it on purpose: use 'categorical_crossentropy' (wrong) and watch the error. The lesson is in the failure mode.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.