Keras
machine learning
neural networks
model weights
deep learning

How to load only specific weights on Keras

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Loading only specific weights in Keras is a common transfer-learning task. The general rule is simple: either load by matching layer names when your Keras version supports it, or load the source model and copy weights layer by layer into the target model explicitly.

Match Layers By Name

The most convenient partial-loading workflow is to give corresponding layers the same names in both models.

Example source model:

python
1import tensorflow as tf
2
3source = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(32,), name="input"),
5    tf.keras.layers.Dense(64, activation="relu", name="encoder"),
6    tf.keras.layers.Dense(10, activation="softmax", name="classifier")
7])
8
9source.save_weights("source.weights.h5")

Target model:

python
1target = tf.keras.Sequential([
2    tf.keras.layers.Input(shape=(32,), name="input"),
3    tf.keras.layers.Dense(64, activation="relu", name="encoder"),
4    tf.keras.layers.Dense(3, activation="softmax", name="new_head")
5])

Here the encoder layer is intentionally shared by name, while the output head is different.

Use By-Name Loading When Available

In Keras versions that support it for your weight format, you can load only matching layers by name and optionally skip mismatched shapes:

python
target.load_weights("source.weights.h5", by_name=True, skip_mismatch=True)

This tells Keras:

  • load layers whose names match
  • ignore layers that do not exist in the target model
  • skip incompatible shapes instead of failing

That is convenient for transfer learning, but it depends on the weight format and Keras version behavior. If your environment does not support by_name in the way you need, use explicit copying instead.

Explicit Layer-By-Layer Copying Is The Most Robust Method

A version-stable approach is to load the source model or source weights into a compatible model and then copy only the desired layers.

python
1import tensorflow as tf
2
3source = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(32,), name="input"),
5    tf.keras.layers.Dense(64, activation="relu", name="encoder"),
6    tf.keras.layers.Dense(10, activation="softmax", name="classifier")
7])
8
9target = tf.keras.Sequential([
10    tf.keras.layers.Input(shape=(32,), name="input"),
11    tf.keras.layers.Dense(64, activation="relu", name="encoder"),
12    tf.keras.layers.Dense(3, activation="softmax", name="new_head")
13])
14
15source.load_weights("source.weights.h5")
16
17target.get_layer("encoder").set_weights(
18    source.get_layer("encoder").get_weights()
19)

This is explicit, easy to debug, and independent of by-name loading quirks.

It also makes the intent obvious: only the encoder weights are being transferred.

Freeze The Transferred Layers If Needed

After loading selected weights, you often want to freeze them before training:

python
1target.get_layer("encoder").trainable = False
2
3target.compile(
4    optimizer="adam",
5    loss="sparse_categorical_crossentropy",
6    metrics=["accuracy"]
7)

That keeps the transferred layer fixed while the new head learns the new task.

Later, you can unfreeze and fine-tune.

Verify That The Weights Actually Loaded

Do not assume the transfer worked just because no error was raised. A useful debugging step is to inspect shapes or compare values directly.

python
1source_weights = source.get_layer("encoder").get_weights()[0]
2target_weights = target.get_layer("encoder").get_weights()[0]
3
4print(source_weights.shape)
5print((source_weights == target_weights).all())

That simple check can save time when layer names differ or shapes were silently skipped.

Architecture Compatibility Still Matters

Partial loading does not remove the need for shape compatibility. A layer can only receive weights if:

  • the layer type is compatible
  • the parameter shapes match
  • the build state is initialized

If the target layer has a different input size or unit count, Keras cannot apply the old weights correctly.

That is why stable layer naming alone is not enough. The parameter structure must line up too.

Common Pitfalls

The biggest mistake is assuming Keras can partially load arbitrary layers by magic. Matching names help, but weight shapes still have to be compatible.

Another mistake is depending entirely on by_name=True without checking your Keras version and weight format behavior. Explicit layer copying is often safer and clearer.

People also forget to build the target model before loading or copying weights. If the target layers are not initialized, shape-dependent operations can fail.

Finally, after transfer learning, remember to decide deliberately which layers are trainable. Loading selected weights is only half of the training strategy.

Summary

  • The cleanest partial-loading strategy is matching layer names plus compatible shapes.
  • 'load_weights(..., by_name=True, skip_mismatch=True) can be convenient when supported by your setup.'
  • Explicit layer-by-layer copying is the most robust and transparent approach.
  • Freeze transferred layers when you want feature reuse before fine-tuning.
  • Always verify that the intended layers actually received the expected weights.

Course illustration
Course illustration

All Rights Reserved.