Keras
TensorFlow
Model Conversion
Neural Networks
Machine Learning

Calling a Keras model on a TensorFlow tensor but keep weights

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Calling a Keras model on a new TensorFlow tensor does not reset or lose weights by default. In most workflows, you can treat a model like a layer and reuse it inside a bigger model while keeping the same parameters. The important part is understanding weight sharing versus cloning so you control training behavior intentionally.

Calling a Model on a Tensor Shares the Same Weights

A compiled or loaded Keras model is callable. When you pass a tensor through it, Keras executes the existing layer graph and reuses the same variables.

python
1import tensorflow as tf
2
3base = tf.keras.Sequential(
4    [
5        tf.keras.layers.Input(shape=(8,)),
6        tf.keras.layers.Dense(16, activation="relu"),
7        tf.keras.layers.Dense(4, activation="relu"),
8    ],
9    name="base_model",
10)
11
12x = tf.random.normal((2, 8))
13y = base(x)
14print(y.shape)
15print(len(base.trainable_variables))

No new independent weights are created just because you called base(x).

To verify sharing, compare variable object identity when reusing in another graph.

python
1inp = tf.keras.Input(shape=(8,))
2out = base(inp)
3head = tf.keras.layers.Dense(1)(out)
4wrapped = tf.keras.Model(inp, head)
5
6print(base.trainable_variables[0] is wrapped.layers[1].trainable_variables[0])

This prints True, confirming shared variables.

Freeze or Fine Tune Reused Weights

When using a pretrained model, you often need one of two modes:

  1. freeze base layers and train only new head,
  2. unfreeze some layers for fine tuning.

Freeze mode:

python
1base.trainable = False
2
3inp = tf.keras.Input(shape=(8,))
4out = base(inp, training=False)
5out = tf.keras.layers.Dense(8, activation="relu")(out)
6out = tf.keras.layers.Dense(1)(out)
7model = tf.keras.Model(inp, out)
8
9model.compile(optimizer="adam", loss="mse")

Fine-tune mode:

python
1base.trainable = True
2for layer in base.layers[:-1]:
3    layer.trainable = False
4
5model.compile(
6    optimizer=tf.keras.optimizers.Adam(1e-4),
7    loss="mse",
8)

Low learning rates are usually safer when unfreezing pretrained layers.

Keep Training and Inference Behavior Correct

Some layers behave differently in training and inference, such as BatchNormalization and Dropout. When freezing a reused model, pass training=False during forward calls if you need stable inference behavior in that block.

python
features = base(inp, training=False)

If you omit this and train end-to-end, stateful layers may update moving statistics even when you intended full freeze semantics.

For custom loops with tf.GradientTape, only optimize intended variables:

python
1with tf.GradientTape() as tape:
2    pred = model(x_batch, training=True)
3    loss = tf.reduce_mean(tf.square(pred - y_batch))
4
5vars_to_train = model.trainable_variables
6grads = tape.gradient(loss, vars_to_train)
7optimizer.apply_gradients(zip(grads, vars_to_train))

This ensures frozen weights stay unchanged.

Clone When You Need Separate Weights

If you want the same architecture but independent parameters, clone the model.

python
clone = tf.keras.models.clone_model(base)
clone.build((None, 8))
clone.set_weights(base.get_weights())

Now clone starts with copied values but future updates do not affect base.

Use cloning for teacher-student models, ensembling, or experiments that require parameter divergence.

Verify Weight Preservation Programmatically

When debugging reuse behavior, compare weight snapshots before and after wrapping.

python
1before = [w.numpy().copy() for w in base.weights]
2
3inp = tf.keras.Input(shape=(8,))
4out = base(inp)
5probe_model = tf.keras.Model(inp, out)
6
7after = [w.numpy().copy() for w in base.weights]
8unchanged = all((b == a).all() for b, a in zip(before, after))
9print(\"weights unchanged after call:\", unchanged)

This confirms that calling on tensors does not mutate parameters unless training updates are applied.

Common Pitfalls

A common mistake is assuming repeated calls create new weight sets. They do not. Repeated calls reuse the same variables unless you explicitly clone.

Another issue is freezing layers after compiling and expecting optimizer behavior to update automatically. After changing trainable flags, recompile the model.

Developers also forget to manage training mode on reused submodels, especially with BatchNormalization, which can silently update internal statistics.

Summary

  • Calling a Keras model on a tensor reuses existing weights by default.
  • Use trainable=False and training=False when you want frozen feature extraction.
  • Recompile after changing trainable flags.
  • Clone models only when you need independent parameter sets.
  • Validate trainable variable lists to confirm optimization scope.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track 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.

Practice ML system design