How to show model summary in Keras

A Keras model can look correct in code while a hidden shape or parameter-count problem remains hard to see. The model.summary() table exposes the layer stack, output shapes, and parameter totals before training, plotting, or export.

The model must be built before summary() can print a complete table. Functional models and Sequential models that start with keras.Input() know their input shape immediately, while subclassed models usually need a sample call before inspection.

Use the summary to confirm named layers, batch dimensions, zero-parameter layers, and trainable parameter totals. A short script keeps the Keras backend explicit, builds a small Functional model, prints the table, and captures the same output with print_fn for automated checks.

Steps to show a Keras model summary:

  1. Create show_model_summary.py with backend selection and the Keras import.
    show_model_summary.py
    import os
     
    os.environ["KERAS_BACKEND"] = "jax"
     
    import keras

    Set KERAS_BACKEND before importing keras. Use tensorflow or torch when those backend packages are installed for the project.
    Related: How to set the Keras backend
    Related: How to install Keras with pip

  2. Add a Functional model with an explicit input shape and stable layer names.
    inputs = keras.Input(shape=(32,), name="features")
    x = keras.layers.Dense(16, activation="relu", name="feature_encoder")(inputs)
    x = keras.layers.Dropout(0.2, name="regularizer")(x)
    outputs = keras.layers.Dense(3, activation="softmax", name="class_scores")(x)
    model = keras.Model(inputs=inputs, outputs=outputs, name="credit_score_classifier")

    Passing keras.Input() builds the graph with known symbolic shapes, so summary() can print output shapes without a training batch.

  3. Print the model summary with a width that fits the terminal.
    model.summary(line_length=92)

    If summary() raises ValueError on an unbuilt model, add an input shape to the model or call the model once with sample input before printing the table.

  4. Capture the summary when a script, test, or notebook cell needs the text.
    summary_lines = []
    model.summary(
        line_length=92,
        print_fn=summary_lines.append,
    )
    summary_text = "\n".join(summary_lines)

    print_fn receives each rendered summary line. Appending those lines keeps the normal table format without redirecting stdout.

  5. Check that the expected layer and parameter lines are present.
    assert "feature_encoder" in summary_text
    assert "Total params" in summary_text
    assert model.built is True
     
    print("model built:", model.built)
    print("summary contains feature_encoder:", "feature_encoder" in summary_text)
    print("summary contains Total params:", "Total params" in summary_text)
  6. Run the script and confirm the table includes layer names, output shapes, and parameter counts.
    $ python show_model_summary.py
    Model: "credit_score_classifier"
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
    ┃ Layer (type)                           ┃ Output Shape                 ┃          Param # ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
    │ features (InputLayer)                  │ (None, 32)                   │                0 │
    ├────────────────────────────────────────┼──────────────────────────────┼──────────────────┤
    │ feature_encoder (Dense)                │ (None, 16)                   │              528 │
    ├────────────────────────────────────────┼──────────────────────────────┼──────────────────┤
    │ regularizer (Dropout)                  │ (None, 16)                   │                0 │
    ├────────────────────────────────────────┼──────────────────────────────┼──────────────────┤
    │ class_scores (Dense)                   │ (None, 3)                    │               51 │
    └────────────────────────────────────────┴──────────────────────────────┴──────────────────┘
     Total params: 579 (2.26 KB)
     Trainable params: 579 (2.26 KB)
     Non-trainable params: 0 (0.00 B)
    model built: True
    summary contains feature_encoder: True
    summary contains Total params: True