Keras
TensorFlow
Initializer
Control Flow
Programming

Keras, tensorflow Initializer for variable... is from inside a control-flow construct, a loop or conditional

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

This TensorFlow error usually means a variable or layer weight is being created inside a loop, conditional, or traced function body instead of being created once up front. TensorFlow wants variables to have a stable lifetime, so weight creation belongs in __init__, build, or another one-time setup path, not inside dynamic control flow.

Why the Error Happens

TensorFlow traces graphs and expects variable creation to be predictable. If a variable initializer depends on a branch or loop body, TensorFlow cannot safely treat that variable as a stable graph object.

Common triggers include:

  • calling tf.Variable inside @tf.function
  • creating Keras layers inside call
  • adding weights inside a conditional branch
  • building new model parts repeatedly inside a loop

All of these create ambiguity about when and how often the variable should exist.

Example of the Wrong Pattern

This pattern looks innocent, but it creates a weight during the forward pass:

python
1import tensorflow as tf
2
3
4class BadLayer(tf.keras.layers.Layer):
5    def call(self, inputs, training=False):
6        if training:
7            scale = self.add_weight(
8                name="scale",
9                shape=(),
10                initializer="ones",
11            )
12            return inputs * scale
13        return inputs

The problem is not the initializer itself. The problem is that add_weight is being called from inside control flow in call, where TensorFlow may trace and execute the code multiple times under different conditions.

Create Weights in build

The standard fix is to create the weight once in build and use it later in call:

python
1import tensorflow as tf
2
3
4class GoodLayer(tf.keras.layers.Layer):
5    def build(self, input_shape):
6        self.scale = self.add_weight(
7            name="scale",
8            shape=(),
9            initializer="ones",
10        )
11
12    def call(self, inputs, training=False):
13        if training:
14            return inputs * self.scale
15        return inputs

Now the variable lifetime is clear. TensorFlow builds the layer once, creates the weight once, and reuses it on every call.

Create Sub-Layers in __init__, Not in call

The same rule applies to nested layers. This is wrong:

python
1class BadModel(tf.keras.Model):
2    def call(self, inputs):
3        dense = tf.keras.layers.Dense(8, activation="relu")
4        return dense(inputs)

It creates a new layer, and therefore new variables, on every call. The correct pattern is:

python
1class GoodModel(tf.keras.Model):
2    def __init__(self):
3        super().__init__()
4        self.dense = tf.keras.layers.Dense(8, activation="relu")
5
6    def call(self, inputs):
7        return self.dense(inputs)

This is the Keras design model: define structure once, execute it many times.

tf.function Makes the Problem More Visible

In eager execution, sloppy variable creation can sometimes seem to work for a while. Once @tf.function traces the code, the variable-lifetime rules become stricter and the error becomes obvious.

For example, this is also a bad pattern:

python
1import tensorflow as tf
2
3
4@tf.function
5def step(x):
6    weight = tf.Variable(tf.ones([x.shape[-1], 1]))
7    return tf.matmul(x, weight)

The fix is to create the variable outside the traced function and pass it in or capture it from an object:

python
1import tensorflow as tf
2
3weight = tf.Variable(tf.ones([3, 1]))
4
5
6@tf.function
7def step(x):
8    return tf.matmul(x, weight)

If Shape Depends on Input, Use build

Developers sometimes put variable creation inside call because they need input_shape. That is exactly what build(self, input_shape) is for. Keras calls build with the input shape the first time the layer is used, which gives you the information you need without creating variables inside runtime control flow.

That pattern is both idiomatic and compatible with model serialization, tracing, and repeated execution.

Common Pitfalls

The most common mistake is treating call like a place to define model structure. In Keras, call should describe computation using already-created weights and sub-layers.

Another pitfall is creating variables conditionally, such as only when training=True. That makes the variable graph depend on runtime state and leads directly to the error.

It is also easy to instantiate layers inside Python loops that run during execution instead of in __init__. If the loop is defining architecture, it belongs in setup code, not in the execution path.

Finally, do not blame the initializer itself. The message mentions the initializer, but the real problem is variable creation happening in the wrong place.

Summary

  • Create TensorFlow variables and Keras weights once, not inside runtime loops or conditionals.
  • Use __init__ for sub-layers and build for weights that depend on input shape.
  • Keep call focused on computation, not model construction.
  • '@tf.function makes unstable variable-creation patterns fail more clearly.'
  • If you see this error, look for tf.Variable or add_weight in dynamic control-flow paths first.

Course illustration
Course illustration

All Rights Reserved.