Load a Keras Model from an HDF5 (.h5) File — and Why .keras Is Now Default
Quick answer
Load a full Keras model saved as HDF5 with tf.keras.models.load_model('model.h5') — it restores architecture, weights, and optimizer state in one call, and still works in current Keras. If the file holds only weights (model.save_weights), rebuild an identical model first, then call model.load_weights('model.weights.h5'). Custom layers/losses need custom_objects. Note: Keras 3 / TF 2.16+ defaults to the native .keras format; .h5 is legacy but still supported for loading.
Short answer: model = tf.keras.models.load_model('model.h5') restores the architecture, weights, and optimizer in one call. If the file holds only weights, rebuild the model first and use load_weights. Custom layers need custom_objects. Note: Keras 3 / TF 2.16+ default to the newer .keras format; .h5 still loads fine.
Save, then load a full model
Saving the whole model captures architecture + weights + optimizer:
import tensorflow as tf
model = tf.keras.Sequential([
tf.keras.layers.Dense(32, activation="relu", input_shape=(10,)),
tf.keras.layers.Dense(1),
])
model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
model.save("my_model.h5") # HDF5 (legacy but supported)
# model.save("my_model.keras") # native format — the Keras 3 defaultLoad it back and use it immediately:
model = tf.keras.models.load_model("my_model.h5")
import numpy as np
x_test = np.random.random((4, 10))
preds = model.predict(x_test)
loss, acc = model.evaluate(x_test, np.zeros((4, 1)))load_model reads both .h5 and .keras, so you don't need to re-save old files.
Load for inference only
Skip optimizer restoration when you won't keep training:
model = tf.keras.models.load_model("my_model.h5", compile=False)Weights-only files are different
If the file was produced by save_weights, it has no architecture — rebuild the same model first:
# saving
model.save_weights("my_model.weights.h5")
# loading
model = build_same_model() # identical architecture
model.load_weights("my_model.weights.h5")Calling load_model on a weights-only file will fail — that's the usual cause of "load doesn't work."
Custom layers or losses
A saved model references your custom classes by name. Provide them on load:
model = tf.keras.models.load_model(
"my_model.h5",
custom_objects={"MyLayer": MyLayer, "my_loss": my_loss},
)Or register them once so Keras resolves them automatically:
@tf.keras.saving.register_keras_serializable()
class MyLayer(tf.keras.layers.Layer): ....keras vs .h5 today
.keras (native) | .h5 (HDF5) | |
|---|---|---|
| Status | Keras 3 default | Legacy, still supported |
| Captures custom-object config | Yes | Limited |
| Best for | New work | Loading existing files |
Common traps
load_modelon a weights-only file — rebuild the architecture and useload_weights.- Missing
custom_objects— custom layers/losses can't be resolved by name. - Assuming
.h5is gone — it isn't; it just isn't the default any more.
Related guides
Sources
Key takeaways
- •load_model('model.h5') restores architecture + weights + optimizer in one call.
- •Weights-only files require rebuilding the same model, then model.load_weights(...).
- •Custom layers/losses: pass custom_objects={...} or register with @keras.saving.register_keras_serializable().
- •Keras 3 / TF 2.16+ default to the newer .keras (zip) format; .h5 (HDF5) is legacy but still loads.
- •Use compile=False to load a model for inference only, skipping optimizer restoration.
Frequently asked questions
How do I load a Keras model from an .h5 file?
Call tf.keras.models.load_model('my_model.h5'). It reconstructs the architecture, restores the trained weights, and restores the optimizer state, returning a ready-to-use model. This works whether the file was saved by an older Keras or a current one.
What's the difference between saving a model and saving weights?
model.save('m.h5') (or 'm.keras') stores the whole model — architecture, weights, and optimizer — so load_model rebuilds everything. model.save_weights('m.weights.h5') stores only the weight tensors, so to load them you must first construct an identical model and then call model.load_weights().
My model has a custom layer/loss and load_model fails — how do I fix it?
Pass it via custom_objects: load_model('m.h5', custom_objects={'MyLayer': MyLayer}). Better, decorate the class/function with @keras.saving.register_keras_serializable() so Keras can find it automatically on load.
Should I still use HDF5 (.h5) to save Keras models?
For new work, prefer the native format model.save('model.keras') — it's the Keras 3 default and captures more (like custom-object configs) reliably. HDF5 (.h5) is still fully supported for loading existing files, so you don't need to re-save old models.
Software Engineering Leader & Technical Author · Updated August 26, 2026