Quick Reference · machine learning in Python · TensorFlow 2.21 (Mar 2026)

tensorflow + tensorflow_hub · keras_hub

One sentence explains most of TensorFlow: your code runs eagerly, line by line, until @tf.function traces it once into a graph — and from then on the graph runs, not your Python. Everything else — the speed, the retracing, the print statements that fire only once — follows from that. Keras 3 is the front door; tf.* is the floor beneath it.
setup & inspect tensors & shapes graph & autodiff Keras: build & train tf.data & preprocessing pretrained, save & deploy gotcha / removed most common
Cross-checked against: tensorflow.org (guide + API docs) · keras.io (Keras 3 + KerasHub) · blog.tensorflow.org (2.20 / 2.21) · github.com/tensorflow (releases, hub#903) · kaggle.com/models
The shape of a TensorFlow program
A · THE HIGH ROAD — KERAS DOES THE LOOP FOR YOU tf.data.Dataset batch · shuffle · prefetch keras.Model Sequential / Functional / sub .compile(...) optimizer · loss · metrics .fit(ds, epochs) the whole loop, one call .save("m.keras") .export() for serving or drop down a level ↓ B · THE LOW ROAD — YOU WRITE THE LOOP with tf.GradientTape() as tape: loss = loss_fn(y, model(x, training=True)) grads = tape.gradient(loss, model.trainable_variables) ← the tape records every op on a watched tensor ← then plays it backwards, once opt.apply_gradients(zip(grads, vars)) C · WHERE THE PRETRAINED MODELS LIVE NOW the stack Keras 3 — backend: tensorflow | jax | torch tensorflow — tensors, tf.data, tf.function XLA · kernels · CPU / GPU / TPU tensorflow_hub frozen at 0.16.1 · Jan 2024 hub.load() still works hub.KerasLayer ✗ Keras 3 breaks on TF 2.16+ moved keras_hub .from_preset() · the successor was KerasNLP Kaggle Models tfhub.dev redirects here since Nov 2023 the bridge keras.layers.TFSMLayer loads any SavedModel into Keras 3 as a layer inference only
# the whole library in fourteen lines
import tensorflow as tf, keras

ds = tf.data.Dataset.from_tensor_slices((X, y)) \
       .shuffle(1024).batch(32).prefetch(tf.data.AUTOTUNE)

model = keras.Sequential([
    keras.layers.Dense(128, activation="relu"),
    keras.layers.Dense(10),          # logits, no softmax
])
model.compile(optimizer="adam",
              loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=["accuracy"])   # from_logits MUST match the last layer
model.fit(ds, epochs=5, validation_data=val_ds)
model.save("m.keras")               # .keras or .h5 — a bare path raises
Read this once and most of the reference below is just filling in the blanks.
PART I

tensorflow  ·  the core

Tensors, the graph, autodiff, tf.data and Keras 3. Since TF 2.16 pip install tensorflow brings Keras 3, and tf.keras is Keras 3 — the old Keras 2 lives on separately as tf_keras.
01Install & verifyonce per env
02The import mapwhat to import
03Create tensorsthe raw material
04Attributes & dtypeswhat a tensor knows
05Shape surgeryrearranging
06Broadcastingthe silent bug factory
07Index, slice, reducegetting values out
08Math & linear algebrathe operations
09tf.Variablethe only mutable thing
10@tf.function & graphsthe central idea
11GradientTapeautodiff by recording
12Devices & precisionwhere it runs
13tf.data · buildthe input pipeline
14tf.data · performancekeep the GPU fed
15Preprocessing layersput it in the model
16Keras · three ways to buildpick one
17Keras · layersthe building blocks
18Keras · losses, metrics, optimizersthe training contract
19Keras · compile & fitthe loop, for free
20Keras · callbackshooks into fit()
21Custom training loopwhen fit() is not enough
22Save, load & exportthree different things
23Deploy & distributeoff your laptop
24Debug & reproducebefore blaming the model
PART II

tensorflow_hub  ·  the frozen module

Read this before you copy any tutorial. tensorflow_hub still installs and hub.load() still works — but the library has not shipped a release since 0.16.1 in January 2024, tfhub.dev now redirects to Kaggle Models, and its headline API hub.KerasLayer does not work under Keras 3, which is the default from TF 2.16 onward. This part covers what still works, what breaks, and how to get moving again.
H1Where it standsthe honest status
H2Install & the two APIsthe whole surface
H3hub.load()the path that still works
H4The Keras 3 wallwhy tutorials fail
H5Making it work todaypick your escape
H6Caching & handlesdownloads and offline
PART III

keras_hub  ·  where it went

The successor. KerasHub is the renamed and widened KerasNLP — text, vision and multimodal presets behind one from_preset() constructor, working on all three Keras 3 backends. Plus the two other places pretrained weights live: keras.applications for classic vision, and Kaggle Models for the raw SavedModels.
K1KerasHub · the ideaone constructor
K2Task, Backbone, Preprocessorthe three classes
K3Textclassify and generate
K4Imagesclassify and fine-tune
K5keras.applicationsthe built-in option
K6Migration mapold call → new call

Four pictures worth the whole reference

The central mechanism, the pipeline that keeps the GPU busy, the three ways to build a model, and where the pretrained weights went.

1 · eager vs graph

The same function, twice. Eagerly, your Python runs every call. Traced, it runs once — and the graph runs thereafter. This is why print fires once and tf.print fires always.

EAGER — default call 1 → run Python call 2 → run Python call 3 → run Python debuggable, slower print() every time @tf.function call 1 → TRACE, build graph call 2 → run graph call 3 → run graph fast, no Python in the loop print() fired only on call 1 new shape or dtype → retrace

2 · why prefetch matters

Without overlap the accelerator idles while the CPU prepares the next batch. prefetch(AUTOTUNE) lets step n+1's preparation run during step n's compute.

WITHOUT prefetch — they take turns CPU prep 1 prep 2 prep 3 GPU step 1 step 2 step 3 idle idle idle half thetime wasted WITH prefetch(AUTOTUNE) — they overlap CPU prep 1 prep 2 prep 3 prep 4 GPU step 1 step 2 step 3 step 4 GPU never waits ds.map(f, AUTOTUNE).cache().shuffle(n).batch(b).prefetch(AUTOTUNE) cache after expensive deterministic work · shuffle before batch · prefetch last

3 · three ways to build a model

Same network, three levels of control. Sequential is a list; Functional is a graph you wire by calling layers on tensors; Subclassing is just Python.

Sequential Dense 128 Dense 64 Dense 10 one in, one out no branching Functional Input Dense 64 Add skip any DAG, shared layers shapes checked as you build Subclass def call(self,x): if training: ...whatever return x full control no summary() until built start Sequential · reach for Functional the moment you need a second branch all three are keras.Model — compile() and fit() work identically on each

4 · where the pretrained models went

One library split into three destinations. The dashed box is the part that still installs but no longer moves — and whose Keras layer no longer works.

tensorflow_hub 0.16.1 · Jan 2024 hub.load() ✓ hub.KerasLayer ✗ keras_hub .from_preset() · text, vision, multimodal keras.applications built in · include_top=False for features keras.layers.TFSMLayer wrap a raw SavedModel · inference only tfhub.dev → kaggle.com since Nov 2023

Worth memorizing

traced once, run manyinside @tf.function, Python side effects fire only while tracing
tf.print vs printtf.print becomes a graph op and fires every call
no dtype promotionint32 + float32 raises — TF never casts for you, unlike NumPy
from_logits must matcha softmax layer and from_logits=True trains on nonsense, silently
loss_fn(y_true, y_pred)true label first — the opposite order to most libraries
channels last(N, H, W, C), not (N, C, H, W)
shuffle before batchthe other order only shuffles the order of whole batches
prefetch last, always.prefetch(AUTOTUNE) is what stops the GPU idling
v.assign(x), not v = xrebinding the name throws the tf.Variable away
no zero_grada fresh GradientTape each step means gradients never accumulate
grads of Nonethe tape lost the chain — a .numpy(), an int dtype, or an op outside the tape
broadcasting aligns right(N,1) against (N,) becomes (N,N) and the loss quietly averages N² pairs
.keras or .h5, never baremodel.save("path") raises in Keras 3; use .export() for SavedModel
load_model can't read SavedModeluse keras.layers.TFSMLayer instead
metrics are statefulreset_state() each epoch or you average across all of training
hub.KerasLayer is Keras 2broken on TF 2.16+; hub.load() is fine, and keras_hub is the successor
set_memory_growth earlyor TF pre-allocates the whole GPU the moment it initialises
estimators and tf.litetf.estimator gone in 2.16; tf.lite deprecated in favour of LiteRT