here is the code from the Distance layer part because site is not allowing me to upload full code.
embedding = make_embedding()
distance layer
class L1Dist(Layer):
def __init__(self, **kwargs):
super().__init__()
def call(self, input_embedding, validation_embedding):
return tf.math.abs(input_embedding - validation_embedding)
def make_siamese_model():
input_image = Input(name='input_img', shape=(100,100,3))
validation_image = Input(name='validation_img', shape=(100,100,3))
siamese_layer = L1Dist()
siamese_layer._name = 'distance'
distances = siamese_layer(embedding(input_image), embedding(validation_image))
classifier = Dense(1, activation='sigmoid')(distances)
return Model(inputs=[input_image, validation_image], outputs=classifier, name='SiameseNetwork')
siamese_model = make_siamese_model()
binary_cross_loss = tf.losses.BinaryCrossentropy()
opt = tf.keras.optimizers.Adam(1e-4) # 0.0001
checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, 'ckpt')
checkpoint = tf.train.Checkpoint(opt=opt, siamese_model=siamese_model)
@tf.function
def train_step(batch):
with tf.GradientTape() as tape:
X = batch[:2]
y = batch[2]
yhat = siamese_model(X, training=True)
loss = binary_cross_loss(y, yhat)
print(loss)
grad = tape.gradient(loss, siamese_model.trainable_variables)
opt.apply_gradients(zip(grad, siamese_model.trainable_variables))
return loss
from tensorflow.python.keras.metrics import Precision, Recall
def train(data, EPOCHS):
for epoch in range(1, EPOCHS+1):
print('\n Epoch {}/{}'.format(epoch, EPOCHS))
progbar = tf.keras.utils.Progbar(len(data))
r = Recall()
p = Precision()
for idx, batch in enumerate(data):
# Run train step here
loss = train_step(batch)
yhat = siamese_model(batch[:2], training=False)
r.update_state(batch[2], yhat)
p.update_state(batch[2], yhat)
progbar.update(idx+1)
print(loss.numpy(), r.result().numpy(), p.result().numpy())
if epoch % 1 == 0:
checkpoint.save(file_prefix=checkpoint_prefix)
siamese_model.compile(
optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy']
)
EPOCHS = 2
train(train_data, EPOCHS)
siamese_model.save('siamese_model.h5')
new_model = tf.keras.models.load_model('siamese_model.h5',custom_objects={'L1Dist':L1Dist, 'binary_crossentropy':tf.losses.binary_crossentropy})
while reloading the model it is showing an ValueError: Unexpected object from deserialization, expected a layer or operation, got a <class 'main.L1Dist'>
please suggest changes in the code so that i could reload the siamsese model.
edit: after trackbacking the error
ValueError Traceback (most recent call last)
Cell In[32], line 1
----> 1 new_model = tf.keras.models.load_model('siamese_model.h5',custom_objects={'L1Dist':Siamese_layer, 'binary_crossentropy':tf.losses.binary_crossentropy})
File ~\Desktop\Mazor Project\.venv\Lib\site-packages\keras\src\saving\saving_api.py:196, in load_model(filepath, custom_objects, compile, safe_mode)
189 return saving_lib.load_model(
190 filepath,
191 custom_objects=custom_objects,
192 compile=compile,
193 safe_mode=safe_mode,
194 )
195 if str(filepath).endswith((".h5", ".hdf5")):
--> 196 return legacy_h5_format.load_model_from_hdf5(
197 filepath, custom_objects=custom_objects, compile=compile
198 )
199 elif str(filepath).endswith(".keras"):
200 raise ValueError(
201 f"File not found: filepath={filepath}. "
202 "Please ensure the file is an accessible `.keras` "
203 "zip file."
204 )
File ~\Desktop\Mazor Project\.venv\Lib\site-packages\keras\src\legacy\saving\legacy_h5_format.py:133, in load_model_from_hdf5(filepath, custom_objects, compile)
130 model_config = json_utils.decode(model_config)
132 with saving_options.keras_option_scope(use_legacy_config=True):
--> 133 model = saving_utils.model_from_config(
134 model_config, custom_objects=custom_objects
135 )
137 # set weights
138 load_weights_from_hdf5_group(f["model_weights"], model)
File ~\Desktop\Mazor Project\.venv\Lib\site-packages\keras\src\legacy\saving\saving_utils.py:88, in model_from_config(config, custom_objects)
84 # TODO(nkovela): Swap find and replace args during Keras 3.0 release
85 # Replace keras refs with keras
86 config = _find_replace_nested_dict(config, "keras.", "keras.")
---> 88 return serialization.deserialize_keras_object(
89 config,
90 module_objects=MODULE_OBJECTS.ALL_OBJECTS,
91 custom_objects=custom_objects,
92 printable_module_name="layer",
93 )
File ~\Desktop\Mazor Project\.venv\Lib\site-packages\keras\src\legacy\saving\serialization.py:495, in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
490 cls_config = _find_replace_nested_dict(
491 cls_config, "keras.", "keras."
492 )
494 if "custom_objects" in arg_spec.args:
--> 495 deserialized_obj = cls.from_config(
496 cls_config,
497 custom_objects={
498 **object_registration.GLOBAL_CUSTOM_OBJECTS,
499 **custom_objects,
500 },
501 )
502 else:
503 with object_registration.CustomObjectScope(custom_objects):
File ~\Desktop\Mazor Project\.venv\Lib\site-packages\keras\src\models\model.py:587, in Model.from_config(cls, config, custom_objects)
582 if is_functional_config and revivable_as_functional:
583 # Revive Functional model
584 # (but not Functional subclasses with a custom __init__)
585 from keras.src.models.functional import functional_from_config
--> 587 return functional_from_config(
588 cls, config, custom_objects=custom_objects
589 )
591 # Either the model has a custom __init__, or the config
592 # does not contain all the information necessary to
593 # revive a Functional model. This happens when the user creates
(...) 596 # In this case, we fall back to provide all config into the
597 # constructor of the class.
598 try:
File ~\Desktop\Mazor Project\.venv\Lib\site-packages\keras\src\models\functional.py:557, in functional_from_config(cls, config, custom_objects)
555 # First, we create all layers and enqueue nodes to be processed
556 for layer_data in functional_config["layers"]:
--> 557 process_layer(layer_data)
559 # Then we process nodes in order of layer depth.
560 # Nodes that cannot yet be processed (if the inbound node
561 # does not yet exist) are re-enqueued, and the process
562 # is repeated until all nodes are processed.
563 while unprocessed_nodes:
File ~\Desktop\Mazor Project\.venv\Lib\site-packages\keras\src\models\functional.py:528, in functional_from_config.<locals>.process_layer(layer_data)
524 layer = serialization_lib.deserialize_keras_object(
525 layer_data, custom_objects=custom_objects
526 )
527 if not isinstance(layer, Operation):
--> 528 raise ValueError(
529 "Unexpected object from deserialization, expected a layer or "
530 f"operation, got a {type(layer)}"
531 )
532 created_layers[layer_name] = layer
534 # Gather layer inputs.
ValueError: Unexpected object from deserialization, expected a layer or operation, got a <class '__main__.L1Dist'>
``
layer
instead of<class 'main.L1Dist'>
then maybe you should use instance of your classL1Dist()
instead of definiton of calssL1Dist
- it needs()
-custom_objects={'L1Dist':L1Dist(), ...
. OR maybe you should usesiamese_layer
which is already instance of this classsiamese_layer = L1Dist()
-custom_objects={'L1Dist':siamese_layer, ...