Simple Multilayer Perceptron model does not converge in TensorFlow
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When a simple MLP fails to converge in TensorFlow, the problem is usually not that the model is too small. More often, the issue is a mismatch between data, labels, output layer, and loss function, or an optimization setup that makes learning unstable.
Start with a small correct baseline
Before tuning layers or activations, make sure you can train a minimal model with a sensible configuration. For binary classification, a reliable baseline looks like this:
This does not guarantee good accuracy on real data, but it does give you a reference point. If your training code is very different from this baseline, simplify it until you know the training pipeline is logically correct.
Make the output layer match the loss
One of the most common convergence failures is using an inconsistent output-loss pair.
For binary classification, typical choices are:
- one output unit with
sigmoidandbinary_crossentropy - one linear output with
BinaryCrossentropy(from_logits=True)
For multiclass classification, typical choices are:
- '
softmaxwithcategorical_crossentropyfor one-hot labels' - '
softmaxwithsparse_categorical_crossentropyfor integer labels'
If these pieces do not match, training can run without crashing while still learning almost nothing.
Scale the input features
MLPs are very sensitive to feature scale. If one input column is between 0 and 1 and another is in the millions, gradient updates become hard to interpret and optimization slows down or becomes unstable.
A simple normalization pass often helps immediately:
Train the same model on x_scaled and compare the loss curve. For tabular data, feature scaling is often more important than adding extra hidden layers.
Check the learning rate before changing the architecture
If the learning rate is too high, the loss can jump around or diverge. If it is too low, the loss may look flat and training seems stuck. Do a small controlled experiment before changing the network depth:
If training becomes stable after lowering the learning rate, the architecture was probably not the real issue.
Verify labels and shapes explicitly
TensorFlow can sometimes broadcast arrays in ways that let code run even though the setup is logically wrong. Inspect your training arrays directly:
For a single sigmoid output, labels shaped like n x 1 with float32 values are a clean default. If your labels are integers for a multiclass task, make sure the loss function expects integer class indices.
Overfit a tiny subset on purpose
One of the best debugging tests is to train on a tiny subset and see whether the model can overfit it:
If the network cannot fit a tiny subset, the training setup is usually broken. That points you back toward labels, loss configuration, data scaling, or optimizer settings rather than model capacity.
Common Pitfalls
- Changing model depth before checking the loss function, label encoding, and feature scaling.
- Using an output layer that does not match the selected loss.
- Training on unscaled tabular features and assuming the optimizer will handle every magnitude difference.
- Looking only at accuracy instead of following training and validation loss.
- Ignoring the tiny-subset overfit test, which often exposes configuration bugs quickly.
Summary
- Most MLP convergence failures in TensorFlow come from setup errors rather than insufficient complexity.
- Match the output layer, label encoding, and loss function carefully.
- Normalize features before spending time on architecture changes.
- Check the learning rate and use a tiny-subset overfit test to isolate broken training setups.

