InterviewsVector

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 default

Load 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)
StatusKeras 3 defaultLegacy, still supported
Captures custom-object configYesLimited
Best forNew workLoading existing files

Common traps

  • load_model on a weights-only file — rebuild the architecture and use load_weights.
  • Missing custom_objects — custom layers/losses can't be resolved by name.
  • Assuming .h5 is gone — it isn't; it just isn't the default any more.

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.

By Mohammad Wasi

Software Engineering Leader & Technical Author · Updated August 26, 2026


Related Posts