Loading pre trained Attention model in keras custom_objects - python

I am loading a pretrained attention model in Keras using load_model() .
My Attention class is defined as below.
# attention class
from keras.engine.topology import Layer
from keras import initializers, regularizers, constraints
from keras import backend as K
class Attention(Layer):
def __init__(self, step_dim, w_regularizer=None, b_regularizer=None,
w_constraint=None, b_constraint=None, bias=True, **kwargs):
self.supports_masking = True
# weight initializer
self.init = initializers.get('glorot_uniform')
self.w_regularizer = regularizers.get(w_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.w_constraint = constraints.get(w_constraint)
self.b_constraint = constraints.get(b_constraint)
self.bias = bias
self.step_dim = step_dim
self.features_dim = 0
super(Attention, self).__init__(**kwargs)
def build(self, input_shape):
assert len(input_shape) == 3
self.w = self.add_weight(shape=(input_shape[-1],),
initializer=self.init, name='{}_w'.format(self.name),
regularizer=self.w_regularizer,
constraint=self.w_constraint)
self.features_dim = input_shape[-1]
if self.bias:
self.b = self.add_weight(shape=(input_shape[1],),
initializer='zero', name='{}_b'.format(self.name),
regularizer=self.b_regularizer,
constraint=self.b_constraint)
else:
self.b = None
self.built = True
def compute_mask(self, input, input_mask=None):
return None
def call(self, x, mask=None):
features_dim = self.features_dim
step_dim = self.step_dim
eij = K.reshape(K.dot(K.reshape(x, (-1, features_dim)),
K.reshape(self.w, (features_dim, 1))), (-1, step_dim))
if self.bias:
eij += self.b
eij = K.tanh(eij)
a = K.exp(eij)
if mask is not None:
a *= K.cast(mask, K.floatx())
a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())
a = K.expand_dims(a)
weighted_input = x * a
return K.sum(weighted_input, axis=1)
def compute_output_shape(self, input_shape):
return input_shape[0], self.features_dim
def get_config(self):
config = {
'step_dim': self.step_dim,
'w_regularizer': self.w_regularizer,
'w_constraint': self.w_constraint,
'b_regularizer': self.b_regularizer,
'b_constraint': self.b_constraint,
'bias': self.bias
}
base_config = super(Attention, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
The model is called in test_loadmod.py as
from attention import Attention
from keras.models import load_model
model = load_model('attention_wo_cval.h5', custom_objects={'Attention': Attention})
print(model)
The custom Attention model is made available using load_model() and custom_objects is passed into it as described here.
However it doesnt seem to find the step_dim attribute. Throws up the below error. Any idea how to get this going ? Thanks for your time and help.
Error while loading
TypeError: __init__() missing 1 required positional argument: 'step_dim'
File "test_loadmod.py", line 4, in <module>
model = load_model('attention_wo_cval.h5', custom_objects={'Attention': Attention})
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 492, in load_wrapper
return load_function(*args, **kwargs)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 584, in load_model
model = _deserialize_model(h5dict, custom_objects, compile)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 274, in _deserialize_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\saving.py", line 627, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\layers\__init__.py", line 165, in deserialize
return deserialize_keras_object(config,
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\utils\generic_utils.py", line 144, in deserialize_keras_object
return cls.from_config(
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\network.py", line 1056, in from_config
process_layer(layer_data)
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\network.py", line 1041, in process_layer
layer = deserialize_layer(layer_data,
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\layers\__init__.py", line 165, in deserialize
return deserialize_keras_object(config,
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\utils\generic_utils.py", line 149, in deserialize_keras_object
return cls.from_config(config['config'])
File "C:\Users\RV\AppData\Local\Programs\Python\Python38\lib\site-packages\keras\engine\base_layer.py", line 1179, in from_config
return cls(**config)
TypeError: __init__() missing 1 required positional argument: 'step_dim'

The get_config method is the right solution, but you have to pay attention to save the model when this method is updated.
So:
First add the get_config method
Save the model (with this method)
Load the method

Related

How to solve the error TypeError: unsupported operand type(s) for /: 'Dimension' and 'float'

I have a class called MaskedDense. Below is its structure.
class MaskedDense(Layer):
def __init__(self, units, activation=None, use_bias=True, **kwargs):
self.units = units
self.activation = keras.activations.get(activation)
self.use_bias = use_bias
self.kernel_initializer = keras.initializers.glorot_uniform()
self.bias_initializer = keras.initializers.Zeros()
self.mask_initializer = keras.initializers.Ones()
super(MaskedDense, self).__init__(**kwargs)
def get_config(self):
config = super(MaskedDense, self).get_config().copy()
config.update({
"units": self.units,
"activation": self.activation,
"use_bias": self.use_bias,
"kernel_initializer": self.kernel_initializer,
"bias_initializer": self.bias_initializer,
"mask_initializer": self.mask_initializer
})
return config
def build(self, input_shape):
# Create a trainable weight variable for this layer.
input_dim = input_shape[-1]
self.kernel = self.add_weight(shape=(input_dim, self.units),
initializer=self.kernel_initializer,
name='kernel')
# The mask is not trainable
self.mask = self.add_weight(shape=(input_dim, self.units),
initializer=self.mask_initializer,
trainable=False,
name='mask')
if self.use_bias:
self.bias = self.add_weight(shape=(self.units,),
initializer=self.bias_initializer,
name='bias')
else:
self.bias = None
self.input_spec = InputSpec(min_ndim=2, axes={-1: input_dim})
self.built = True
super(MaskedDense, self).build(input_shape) # Be sure to call this at the end
def call(self, inputs):
output = K.dot(inputs, self.kernel * self.mask)
if self.use_bias:
output = K.bias_add(output, self.bias, data_format='channels_last')
if self.activation is not None:
output = self.activation(output)
return output
def compute_output_shape(self, input_shape):
assert input_shape and len(input_shape) >= 2
assert input_shape[-1]
output_shape = list(input_shape)
output_shape[-1] = self.units
return tuple(output_shape)
def set_mask(self, value, feature_idx, class_idx = None):
"""
Set the mask of [feature_idx, class_idx] to a value.
feature_idx: index of the feature
class_idx: index of the class (or a list of indices). None means setting the value to all the classes
value: the value to set
"""
weights = K.get_value(self.mask)
assert feature_idx >= 0 and feature_idx < weights.shape[0], f"Feature index out of bound [0, ..., {weights.shape[0]-1}] -- {feature_idx} given"
if class_idx is not None:
if isinstance(class_idx, list):
for idx in class_idx:
assert idx >= 0 and idx < weights.shape[1], f"Class index out of bound [0, ..., {weights.shape[1]-1}] -- {idx} given"
weights[feature_idx,idx] = value
elif isinstance(class_idx, int):
idx = class_idx
assert idx >= 0 and idx < weights.shape[1], f"Class index out of bound [0, ..., {weights.shape[1]-1}] -- {idx} given"
weights[feature_idx,idx] = value
else:
weights[feature_idx,:] = value
K.set_value(self.mask, weights)
def disable_mask(self, feature_idx, class_idx = None):
self.set_mask(value = 0, feature_idx = feature_idx, class_idx = class_idx)
def enable_mask(self, feature_idx, class_idx = None):
self.set_mask(value = 1, feature_idx = feature_idx, class_idx = class_idx)
def get_masked_weights(self):
return K.get_value(self.mask) * K.get_value(self.kernel)
Then I am trying to create the model. Below is the code.
text_input = Input(shape=(None,), dtype="int32")
embedded_text = Embedding(vocab_size, 300, weights=[embedding_matrix], input_length=150, trainable=True)(text_input)
filters = [(10, 2), (10, 3), (10, 4)]
filter_layers = [Conv1D(f[0], f[1], activation='relu', trainable=True)(embedded_text) for f in filters]
max_pool_layers = [GlobalMaxPool1D()(result) for result in filter_layers]
concatenated = concatenate(max_pool_layers,axis=-1)
ans = MaskedDense(len(class_names), activation='softmax')(concatenated)
model = Model(text_input, ans)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
I am getting the following error:
TypeError: unsupported operand type(s) for /: 'Dimension' and 'float'
What am I doing wrong?
Here is the full error:
Traceback (most recent call last): File "find_1.py", line 227, in
<module>
ans = MaskedDense(len(class_names), activation='softmax')(concatenated) File
"/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py",
line 746, in __call__
self.build(input_shapes) File "find_1.py", line 151, in build
name='kernel') File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py",
line 609, in add_weight
aggregation=aggregation) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/training/checkpointable/base.py",
line 639, in _add_variable_with_custom_getter
**kwargs_for_getter) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py",
line 1977, in make_variable
aggregation=aggregation) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/variables.py",
line 183, in __call__
return cls._variable_v1_call(*args, **kwargs) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/variables.py",
line 146, in _variable_v1_call
aggregation=aggregation) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/variables.py",
line 125, in <lambda>
previous_getter = lambda **kwargs: default_variable_creator(None, **kwargs) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/variable_scope.py",
line 2437, in default_variable_creator
import_scope=import_scope) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/variables.py",
line 187, in __call__
return super(VariableMetaclass, cls).__call__(*args, **kwargs) File
"/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py",
line 297, in __init__
constraint=constraint) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py",
line 409, in _init_from_args
initial_value() if init_from_fn else initial_value, File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py",
line 1959, in <lambda>
shape, dtype=dtype, partition_info=partition_info) File "/home/user_name/miniforge3/envs/py36/lib/python3.6/site-packages/tensorflow/python/ops/init_ops.py",
line 473, in __call__
scale /= max(1., (fan_in + fan_out) / 2.) TypeError: unsupported operand type(s) for /: 'Dimension' and 'float'
Changing input_dim = input_shape[-1] to input_dim = int(input_shape[-1]) solved the problem.

Keras load_model is causing 'TypeError: Keyword argument not understood:' when using custom layer in model

I am building a model with a custom attention layer as implemented in Tensorflow's nmt tutorial. I used the same layer code with a few changes which I found as suggestions in order to solve my problem.
The problem is that I cannot load the model from file after I save it when I have this custom layer. This is the layer class:
class BahdanauAttention(layers.Layer):
def __init__(self, output_dim=30, **kwargs):
super(BahdanauAttention, self).__init__(**kwargs)
self.W1 = tf.keras.layers.Dense(output_dim)
self.W2 = tf.keras.layers.Dense(output_dim)
self.V = tf.keras.layers.Dense(1)
def call(self, inputs, **kwargs):
query = inputs[0]
values = inputs[1]
query_with_time_axis = tf.expand_dims(query, 1)
score = self.V(tf.nn.tanh(
self.W1(query_with_time_axis) + self.W2(values)))
attention_weights = tf.nn.softmax(score, axis=1)
context_vector = attention_weights * values
context_vector = tf.reduce_sum(context_vector, axis=1)
return context_vector, attention_weights
def get_config(self):
config = super(BahdanauAttention, self).get_config()
config.update({
'W1': self.W1,
'W2': self.W2,
'V': self.V,
})
return config
I am saving the model with keras' ModelCheckpoint callback:
path = os.path.join(self.dir, 'model_{}'.format(self.timestamp))
callbacks.append(ModelCheckpoint(path, save_best_only=True, monitor='val_loss', mode='min'))
Later, I am loading the model like so:
self.model = load_model(path, custom_objects={'BahdanauAttention': BahdanauAttention, 'custom_loss': self.custom_loss})
This is the error message I am getting:
raise TypeError(error_message, kwarg)
TypeError: ('Keyword argument not understood:', 'W1')
and full traceback:
Traceback (most recent call last):
File "models/lstm.py", line 49, in load_model
'dollar_mape_loss': self.dollar_mape_loss})
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/save.py", line 187, in load_model
return saved_model_load.load(filepath, compile, options)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 121, in load
path, options=options, loader_cls=KerasObjectLoader)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py", line 633, in load_internal
ckpt_options)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 194, in __init__
super(KerasObjectLoader, self).__init__(*args, **kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/saved_model/load.py", line 130, in __init__
self._load_all()
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 215, in _load_all
self._layer_nodes = self._load_layers()
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 315, in _load_layers
layers[node_id] = self._load_layer(proto.user_object, node_id)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 341, in _load_layer
obj, setter = self._revive_from_config(proto.identifier, metadata, node_id)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 359, in _revive_from_config
self._revive_layer_from_config(metadata, node_id))
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 417, in _revive_layer_from_config
generic_utils.serialize_keras_class_and_config(class_name, config))
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/layers/serialization.py", line 175, in deserialize
printable_module_name='layer')
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/utils/generic_utils.py", line 360, in deserialize_keras_object
return cls.from_config(cls_config)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 697, in from_config
return cls(**config)
File "models/lstm.py", line 310, in __init__
super(BahdanauAttention, self).__init__(**kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/training/tracking/base.py", line 457, in _method_wrapper
result = method(self, *args, **kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 318, in __init__
generic_utils.validate_kwargs(kwargs, allowed_kwargs)
File "venv/m/lib/python3.7/site-packages/tensorflow/python/keras/utils/generic_utils.py", line 778, in validate_kwargs
raise TypeError(error_message, kwarg)
TypeError: ('Keyword argument not understood:', 'W1')
Similar questions suggest that the code is using different versions of Keras and TensorFlow. I am only using TensorFlow's Keras. These are the imports
from tensorflow.keras.models import load_model
from tensorflow.keras.callbacks import EarlyStopping, CSVLogger, ModelCheckpoint
from tensorflow.keras import layers
Following keras' documentation on custom layers, They recommend that any weights should not be initialized in __init__() but in build(). This way the weights do not need to be added to the config and the error will be resolved.
This is the updated custom layer class:
class BahdanauAttention(tf.keras.layers.Layer):
def __init__(self, units=30, **kwargs):
super(BahdanauAttention, self).__init__(**kwargs)
self.units = units
def build(self, input_shape):
self.W1 = tf.keras.layers.Dense(self.units)
self.W2 = tf.keras.layers.Dense(self.units)
self.V = tf.keras.layers.Dense(1)
def call(self, inputs, **kwargs):
query = inputs[0]
values = inputs[1]
query_with_time_axis = tf.expand_dims(query, 1)
score = self.V(tf.nn.tanh(
self.W1(query_with_time_axis) + self.W2(values)))
attention_weights = tf.nn.softmax(score, axis=1)
context_vector = attention_weights * values
context_vector = tf.reduce_sum(context_vector, axis=1)
return context_vector, attention_weights
def get_config(self):
config = super(BahdanauAttention, self).get_config()
config.update({
'units': self.units,
})
return config
I also have this problem.
I've tried a lot of methods and found that this method can be used.
first,build model
model = TextAttBiRNN(maxlen, max_features, embedding_dims).get_model()
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
second, load weights:
I solved the problem with this:
model_file = "/content/drive/My Drive/dga/output_data/model_lstm_att_test_v6.h5"
model.load_weights(model_file)
then,we will find the modle can be use.
in this way,I avoided the previous questions.

Exporting a model with tf.map_fn

I have some tensorflow model which I need to export in a saved model. Below is the simplified code of the model, which I am trying to export.
import tensorflow as tf
def foo(x):
return tf.reduce_sum(x)
inputs = tf.keras.layers.Input(shape=(128,128,3))
y = tf.keras.layers.Conv2D(filters=32, kernel_size=3, padding='SAME')(inputs)
y = tf.keras.layers.ReLU()(y)
outputs = tf.map_fn(foo, y, dtype=(tf.float32))
model = tf.keras.models.Model(inputs=inputs, outputs=outputs)
model.save('./export', save_format='tf')
but while exporting the model I am getting the following error.
/Users/bruce/.venv/bin/python /Users/bruce/test_project/mymodel/test.py
Traceback (most recent call last):
File "/Users/bruce/test_project/mymodel/test.py", line 12, in <module>
outputs = tf.map_fn(foo, y, dtype=(tf.float32))
File "/Users/bruce/.venv/lib/python3.6/site-packages/tensorflow_core/python/ops/map_fn.py", line 228, in map_fn
for elem in elems_flat]
File "/Users/bruce/.venv/lib/python3.6/site-packages/tensorflow_core/python/ops/map_fn.py", line 228, in <listcomp>
for elem in elems_flat]
File "/Users/bruce/.venv/lib/python3.6/site-packages/tensorflow_core/python/ops/tensor_array_ops.py", line 1078, in __init__
name=name)
File "/Users/bruce/.venv/lib/python3.6/site-packages/tensorflow_core/python/ops/tensor_array_ops.py", line 716, in __init__
self._tensor_array = [None for _ in range(size)]
TypeError: 'Tensor' object cannot be interpreted as an integer
I cannot remove the part tf.map_fn which is doing some essential processing which I need in the saved model while deploying it.
You need to use a custom layer:
class MyMapLayer(tf.keras.layers.Layer):
def __init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def foo(self, x):
return tf.reduce_sum(x)
def call(self, inputs, **kwargs):
return tf.map_fn(self.foo, inputs, dtype=(tf.float32))
Then, in your model:
inputs = tf.keras.layers.Input(shape=(128,128,3))
y = tf.keras.layers.Conv2D(filters=32, kernel_size=3, padding='SAME')(inputs)
y = tf.keras.layers.ReLU()(y)
outputs = MyMapLayer()(y)
model = tf.keras.models.Model(inputs=inputs, outputs=outputs)

Define a Custom dense layer with tensorflow

I want to define a new CustomLayer in tensorflow in order to writedown a customized forward and backward operation.
Actually I've defined a CustomLayer according to Dense tensorflow layer. But It doesn't work and I'm stuck with it.
Can anyone help me with this?
Here you are the current version of my code:
class CustomLayer(Layer):
def __init__(self,
units,
activation=None,
use_bias=True,
kernel_initializer='glorot_uniform',
bias_initializer='zeros',
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None,
dynamic=True,
**kwargs):
if 'input_shape' not in kwargs and 'input_dim' in kwargs:
kwargs['input_shape'] = (kwargs.pop('input_dim'),)
super(CustomLayer, self).__init__(activity_regularizer=regularizers.get(activity_regularizer), **kwargs)
self.units = int(units)
self.activation = activations.get(activation)
self.use_bias = use_bias
self.kernel_initializer = initializers.get(kernel_initializer)
self.bias_initializer = initializers.get(bias_initializer)
self.kernel_regularizer = regularizers.get(kernel_regularizer)
self.bias_regularizer = regularizers.get(bias_regularizer)
self.kernel_constraint = constraints.get(kernel_constraint)
self.bias_constraint = constraints.get(bias_constraint)
self.supports_masking = True
self.input_spec = InputSpec(min_ndim=2)
def build(self, input_shape):
dtype = dtypes.as_dtype(self.dtype or K.floatx())
if not (dtype.is_floating or dtype.is_complex):
raise TypeError('Unable to build Dense layer with non-floating point '
'dtype %s' % (dtype,))
input_shape = tensor_shape.TensorShape(input_shape)
if tensor_shape.dimension_value(input_shape[-1]) is None:
raise ValueError('The last dimension of the inputs to Dense '
'should be defined. Found None.')
last_dim = tensor_shape.dimension_value(input_shape[-1])
self.input_spec = InputSpec(min_ndim=2,
axes={-1: last_dim})
self.kernel = self.add_weight(
'kernel',
shape=[last_dim, self.units],
initializer=self.kernel_initializer,
regularizer=self.kernel_regularizer,
constraint=self.kernel_constraint,
dtype=self.dtype,
trainable=True)
if self.use_bias:
self.bias = self.add_weight(
'bias',
shape=[self.units, ],
initializer=self.bias_initializer,
regularizer=self.bias_regularizer,
constraint=self.bias_constraint,
dtype=self.dtype,
trainable=True)
else:
self.bias = None
self.built = True
def call(self, inputs):
global global_self
global_self = self
return custom_op(inputs)
global_self = None
#tf.custom_gradient
def custom_op(inputs):
self = global_self
rank = len(inputs.shape)
if rank > 2:
# Broadcasting is required for the inputs.
outputs = standard_ops.tensordot(inputs, self.kernel, [[rank - 1], [0]])
# Reshape the output back to the original ndim of the input.
if not context.executing_eagerly():
shape = inputs.shape.as_list()
output_shape = shape[:-1] + [self.units]
outputs.set_shape(output_shape)
else:
inputs = math_ops.cast(inputs, self._compute_dtype)
if K.is_sparse(inputs):
outputs = sparse_ops.sparse_tensor_dense_matmul(inputs, self.kernel)
else:
outputs = gen_math_ops.mat_mul(inputs, self.kernel)
if self.use_bias:
outputs = nn.bias_add(outputs, self.bias)
if self.activation is not None:
return self.activation(outputs) # pylint: disable=not-callable
def custom_grad(dy):
print(dy, [dy])
grad = dy # compute gradient
return grad
return outputs, custom_grad
When I try executing get this traceback
Traceback (most recent call last):
File "/home/labt41/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/base_layer.py", line 802, in call
outputs = call_fn(cast_inputs, *args, **kwargs)
File "/home/labt41/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/api.py", line 237, in wrapper
raise e.ag_error_metadata.to_exception(e)
tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: in converted code:
relative to /home/labt41:
PycharmProjects/TF_Custom/CustomLayer_stackoverflow.py:125 call *
return custom_op(inputs)
PycharmProjects/TF_Custom/CustomLayer_stackoverflow.py:136 decorated *
return _graph_mode_decorator(f, *args, **kwargs)
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/custom_gradient.py:229 _graph_mode_decorator
result, grad_fn = f(*args)
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:547 iter
self._disallow_iteration()
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:543 _disallow_iteration
self._disallow_in_graph_mode("iterating over `tf.Tensor`")
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:523 _disallow_in_graph_mode
" this function with #tf.function.".format(task))
OperatorNotAllowedInGraphError: iterating over tf.Tensor is not allowed in Graph execution. Use Eager execution or decorate this function with #tf.function.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/labt41/PycharmProjects/TF_Custom/CustomLayer_stackoverflow.py", line 179, in <module>
model = create_model()
File "/home/labt41/PycharmProjects/TF_Custom/CustomLayer_stackoverflow.py", line 50, in create_model
layer = CustomLayer(units=128)(visible)
File "/home/labt41/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/base_layer.py", line 814, in call
str(e) + '\n"""')
TypeError: You are attempting to use Python control flow in a layer that was not declared to be dynamic. Pass dynamic=True to the class constructor.
Encountered error:
in converted code:
relative to /home/labt41:
PycharmProjects/TF_Custom/CustomLayer_stackoverflow.py:125 call *
return custom_op(inputs)
PycharmProjects/TF_Custom/CustomLayer_stackoverflow.py:136 decorated *
return _graph_mode_decorator(f, *args, **kwargs)
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/ops/custom_gradient.py:229 _graph_mode_decorator
result, grad_fn = f(*args)
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:547 iter
self._disallow_iteration()
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:543 _disallow_iteration
self._disallow_in_graph_mode("iterating over `tf.Tensor`")
anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:523 _disallow_in_graph_mode
" this function with #tf.function.".format(task))
OperatorNotAllowedInGraphError: iterating over tf.Tensor is not allowed in Graph execution. Use Eager execution or decorate this function with #tf.function.

Keras 'load_model' with custom layer object

I have a simple custom layer object to generate multi-varite normal noise with cholesky decomposition. Everything works fine but 'load_model' loading a best model saved by 'ModelCheckPoint'.
The custom layer is:
import kears as ks
import keras.backend as K
class MVGaussianNoise(Layer):
def __init__(self, sigma_ind=None, sigma_dep=None,
noise_level=1.0, seed=None, **kwargs):
self.sigma_ind = sigma_ind
self.sigma_dep = sigma_dep
self.noise_level = noise_level
self.supports_masking = True
self.seed = seed
self._lut_ind = scipy.linalg.cholesky(self.sigma_ind)
self._lut_dep = scipy.linalg.cholesky(self.sigma_dep)
super(MVGaussianNoise, self).__init__(**kwargs)
def call(self, inputs, training=None):
def noised():
z_ind = K.random_normal(
shape=K.shape(inputs),
mean=0.0,
seed=self.seed,
stddev=1.0)
noised_ind = self.noise_level * K.dot(z_ind, self._lut_ind)
return inputs + noised_ind
return K.in_train_phase(noised, inputs, training=training)
def get_config(self):
config = {'sigma_ind': self.sigma_ind,
'sigma_dep': self.sigma_dep,
'noise_level': self.noise_level,
'seed': self.seed}
base_config = super(MVGaussianNoise, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
Here 'sigma_ind' and 'sigma_dep' are of type 'numpy.ndarray(float)' defining the covariances.
Loading the model:
with ks.utils.CustomObjectScope({'MVGaussianNoise': MVGaussianNoise}):
best_model = ks.models.load_model('best_model' + '.h5')
makes the error message:
.
.
.
File "/home/aidin/miniconda3/envs/keras-theano/lib/python2.7/site-packages/keras/utils/generic_utils.py", line 141, in deserialize_keras_object
return cls.from_config(config['config'])
File "/home/aidin/miniconda3/envs/keras-theano/lib/python2.7/site-packages/keras/engine/topology.py", line 1252, in from_config
return cls(**config)
File "hsipydeep/keraskit/noise.py", line 99, in __init__
self._lut_ind = scipy.linalg.cholesky(self.sigma_ind)
File "/home/aidin/miniconda3/envs/keras-theano/lib/python2.7/site-packages/scipy/linalg/decomp_cholesky.py", line 91, in cholesky
check_finite=check_finite)
File "/home/aidin/miniconda3/envs/keras-theano/lib/python2.7/site-packages/scipy/linalg/decomp_cholesky.py", line 37, in _cholesky
c, info = potrf(a1, lower=lower, overwrite_a=overwrite_a, clean=clean)
TypeError: float() argument must be a string or a number
Any thought on that?
It seem's that in your __init__ function, your sigma_ind parameter has default value of None which would be a problem in case that you don't pass sigma_ind during initialization because scipy.linalg.cholesky expect value.
I solved this by changing the data type to 'python.array', seem Keras can not handle numpy.array input args through model loading.

Categories