TensorFlow
optimizer variables
machine learning
deep learning
initialization

How to initialise only optimizer variables in Tensorflow?

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

In TensorFlow, optimizer variables (slot variables and iteration counters) are usually created lazily when gradients are first applied, which can surprise users who expect all variables to exist immediately after optimizer creation. A better pattern is to define the minimum successful flow first, make assumptions explicit, and only then optimize. This avoids brittle fixes and gives you a clear baseline when behavior changes under load or in different environments.

If you restore checkpoints or run custom loops, you may need optimizer state initialized without reinitializing model weights. The correct pattern is to force optimizer variable creation with a controlled dummy apply step. Treat configuration, runtime behavior, and validation as separate concerns. That separation helps you troubleshoot faster and gives teammates a stable mental model for ongoing maintenance.

Core Sections

1) Define the operating contract first

Before changing implementation details, write down the input shape, output guarantees, and failure behavior you expect. Include environment assumptions such as runtime version, network boundaries, data volume, and latency goals. This contract turns vague bugs into verifiable hypotheses. It also prevents accidental coupling between unrelated concerns, such as configuration and business logic. Teams that document these boundaries up front usually spend less time on regressions and more time on measurable improvements.

2) Create optimizer slots by applying zero gradients once

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([tf.keras.layers.Dense(8), tf.keras.layers.Dense(1)])
4_ = model(tf.zeros([1, 4]))  # build model variables
5
6opt = tf.keras.optimizers.Adam(1e-3)
7zero_grads = [tf.zeros_like(v) for v in model.trainable_variables]
8opt.apply_gradients(zip(zero_grads, model.trainable_variables))
9
10print("optimizer vars:", len(opt.variables()))

This baseline example is intentionally conservative. It favors clarity over cleverness and makes state transitions visible. Keep it running as a reference implementation while you iterate. If later optimization changes behavior, compare against this baseline to isolate the exact regression. In practice, this approach shortens debugging loops and keeps refactors from drifting away from expected behavior.

3) Separate model and optimizer checkpoint state explicitly

python
1ckpt = tf.train.Checkpoint(model=model, optimizer=opt)
2manager = tf.train.CheckpointManager(ckpt, "./ckpt", max_to_keep=3)
3
4# Restore both model and optimizer slots if available
5ckpt.restore(manager.latest_checkpoint).expect_partial()
6
7# If optimizer slots are missing, run one dummy step to initialize
8if len(opt.variables()) == 0:
9    opt.apply_gradients(zip([tf.zeros_like(v) for v in model.trainable_variables],
10                            model.trainable_variables))

The second example adds operational hardening: better observability, explicit lifecycle handling, and safer defaults. Production systems fail at boundaries, not just in core logic, so edge-path behavior must be deliberate. Add logs or metrics at decision points, and prefer deterministic failure modes over silent fallbacks. That design makes on-call response significantly faster when incidents occur.

4) Validation and rollout strategy

Verify state continuity by comparing loss curves before and after resume. If optimizer state is missing, Adam-like optimizers often show a noticeable transient jump. Keep a short regression checklist in your repository so every environment change can be verified consistently. Include success-path checks and one intentional failure case. Over time, this checklist becomes living documentation that protects future edits and keeps behavior stable across teams and release cycles.

Common Pitfalls

  • Assuming optimizer variables exist before the first gradient application.
  • Reinitializing model variables accidentally while trying to init optimizer slots.
  • Restoring checkpoints with mismatched optimizer type or hyperparameters.
  • Skipping a model build call before creating zero gradients.
  • Using custom training loops without checkpointing iteration counters.

Summary

Initialize optimizer state deliberately by creating slots through a controlled gradient application, and checkpoint model plus optimizer together for reproducible resumes. The recurring pattern is simple: keep the core path explicit, add guardrails around it, and verify outcomes with repeatable tests before scaling complexity.


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

All Rights Reserved.