Limits of Keras load_weights skip_mismatch for rollback after a schema change
0 reputation · 30 Dec 2021, 00:30 UTC
0 reputation · 30 Dec 2021, 00:30 UTC
I want to reuse trained weights from a previous model version after changing the architecture (for example, adding a Dense layer), and I need the process to be rollback-safe: the original layers must keep their trained values, and it must be obvious which parts of the new model were left untouched.
Keras documents model.load_weights(filepath, by_name=True, skip_mismatch=True) as a way to load weights into a modified architecture by matching layers by name and skipping shape mismatches. With the default by_name=False, any architecture change raises a ValueError, which is safe but blocks reuse entirely. My concern is that skip_mismatch=True appears to silently ignore mismatched layers, so a partially initialized model could go unnoticed unless I audit the result myself. I am assuming TensorFlow 2.x with tf.keras, since the skip_mismatch argument is not available in older standalone Keras releases.
skip_mismatch=True load, or is manual comparison of layer names and shapes the only option?by_name=True guarantee that renamed or reordered layers are matched correctly, or are there documented edge cases where weights land on the wrong layer?model.get_config() with weight saving a supported pattern for reverting to a prior schema, or is full model saving the only reliable rollback path?Direct answer: skip_mismatch=True has no documented way to enumerate skipped layers. Keras silently ignores any layer whose name or shape doesn't match the checkpoint, leaving it in its freshly initialized (usually random) state. Manual comparison of layer names and shapes before and after the load is the only reliable audit.
Since the load returns nothing, snapshot the model's weights first and diff afterward:
initial = {layer.name: layer.get_weights() for layer in model.layers}
model.load_weights('old_weights.h5', by_name=True, skip_mismatch=True)
for layer in model.layers:
before = initial.get(layer.name)
after = layer.get_weights()
if before is None:
print(f"{layer.name}: NEW layer, untouched (random init)")
elif all((b == a).all() for b, a in zip(before, after)):
print(f"{layer.name}: SKIPPED or unchanged")
else:
print(f"{layer.name}: weights loaded")Note the caveat: "unchanged" can also mean the checkpoint genuinely contained identical values, so treat the audit as a name/shape cross-check, not proof of a skip.
Matching is strictly by the layer's name attribute:
dense_1 across different schema versions) can cause weights to land on the wrong layer. Assign explicit, stable names to every layer you intend to reuse.model.get_config() captures architecture metadata only — no weights. It is a legitimate schema-versioning tool, but a rollback-safe workflow needs both pieces:
model.to_json() or the config) to record the schema version.model.save_weights().load_weights() — with matching names and shapes, no skip_mismatch is needed.Full model saving (model.save(), SavedModel format) bundles architecture and weights and is the most reliable rollback path, but it prevents partial reuse into a modified architecture. A practical pattern: keep full saves per version for rollback, and use by_name=True, skip_mismatch=True only for forward migration — always followed by the audit above.
Assumption: TensorFlow 2.x / tf.keras; skip_mismatch is unavailable in older standalone Keras. Verify exact behavior against your installed version, as weight-file formats (H5 vs .weights.h5) differ across releases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.