How to create a combined tf.keras model with conditional evaluation of sub-models
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
Combined tf.keras models become useful when one network should handle one kind of input and another network should handle a different kind. The important design choice is deciding whether the branch condition applies to the whole batch or to each example individually, because TensorFlow handles those two cases differently.
Build the Sub-Models First
A conditional model is easier to reason about when each branch is a normal Keras model with a clear input shape and output shape. Start with sub-models that can already run on their own.
Both branches return a single score, so they can be swapped in and out by a routing step without changing the downstream shape.
Use tf.cond for Whole-Batch Decisions
If the routing rule chooses one branch for the entire batch, use tf.cond inside a subclassed model. This is the closest match to ordinary conditional execution.
This works because there is one condition for the whole tensor. It is not appropriate when different rows in the same batch should go to different branches.
Route Individual Examples One Row at a Time
Per-example routing requires a different pattern. One practical option is to route each row through a branch with tf.map_fn, then stack the outputs back into a single tensor.
The branch outputs keep the same final shape, while the internal routing remains flexible. This pattern is more verbose, but it models true per-example routing rather than pretending a batch-wide condition solves it.
Compile and Train Like a Normal Keras Model
Once the routing logic is inside call, the outer model can still use the normal Keras training flow.
That said, hard routing introduces optimization tradeoffs. If one branch is selected much more often than the other, the neglected branch may train poorly. In those cases, a learned gate or a softer mixture-of-experts design can behave better.
Common Pitfalls
- Using a Python
ifon a tensor insidecall, which fails in graph execution because TensorFlow needs symbolic control flow. - Sending branches with different output shapes into the same downstream pipeline, which makes the combined model impossible to use consistently.
- Assuming
tf.condgives per-example routing when it only selects one branch for the current tensor condition. - Training with data that almost never activates one branch, leaving that sub-model effectively untrained.
- Forgetting that hard routing can make debugging harder because different inputs exercise different parameter sets.
Summary
- Build each branch as a normal Keras model first.
- Use
tf.condwhen one decision applies to the whole batch. - Use masks and scatter updates when each example needs its own branch.
- Keep branch output shapes compatible so the outer model remains usable.
- Watch the training distribution so both branches receive enough signal.
Related reading
- How to create a keras layer with a custom gradient in TF2.0?
- How to create a keras layer with a custom gradient in TF2.0?
- How to create a Rotation Matrix in Tensorflow
- How to create a sparse layer in Keras i.e. not all neurons are connected to each other?
- How to create a neural network for regression?
- How to create a new gym environment in OpenAI?
- How to create a tensorflow serving client for the 'wide and deep' model?
- How to create a Tensorflow Tensorboard Empty Graph
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.