'How to save Keras model with custom layer that have dictionary variable
I have a custom layer , which has a dictionary variable called vmap. I implement the get_config() and from_config() method in the custom layer class and try to save the model using : model.save('model.h5') and loading the model using : new_model = tf.keras.models.load_model('model.h5',custom_objects = {"valuemaplayer": valuemaplayer})
This is my code for custom layer :
class valuemaplayer(keras.layers.Layer):
def init(self,vmap ={},compress = False, **kwargs):
kwargs["dynamic"] = True
super(valuemaplayer,self).init(**kwargs)
self._vmap = vmap
self._data = []
self._compression = compress
self._output_shape = None
def build(self, input_shape):
pass
def enable_compression(self):
value = list(self.get_values())
vmap = self._vmap
cnt = 0
# FIXME right now only 2D input data is supported
for v0 in value:
for v1 in v0:
for v2 in v1:
for v3 in v2:
v = tuple(v3)
if v not in vmap:
vmap[v]=cnt
cnt+=1
self._compression = True
print(vmap)
@tf.function
def do_mapping(self,pixel):
enumerated_value = self._vmap.get(pixel)
# print(enumerated_value)
# print(pixel)
return enumerated_value
def call(self, inputs, training=True):#use eager execution or decorate with @tf.function
if self._compression:
elem = []
for b in inputs:
for h in b:
for w in h:
x = self.do_mapping(pixel=tuple(w.numpy()))
elem.append(tf.convert_to_tensor(x, dtype='float32'))
return tf.cast(tf.reshape(elem, self._output_shape), dtype='float32')
# TODO check if channel axis gets mapped by tf.map_fn
# else compression is disabled
# in case we're training, we do not want to observe values
if not training:
self._data.append(inputs)
return inputs
# get values of the output of value map layer
def get_values(self):
for d in self._data:
try:
d = d.numpy()
except AttributeError:
continue
yield d
def get_config(self):
config = super(valuemaplayer, self).get_config()
config.update({"vmap": self._vmap.items(),
"compress": self._compression})
return config
@classmethod
def from_config(cls, config):
return cls(**config)
def compute_output_shape(self, input_shape):
print("input shape of value map layer:", input_shape)
self._output_shape=input_shape
b, h, w, _ = input_shape
if self._compression:
# TODO did I set the channel axis? and does this work?
print("channel axis is set")
self._output_shape = tf.TensorShape((b, h, w, 1))
return self._output_shape
#saving the model :
model.save('model.h5')
#load model :
new_model = tf.keras.models.load_model('model.h5',custom_objects = {"valuemaplayer": valuemaplayer})
In the config method if i do "vmap": self._vmap and try to save the model it is saved and loaded successfully. However, i need to save the dictionary vmap with its content so i do "vmap": self._vmap.items() in config method and try to retrain and save that retrained model but i get an error stating Type error: keys must be str,int,float,bool or None , not Tuple
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
