Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You can build a small image classifier in Keras by loading Fashion MNIST, scaling its pixel values, and stacking a flattening layer with two dense layers. The example below maps each 28 × 28 grayscale image to one of 10 clothing categories. It is an educational baseline—not a tuned or production image-recognition system—and its accuracy will depend on your training choices and run.

What this neural network does

Fashion MNIST contains 70,000 grayscale clothing images, each 28 × 28 pixels, divided into 60,000 training images and 10,000 evaluation images in the TensorFlow tutorial’s dataset split. Each image has one label from 10 categories. The model learns a mapping from the pixel values to scores for those categories; the TensorFlow tutorial presents the dataset as a beginner classification exercise, not as representative of every image-recognition task (TensorFlow: Basic classification).

This is a straight stack of layers: data enters at one end and passes through each layer in order. Keras describes this arrangement as appropriate when each layer has one input tensor and one output tensor. If your model needs multiple inputs or outputs, shared layers, or branching connections, use the Functional API or model subclassing instead (Keras: The Sequential model).

Load and prepare the data

The example uses TensorFlow’s bundled Keras API, tf.keras. In a hosted notebook, TensorFlow tutorials can be opened in Google Colab, which the tutorials page describes as requiring no setup (TensorFlow tutorials). If you work locally, use a Python environment with a compatible TensorFlow installation; setup details depend on your operating system and chosen release.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import tensorflow as tf

# Load images and integer labels.
(train_images, train_labels), (test_images, test_labels) = (
    tf.keras.datasets.fashion_mnist.load_data()
)

print(train_images.shape)  # (60000, 28, 28)
print(test_images.shape)   # (10000, 28, 28)
print(train_labels[0])    # An integer from 0 through 9

# Convert pixel values from 0–255 to 0–1 in both splits.
train_images = train_images.astype("float32") / 255.0
test_images = test_images.astype("float32") / 255.0

Each image is a two-dimensional grid of pixel intensities. Scaling both training and test images by the same factor gives the model consistently formatted inputs. The labels are integers, so the loss used below must be configured for integer class labels rather than one-hot vectors.

Build the Sequential model

Use an explicit input declaration so Keras knows the expected image shape before training and can build the model for a summary. The layers then transform each image from a 28 × 28 grid into a vector, compute hidden features, and produce one score per category.

model = tf.keras.Sequential([
    tf.keras.Input(shape=(28, 28)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation="relu"),
    tf.keras.layers.Dense(10)  # Raw scores, or logits
])

model.summary()

What each layer contributes

  • Input(shape=(28, 28)) declares the shape of one image, excluding the batch dimension.
  • Flatten reshapes each 28 × 28 image into 784 values. It has no learned weights; it only changes the arrangement of the data.
  • Dense(128, activation="relu") connects each of the 784 input values to 128 learned units. The weights and biases are trained, and ReLU introduces a non-linear transformation.
  • Dense(10) produces 10 learned output scores, one for each class. With no activation specified, these outputs are logits, not probabilities.

The 128 hidden units and 10 output scores follow the TensorFlow tutorial’s illustrative structure; 128 is a teaching choice, not a claim that this is the optimal model size (TensorFlow: Basic classification).

Rank #2
msi Gaming GeForce RTX 3060 Ventus 2X 12G OC V1 Graphics Card - 15 Gbps GDRR6 Boost Clock: 1807 MHz 192-Bit HDMI/DP PCIe 4 Torx Twin Fan Ampere
  • Chipset: NVIDIA GeForce RTX 3060
  • Video Memory: 12GB GDDR6
  • Memory Interface: 192-bit
  • Output: DisplayPort x 3 (v1.4a) / HDMI 2.1 x 1.Avoid using unofficial software
  • Digital maximum resolution: 7680 x 4320

Compile and train the network

compile configures training: the optimizer updates the model’s weights, the loss measures prediction error, and the metric provides a readable progress measure. Because the final layer returns logits and the labels are integer class IDs, use sparse categorical cross-entropy with from_logits=True.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
model.compile(
    optimizer="adam",
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=["accuracy"]
)

history = model.fit(
    train_images,
    train_labels,
    epochs=10,
    validation_split=0.1
)

fit trains on the supplied training data. Here, Keras holds out 10% of that training data for validation, so it can report validation metrics during development. The 10 epochs are an example setting, not a promised performance target. Keras’s built-in training APIs accept in-memory NumPy arrays as shown here, as well as supported dataset and other input formats (TensorFlow: Training and evaluation with built-in methods).

Keep validation and final testing distinct: use validation results while making development choices, then reserve the test split for evaluation after those choices are made. Repeatedly choosing settings based on test results makes that split less useful as an independent check.

Evaluate on held-out test images

Call evaluate on the test split once you are ready to assess the trained model. It returns the configured loss and metrics, including accuracy here. Treat the reported value as the result of your own run rather than a guaranteed accuracy figure; training settings and environment can affect it.

test_loss, test_accuracy = model.evaluate(test_images, test_labels, verbose=2)
print("Test loss:", test_loss)
print("Test accuracy:", test_accuracy)

The test images were scaled in the same way as the training images. Passing unscaled 0–255 pixels at evaluation time would not match the input preprocessing used to train this model.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Predict a category for a new image

predict returns the model’s output scores. Since the final layer emits logits, apply softmax to turn the 10 scores into values that sum to 1 and can be interpreted as class probabilities. Do not apply softmax and then feed those probabilities into a loss configured with from_logits=True; the configuration must match the model’s output.

logits = model.predict(test_images[:1], verbose=0)
probabilities = tf.nn.softmax(logits, axis=1)

predicted_class = int(tf.argmax(probabilities[0]))
confidence = float(tf.reduce_max(probabilities[0]))

print("Predicted class:", predicted_class)
print("Probability for predicted class:", confidence)

The class ID is an integer from 0 through 9. For a human-readable category name, map it using the dataset’s documented label order in the TensorFlow Fashion MNIST tutorial. The printed probability is the model’s normalized score, not proof that its prediction is correct.

When this baseline is not enough

This dense model treats an image as a vector after flattening, so it does not preserve the grid as an explicit spatial structure in subsequent layers. Convolutional and pooling layers are common alternatives for image classification; TensorFlow’s image-classification tutorial demonstrates a model built with Conv2D and pooling blocks (TensorFlow: Convolutional neural network). Use the simple dense network to learn the Keras workflow, then choose a more suitable architecture for the actual task and its requirements.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.