Saving only weights keeps the learned parameters without serializing the complete Keras model definition. This is useful when the architecture is recreated by code, when a checkpoint feeds transfer learning, or when only compatible layer weights should move between models.
In Keras 3, model.save_weights() writes an HDF5 weights file whose name should end in .weights.h5. The receiving model must have a compatible architecture and built variables before load_weights() can restore the parameters.
Use full-model .keras saving when the next process should reload the architecture, compile information, and optimizer state automatically. Use weights-only saving when that extra model metadata is not needed or the architecture is intentionally rebuilt.
Related: How to save and load a Keras model
Related: How to use ModelCheckpoint in Keras
Related: How to run transfer learning in Keras
Steps to save and load Keras model weights:
- Install Keras and the backend package.
$ python -m pip install --upgrade keras jax
- Create save_load_weights.py.
- save_load_weights.py
import os from pathlib import Path os.environ["KERAS_BACKEND"] = "jax" import keras import numpy as np def build_model(compile_model=True): model = keras.Sequential( [ keras.Input(shape=(4,), name="features"), keras.layers.Dense(8, activation="relu", name="hidden"), keras.layers.Dense(1, activation="sigmoid", name="score"), ] ) if compile_model: model.compile( optimizer=keras.optimizers.Adam(learning_rate=0.04), loss=keras.losses.BinaryCrossentropy(), ) return model keras.utils.set_random_seed(29) weights_path = Path("risk-score.weights.h5") if weights_path.exists(): weights_path.unlink() x_train = np.linspace(0.0, 1.0, 64, dtype="float32").reshape(16, 4) y_train = ((x_train[:, 1] + x_train[:, 3]) > 0.9).astype("float32") sample = np.array([[0.2, 0.7, 0.4, 0.8]], dtype="float32") model = build_model() model.fit(x_train, y_train, epochs=10, batch_size=4, verbose=0) before = model.predict(sample, verbose=0) model.save_weights(weights_path) clone = build_model(compile_model=False) clone(np.zeros((1, 4), dtype="float32")) clone.load_weights(weights_path) after = clone.predict(sample, verbose=0) print(f"backend: {keras.backend.backend()}") print(f"weights file: {weights_path}") print(f"weights file exists: {weights_path.exists()}") print(f"prediction before save: {before[0, 0]:.6f}") print(f"prediction after load: {after[0, 0]:.6f}") print(f"predictions match: {np.allclose(before, after, atol=1e-6)}")
The clone is built once before loading weights so all layer variables exist. The architecture must stay compatible with the saved weights file.
- Run the script.
$ python save_load_weights.py backend: jax weights file: risk-score.weights.h5 weights file exists: True prediction before save: 0.655520 prediction after load: 0.655520 predictions match: True
Confirm predictions match: True before using the weights file in another script or training job.
- Use the native .keras format instead when the architecture should travel with the weights.
model.save("risk-score.keras") loaded_model = keras.models.load_model("risk-score.keras")
Related: How to save and load a Keras model
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.