Your model's X-ray
model.summary() prints the architecture as a table — layer names, output shapes, per-layer parameter counts, and trainable vs non-trainable totals. It's the first thing you run after building and before you ever call .compile(), because it surfaces structural mistakes in seconds that would otherwise cost you an entire training run to discover.
Read the table top to bottom and three things jump out (the Code section shows a real example). A (None, 128) output shape means the batch dimension is left as None — it gets filled in at fit time. A param count of 0 means a layer with no learnable weights, like Flatten or Dropout; that's expected, not a bug. And a non-zero non-trainable count points at frozen layers or BatchNormalization's moving statistics.
Where the parameter numbers come from
The param column isn't magic — you can derive it by hand, and doing so once cements how a layer actually works. A Dense layer mapping input size n to output size m has n × m weights plus m biases. So Dense(128) fed a 784-vector is 784 × 128 + 128 = 100,480 parameters. If your hand math and summary() disagree, your mental model of the shapes is wrong — and that's exactly the bug you want to catch before training, not after.