Metrics vs loss — the line that confuses everyone
Loss and metrics look similar in the compile() call, but they play opposite roles. The loss is what training minimizes — it must be differentiable so gradients can flow. Metrics are pure observers: they're computed every step, reported in the log, and never touch the gradient. That's exactly why accuracy can be a metric but never a loss — it's a step function, non-differentiable, useless to the optimizer but perfect for telling a human how the model is doing.
You pass metrics as a list, mixing string shortcuts with instances. Use the instance form when you need to name a metric (so it reads cleanly in the log) or configure it. The Code section stacks the metrics you'll actually want on a classifier — accuracy plus the precision/recall/AUC/F1 family that tells you where the model is wrong, not just how often.
Watch validation, and build your own when you must
Every metric reported during fit() gets a val_ twin once you pass validation data — accuracy and val_accuracy. The training metric tells you the model is fitting; the validation metric tells you it's generalizing, and the gap between them is your overfitting gauge. When no built-in captures what you care about, subclass keras.metrics.Metric and implement three methods: update_state() accumulates over the batch, result() returns the current value, and reset_state() clears it at each epoch boundary.