Tensorflow
ValueError
train_function
Model.compile
run_eagerly

Tensorflow ValueError Unexpected result of train_function Empty logs. Please use Model.compile..., run_eagerlyTrue

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

This Keras error usually indicates that custom training logic returned invalid outputs or encountered a silent shape and dtype issue that prevented metric logs from being produced. The suggestion to set run_eagerly=True is a debugging aid, not the final fix. The durable solution is to validate train_step contract and dataset output consistency.

Core Sections

What Keras Expects from train_function

During model.fit, Keras expects each step to return a mapping of metric names to tensor values. If custom code returns None, non-tensor objects, or malformed structures, logs can be empty and Keras throws the error.

A valid train_step should:

  • unpack data correctly
  • compute loss
  • apply gradients
  • return a dictionary of metrics
python
1import tensorflow as tf
2
3class MyModel(tf.keras.Model):
4    def train_step(self, data):
5        x, y = data
6        with tf.GradientTape() as tape:
7            y_pred = self(x, training=True)
8            loss = self.compiled_loss(y, y_pred)
9
10        grads = tape.gradient(loss, self.trainable_variables)
11        self.optimizer.apply_gradients(zip(grads, self.trainable_variables))
12        self.compiled_metrics.update_state(y, y_pred)
13        return {m.name: m.result() for m in self.metrics}

Use run_eagerly for Diagnosis

Enable eager execution in compile call to get clearer Python stack traces.

python
1model.compile(
2    optimizer="adam",
3    loss="mse",
4    metrics=["mae"],
5    run_eagerly=True
6)

This helps identify where outputs become invalid. After fixing logic, you can switch back to graph execution for speed.

Validate Dataset Output Signature

Many empty-log failures come from dataset output mismatch. Ensure each batch matches model input expectations.

python
for batch in train_ds.take(1):
    x, y = batch
    print(x.shape, y.shape, x.dtype, y.dtype)

If labels are missing, ragged unexpectedly, or wrong dtype for loss function, train_step can fail indirectly.

Common Custom train_step Mistakes

Frequent issues include:

  • forgetting return statement
  • returning plain float instead of tensor mapping
  • not calling compiled_loss
  • applying gradients to wrong variable list
  • metric updates skipped due to early branch exits

Use explicit checks while debugging.

python
tf.debugging.assert_all_finite(loss, "loss has invalid values")

Keep Graph-Compatible Operations

If code works in eager mode but fails when run_eagerly=False, non-graph-friendly Python side effects may be involved.

Avoid mutable Python state updates in step logic unless wrapped safely. Prefer TensorFlow ops for math and conditionals when possible.

Debugging Workflow That Scales

A reliable sequence:

  1. run one batch in eager mode
  2. print shapes and dtypes
  3. validate train_step return dictionary keys
  4. re-enable graph mode
  5. run short smoke training with two epochs

This catches most errors before full training runs.

Test with Minimal Model First

Before debugging a large architecture, reproduce with a tiny network and tiny dataset. If the small case passes, incrementally restore complexity until failure returns.

This binary-search style approach is faster than debugging full production setup directly.

Log Metric Dictionary Keys Explicitly

When custom metrics are dynamic, print the keys returned by train_step for the first few batches. Missing or inconsistent keys can explain empty log aggregation even when training appears to run.

Common Pitfalls

  • Treating run_eagerly=True as permanent solution instead of temporary debugging step.
  • Returning invalid structure from train_step and producing empty logs.
  • Ignoring dataset shape and dtype mismatches that break loss or metric updates.
  • Mixing Python control flow with graph mode assumptions in custom training code.
  • Debugging full pipeline first instead of building a minimal reproducible case.

Summary

  • Empty logs during train_function usually indicate broken custom step contract.
  • run_eagerly=True helps diagnose but should not be the final patch by itself.
  • Ensure train_step returns proper metric dictionary every step.
  • Verify dataset output matches model and loss expectations.
  • Fix minimal reproductions first, then scale back to full training workload.

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
Basis Lab
No course covers this one yet

Basis Lab writes one for you from a sentence about what you want to be able to do, then teaches it and checks you understood. Your first course is free.

Build my course
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