How can I create a multihot embedding layer in Keras? - tensorflow

I have sequential data where each element is a vector as follows:
x_i = [ 0. , 0. , 0. , 0.03666667, 0. ,
0. , 0.95666667, 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0.00666667, 0. ,
0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. ,
0. ]
The vector represents the distribution of time (over a 5-minute block, for example) a user spent on a set of activities. The task is to predict the distribution of the tasks over the next time step t+1 given the previous N steps (t-N : t). Consequently, my input shape is:
X.shape = (batch_size, timesteps, input_length), and an example would be (32, 10, 41) where we have a batch size of 32, 10 timesteps in the past and the each element has a dimenionsality of 41.
To do this I'm using an LSTM built using Keras. Before passing this input to the LSTM though, I would like to create something similar to an Embedding layer that converts this representation into a dense high-dimensional vector similar to what's done in NLP and embedding one-hot vectors of words into an embedding space using the embedding layer. However, the Embedding layer in Keras only accepts integer inputs (or one-hot representations), and in my case what I would like to achieve is a matrix product between the input vector X (which is composed of several x_i as it represents time-series data) and an Embedding Matrix V. To illustrate:
X.shape = (10, 41)
Embedding matrix shape = (41, 100)
The role is to convert every element in X from it's 41 dimenional sparse representation into 100 dimensions via the matrix multiplication, and this should be done for all elements in the batch input.
To do that I've done the following
class EmbeddingMatrix(Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
super(EmbeddingMatrix, self).__init__(**kwargs)
def build(self, input_shape):
# Create a trainable weight variable for this layer.
self.kernel = self.add_weight(name='kernel',
shape=(input_shape[2], self.output_dim),
initializer='uniform',
trainable=True)
super(EmbeddingMatrix, self).build(input_shape) # Be sure to call this somewhere!
def call(self, x, mask=None):
return K.dot(x, self.kernel)
def compute_output_shape(self, input_shape):
return (input_shape[0], input_shape[1], self.output_dim)
And the LSTM network I'm using is as follows:
inputs = Input(shape=(FLAGS.look_back, FLAGS.inputlength))
inputs_embedded = EmbeddingMatrix(N_EMBEDDING)(inputs)
encoded = LSTM(N_HIDDEN, dropout=0.2, recurrent_dropout=0.2)(inputs_embedded)
dense = TimeDistributed(Dense(N_DENSE, activation='sigmoid'))(dropout)
dense_output = TimeDistributed(Dense(FLAGS.inputlength, activation='softmax'))(dense)
embedder = Model(inputs, inputs_embedded)
model = Model(inputs, dense_output)
model.compile(loss='mean_squared_error', optimizer = RMSprop(lr=LEARNING_RATE, clipnorm=5))
However, when running I get the following error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-24-5a28b4f3b6b9> in <module>()
5 inputs_embedded = EmbeddingMatrix(N_EMBEDDING)(inputs)
6
----> 7 encoded = LSTM(N_HIDDEN, dropout=0.2, recurrent_dropout=0.2)(inputs_embedded)
8
9 dense = TimeDistributed(Dense(N_DENSE, activation='sigmoid'))(dropout)
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/layers/recurrent.py in __call__(self, inputs, initial_state, **kwargs)
260 # modify the input spec to include the state.
261 if initial_state is None:
--> 262 return super(Recurrent, self).__call__(inputs, **kwargs)
263
264 if not isinstance(initial_state, (list, tuple)):
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/engine/topology.py in __call__(self, inputs, **kwargs)
567 '`layer.build(batch_input_shape)`')
568 if len(input_shapes) == 1:
--> 569 self.build(input_shapes[0])
570 else:
571 self.build(input_shapes)
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/layers/recurrent.py in build(self, input_shape)
1041 initializer=bias_initializer,
1042 regularizer=self.bias_regularizer,
-> 1043 constraint=self.bias_constraint)
1044 else:
1045 self.bias = None
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
85 warnings.warn('Update your `' + object_name +
86 '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 87 return func(*args, **kwargs)
88 wrapper._original_function = func
89 return wrapper
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/engine/topology.py in add_weight(self, name, shape, dtype, initializer, regularizer, trainable, constraint)
389 if dtype is None:
390 dtype = K.floatx()
--> 391 weight = K.variable(initializer(shape), dtype=dtype, name=name)
392 if regularizer is not None:
393 self.add_loss(regularizer(weight))
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/layers/recurrent.py in bias_initializer(shape, *args, **kwargs)
1033 self.bias_initializer((self.units,), *args, **kwargs),
1034 initializers.Ones()((self.units,), *args, **kwargs),
-> 1035 self.bias_initializer((self.units * 2,), *args, **kwargs),
1036 ])
1037 else:
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py in concatenate(tensors, axis)
1721 return tf.sparse_concat(axis, tensors)
1722 else:
-> 1723 return tf.concat([to_dense(x) for x in tensors], axis)
1724
1725
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py in concat(concat_dim, values, name)
1073 ops.convert_to_tensor(concat_dim,
1074 name="concat_dim",
-> 1075 dtype=dtypes.int32).get_shape(
1076 ).assert_is_compatible_with(tensor_shape.scalar())
1077 return identity(values[0], name=scope)
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in convert_to_tensor(value, dtype, name, as_ref, preferred_dtype)
667
668 if ret is None:
--> 669 ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
670
671 if ret is NotImplemented:
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/constant_op.py in _constant_tensor_conversion_function(v, dtype, name, as_ref)
174 as_ref=False):
175 _ = as_ref
--> 176 return constant(v, dtype=dtype, name=name)
177
178
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/constant_op.py in constant(value, dtype, shape, name, verify_shape)
163 tensor_value = attr_value_pb2.AttrValue()
164 tensor_value.tensor.CopyFrom(
--> 165 tensor_util.make_tensor_proto(value, dtype=dtype, shape=shape, verify_shape=verify_shape))
166 dtype_value = attr_value_pb2.AttrValue(type=tensor_value.tensor.dtype)
167 const_tensor = g.create_op(
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/tensor_util.py in make_tensor_proto(values, dtype, shape, verify_shape)
365 nparray = np.empty(shape, dtype=np_dt)
366 else:
--> 367 _AssertCompatible(values, dtype)
368 nparray = np.array(values, dtype=np_dt)
369 # check to them.
/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/tensor_util.py in _AssertCompatible(values, dtype)
300 else:
301 raise TypeError("Expected %s, got %s of type '%s' instead." %
--> 302 (dtype.name, repr(mismatch), type(mismatch).__name__))
303
304
TypeError: Expected int32, got list containing Tensors of type '_Message' instead.
What could be causing this and what would be the best way to implement such a weighted embedding matrix?

Related

Using gen_nn_ops.max_pool_grad_v2 for layerwise relevance propagation not working: Keras symbolic input/output

I am trying to apply layerwise relevance propagation (LRP) following some examples and tutorials, in particular this one and this one. However, I am struggling to get the relevances for the max_pooling layers. In particular, the problem appears when using gen_nn_ops.max_pool_grad_v2:
gen_nn_ops.max_pool_grad_v2(orig_input=a, orig_output=z, grad=s,
ksize=ksize,
strides=[1, 2, 2, 1], padding='VALID')
where the inputs are:
a : <KerasTensor: shape=(None, 6, 8, 512) dtype=float32 (created by layer 'activation_23')>
z : <KerasTensor: shape=(None, 3, 4, 512) dtype=float32 (created by layer 'tf.compat.v1.nn.max_pool_1')>
s: <KerasTensor: shape=(None, 3, 4, 512) dtype=float32 (created by layer 'tf.math.truediv_23')>
The error I got is:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/scratch/local/26230143/ipykernel_15814/2576584237.py in <module>
----> 1 gen_nn_ops.max_pool_grad_v2(orig_input=a, orig_output=z, grad=s,
2 ksize=kk,
3 strides=[1, 2, 2, 1], padding='VALID')
~/.local/lib/python3.9/site-packages/tensorflow/python/ops/gen_nn_ops.py in max_pool_grad_v2(orig_input, orig_output, grad, ksize, strides, padding, data_format, name)
6251 pass
6252 try:
-> 6253 return max_pool_grad_v2_eager_fallback(
6254 orig_input, orig_output, grad, ksize, strides, padding=padding,
6255 data_format=data_format, name=name, ctx=_ctx)
~/.local/lib/python3.9/site-packages/tensorflow/python/ops/gen_nn_ops.py in max_pool_grad_v2_eager_fallback(orig_input, orig_output, grad, ksize, strides, padding, data_format, name, ctx)
6283 data_format = "NHWC"
6284 data_format = _execute.make_str(data_format, "data_format")
-> 6285 _attr_T, _inputs_T = _execute.args_to_matching_eager([orig_input, orig_output, grad], ctx, [_dtypes.float32, _dtypes.float64, _dtypes.int32, _dtypes.uint8, _dtypes.int16, _dtypes.int8, _dtypes.int64, _dtypes.bfloat16, _dtypes.uint16, _dtypes.half, _dtypes.uint32, _dtypes.uint64, ], _dtypes.float32)
6286 (orig_input, orig_output, grad) = _inputs_T
6287 ksize = _ops.convert_to_tensor(ksize, _dtypes.int32)
~/.local/lib/python3.9/site-packages/tensorflow/python/eager/execute.py in args_to_matching_eager(l, ctx, allowed_dtypes, default_dtype)
254 # not list allowed dtypes, in which case we should skip this.
255 if dtype is None and allowed_dtypes:
--> 256 tensor = ops.convert_to_tensor(t, ctx=ctx)
257 # If we did not match an allowed dtype, try again with the default
258 # dtype. This could be because we have an empty tensor and thus we
~/.local/lib/python3.9/site-packages/tensorflow/python/profiler/trace.py in wrapped(*args, **kwargs)
181 with Trace(trace_name, **trace_kwargs):
182 return func(*args, **kwargs)
--> 183 return func(*args, **kwargs)
184
185 return wrapped
~/.local/lib/python3.9/site-packages/tensorflow/python/framework/ops.py in convert_to_tensor(value, dtype, name, as_ref, preferred_dtype, dtype_hint, ctx, accepted_result_types)
1693
1694 if ret is None:
-> 1695 ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
1696
1697 if ret is NotImplemented:
~/.local/lib/python3.9/site-packages/tensorflow/python/framework/constant_op.py in _constant_tensor_conversion_function(v, dtype, name, as_ref)
341 as_ref=False):
342 _ = as_ref
--> 343 return constant(v, dtype=dtype, name=name)
344
345
~/.local/lib/python3.9/site-packages/tensorflow/python/framework/constant_op.py in constant(value, dtype, shape, name)
265 ValueError: if called on a symbolic tensor.
266 """
--> 267 return _constant_impl(value, dtype, shape, name, verify_shape=False,
268 allow_broadcast=True)
269
~/.local/lib/python3.9/site-packages/tensorflow/python/framework/constant_op.py in _constant_impl(value, dtype, shape, name, verify_shape, allow_broadcast)
277 with trace.Trace("tf.constant"):
278 return _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
--> 279 return _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
280
281 g = ops.get_default_graph()
~/.local/lib/python3.9/site-packages/tensorflow/python/framework/constant_op.py in _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
302 def _constant_eager_impl(ctx, value, dtype, shape, verify_shape):
303 """Creates a constant on the current device."""
--> 304 t = convert_to_eager_tensor(value, ctx, dtype)
305 if shape is None:
306 return t
~/.local/lib/python3.9/site-packages/tensorflow/python/framework/constant_op.py in convert_to_eager_tensor(value, ctx, dtype)
100 dtype = dtypes.as_dtype(dtype).as_datatype_enum
101 ctx.ensure_initialized()
--> 102 return ops.EagerTensor(value, ctx.device_name, dtype)
103
104
~/.local/lib/python3.9/site-packages/keras/engine/keras_tensor.py in __array__(self, dtype)
252
253 def __array__(self, dtype=None):
--> 254 raise TypeError(
255 f'You are passing {self}, an intermediate Keras symbolic input/output, '
256 'to a TF API that does not allow registering custom dispatchers, such '
TypeError: You are passing KerasTensor(type_spec=TensorSpec(shape=(None, 6, 8, 512),
dtype=tf.float32, name=None), name='activation_23/Relu:0', description="created by layer
'activation_23'"), an intermediate Keras symbolic input/output, to a TF API that does not allow
registering custom dispatchers, such as `tf.cond`, `tf.function`, gradient tapes, or
`tf.map_fn`. Keras Functional model construction only supports TF API calls that *do* support
dispatching, such as `tf.math.add` or `tf.reshape`. Other APIs cannot be called directly on
symbolic Kerasinputs/outputs. You can work around this limitation by putting the operation in a
custom Keras layer `call` and calling that layer on this symbolic input/output.
I am assuming that somehow a, z and s must be tf.Tensor (am I wrong)? (instead of KerasTensor) , but I don't really know and neither how to get around this issue. I read that using:
from tensorflow.python.framework.ops import disable_eager_execution
disable_eager_execution()
might work, but it is not working for me. I'd really appreaciate any idea, suggestion here!
Thank you very much in advance,

Using tf.data.Dataset with tf Hub Modules

How do I feed a tf.keras model, that includes a 1D input TF Hub module, with a tf.data.Dataset?
(Ultimately, the aim is to use a single tf.data.Dataset with a multi-input, multi-output keras funtional api model.)
Tried this:
import tensorflow as tf
import tensorflow_hub as hub
embed = "https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1"
hub_layer = hub.KerasLayer(embed, output_shape=[20], input_shape=[],
dtype=tf.string, trainable=True, name='hub_layer')
# From tf hub webpage: "The module takes a batch of sentences in a 1-D tensor of strings as input."
input_tensor = tf.keras.Input(shape=(), dtype=tf.string)
hub_tensor = hub_layer(input_tensor)
x = tf.keras.layers.Dense(16, activation='relu')(hub_tensor)#(x)
main_output = tf.keras.layers.Dense(units=4, activation='softmax', name='main_output')(x)
model = tf.keras.models.Model(inputs=[input_tensor], outputs=[main_output])
# This works as expected.
X_tensor = tf.constant(['Hello World', 'The Quick Brown Fox'])
model(X_tensor)
# This fails
X_ds = tf.data.Dataset.from_tensors(X_tensor)
X_ds.element_spec
model(X_ds)
Expectation was that the 1D tensor in the dataset would be automatically extracted and consumed by the model.
Error message:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in
21 X_ds = tf.data.Dataset.from_tensors(X_tensor)
22 X_ds.element_spec
---> 23 model(X_ds)
24
25
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in __call__(self, *args, **kwargs)
966 with base_layer_utils.autocast_context_manager(
967 self._compute_dtype):
--> 968 outputs = self.call(cast_inputs, *args, **kwargs)
969 self._handle_activity_regularization(inputs, outputs)
970 self._set_mask_metadata(inputs, outputs, input_masks)
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/keras/engine/network.py in call(self, inputs, training, mask)
717 return self._run_internal_graph(
718 inputs, training=training, mask=mask,
--> 719 convert_kwargs_to_constants=base_layer_utils.call_context().saving)
720
721 def compute_output_shape(self, input_shape):
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/keras/engine/network.py in _run_internal_graph(self, inputs, training, mask, convert_kwargs_to_constants)
835 tensor_dict = {}
836 for x, y in zip(self.inputs, inputs):
--> 837 y = self._conform_to_reference_input(y, ref_input=x)
838 x_id = str(id(x))
839 tensor_dict[x_id] = [y] * self._tensor_usage_count[x_id]
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/keras/engine/network.py in _conform_to_reference_input(self, tensor, ref_input)
959 # Dtype handling.
960 if isinstance(ref_input, (ops.Tensor, composite_tensor.CompositeTensor)):
--> 961 tensor = math_ops.cast(tensor, dtype=ref_input.dtype)
962
963 return tensor
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/util/dispatch.py in wrapper(*args, **kwargs)
178 """Call target, and fall back on dispatchers if there is a TypeError."""
179 try:
--> 180 return target(*args, **kwargs)
181 except (TypeError, ValueError):
182 # Note: convert_to_eager_tensor currently raises a ValueError, not a
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py in cast(x, dtype, name)
785 # allows some conversions that cast() can't do, e.g. casting numbers to
786 # strings.
--> 787 x = ops.convert_to_tensor(x, name="x")
788 if x.dtype.base_dtype != base_type:
789 x = gen_math_ops.cast(x, base_type, name=name)
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in convert_to_tensor(value, dtype, name, as_ref, preferred_dtype, dtype_hint, ctx, accepted_result_types)
1339
1340 if ret is None:
-> 1341 ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
1342
1343 if ret is NotImplemented:
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/framework/constant_op.py in _constant_tensor_conversion_function(v, dtype, name, as_ref)
319 as_ref=False):
320 _ = as_ref
--> 321 return constant(v, dtype=dtype, name=name)
322
323
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/framework/constant_op.py in constant(value, dtype, shape, name)
260 """
261 return _constant_impl(value, dtype, shape, name, verify_shape=False,
--> 262 allow_broadcast=True)
263
264
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/framework/constant_op.py in _constant_impl(value, dtype, shape, name, verify_shape, allow_broadcast)
268 ctx = context.context()
269 if ctx.executing_eagerly():
--> 270 t = convert_to_eager_tensor(value, ctx, dtype)
271 if shape is None:
272 return t
~/projects/email_analysis/email_venv/lib/python3.6/site-packages/tensorflow/python/framework/constant_op.py in convert_to_eager_tensor(value, ctx, dtype)
94 dtype = dtypes.as_dtype(dtype).as_datatype_enum
95 ctx.ensure_initialized()
---> 96 return ops.EagerTensor(value, ctx.device_name, dtype)
97
98
ValueError: Attempt to convert a value () with an unsupported type () to a Tensor.
The point of a dataset is to provide a sequence of tensors, like here:
all_data = tf.constant([['Hello', 'World'], ['Brown Fox', 'lazy dog']])
ds = tf.data.Dataset.from_tensor_slices(all_data)
for tensor in ds:
print(tensor)
which outputs
tf.Tensor([b'Hello' b'World'], shape=(2,), dtype=string)
tf.Tensor([b'Brown Fox' b'lazy dog'], shape=(2,), dtype=string)
Instead of just printing tensor, you can compute with it:
for tensor in ds:
print(hub_layer(tensor))
which outputs 2 tensors of shape (2,20) each.
For more, see https://www.tensorflow.org/guide/data.

How do you write a custom activation function in python for Keras?

I'm trying to write a custom activation function for use with Keras. I can not write it with tensorflow primitives as it does properly compute the derivative. I followed How to make a custom activation function with only Python in Tensorflow? and it works very we in creating a tensorflow function. However, when I tried putting it into Keras as an activation function for the classic MNIST demo. I got errors. I also tried the tf_spiky function from the above reference.
Here is the sample code
tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(512, activation=tf_spiky),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
Here's my entire error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-48-73a57f81db19> in <module>
3 tf.keras.layers.Dense(512, activation=tf_spiky),
4 tf.keras.layers.Dropout(0.2),
----> 5 tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
6 x=tf.keras.layers.Activation(tf_spiky)
7 y=tf.keras.layers.Flatten(input_shape=(28, 28))
/opt/conda/lib/python3.6/site-packages/tensorflow/python/training/checkpointable/base.py in _method_wrapper(self, *args, **kwargs)
472 self._setattr_tracking = False # pylint: disable=protected-access
473 try:
--> 474 method(self, *args, **kwargs)
475 finally:
476 self._setattr_tracking = previous_value # pylint: disable=protected-access
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/sequential.py in __init__(self, layers, name)
106 if layers:
107 for layer in layers:
--> 108 self.add(layer)
109
110 #property
/opt/conda/lib/python3.6/site-packages/tensorflow/python/training/checkpointable/base.py in _method_wrapper(self, *args, **kwargs)
472 self._setattr_tracking = False # pylint: disable=protected-access
473 try:
--> 474 method(self, *args, **kwargs)
475 finally:
476 self._setattr_tracking = previous_value # pylint: disable=protected-access
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/sequential.py in add(self, layer)
173 # If the model is being built continuously on top of an input layer:
174 # refresh its output.
--> 175 output_tensor = layer(self.outputs[0])
176 if isinstance(output_tensor, list):
177 raise TypeError('All layers in a Sequential model '
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)
728
729 # Check input assumptions set before layer building, e.g. input rank.
--> 730 self._assert_input_compatibility(inputs)
731 if input_list and self._dtype is None:
732 try:
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in _assert_input_compatibility(self, inputs)
1463 if x.shape.ndims is None:
1464 raise ValueError('Input ' + str(input_index) + ' of layer ' +
-> 1465 self.name + ' is incompatible with the layer: '
1466 'its rank is undefined, but the layer requires a '
1467 'defined rank.')
ValueError: Input 0 of layer dense_1 is incompatible with the layer: its rank is undefined, but the layer requires a defined rank.
From this I gather the last Dense layer is unable to get the dimensions of the output after the activation function or something to that. I did see in the tensorflow code that many activation functions register a shape. But either I'm not doing that correctly or I'm going in the wrong direction. But I'm guessing something needs to be done to the tensorflow function to make it an activation function that Keras can use.
I would appreciate any help you can give.
As requested here is the sample codes for tf_spiky, it works as described in the above reference. However, once put into Keras I get the errors shown. This is pretty much as shown in the *How to make a custom activation function with only Python in Tensorflow?" stackoverflow article.
def spiky(x):
print(x)
r = x % 1
if r <= 0.5:
return r
else:
return 0
def d_spiky(x):
r = x % 1
if r <= 0.5:
return 1
else:
return 0
np_spiky = np.vectorize(spiky)
np_d_spiky = np.vectorize(d_spiky)
np_d_spiky_32 = lambda x: np_d_spiky(x).astype(np.float32)
import tensorflow as tf
from tensorflow.python.framework import ops
def tf_d_spiky(x,name=None):
with tf.name_scope(name, "d_spiky", [x]) as name:
y = tf.py_func(np_d_spiky_32,
[x],
[tf.float32],
name=name,
stateful=False)
return y[0]
def py_func(func, inp, Tout, stateful=True, name=None, grad=None):
# Need to generate a unique name to avoid duplicates:
rnd_name = 'PyFuncGrad' + str(np.random.randint(0, 1E+8))
tf.RegisterGradient(rnd_name)(grad) # see _MySquareGrad for grad example
g = tf.get_default_graph()
with g.gradient_override_map({"PyFunc": rnd_name}):
return tf.py_func(func, inp, Tout, stateful=stateful, name=name)
def spikygrad(op, grad):
x = op.inputs[0]
n_gr = tf_d_spiky(x)
return grad * n_gr
np_spiky_32 = lambda x: np_spiky(x).astype(np.float32)
def tf_spiky(x, name=None):
with tf.name_scope(name, "spiky", [x]) as name:
y = py_func(np_spiky_32,
[x],
[tf.float32],
name=name,
grad=spikygrad) # <-- here's the call to the gradient
return y[0]
The solution is in this post Output from TensorFlow `py_func` has unknown rank/shape
The easiest fix is to add y[0].set_shape(x.get_shape()) before the return statement in the definition of tf_spiky.
Perhaps someone out there knows how to properly work with tensorflow shape functions. Digging around I found a unchanged_shape shape function in tensorflow.python.framework.common_shapes, which be appropriate here, but I don't know how to attach it to the tf_spiky function. Seems a python decorator is in order here. It would probably be a service to others to explain customizing tensorflow functions with shape functions.

Adding custom base64-string conversion layer to existing Keras model

I am trying to configure a model that I previously trained to classify images in a such a way that it accepts images as base64-strings (instead of a NumPy array), converts them to a NumPy array and then performs the prediction. How do I add a layer on top of my regular input layer that accepts strings and outputs a NumPy array?
So I've already pre-trained a model that predicts images based on the ResNet architecture. Having looked at this and this answer, I am trying to create a Lambda layer that converts strings to RGB jpeg images. I have done this as shown in the sample code below:
image = tf.placeholder(shape=[], dtype=tf.string)
input_tensor = keras.layers.Input(shape = (1,), tensor = image, dtype=tf.string)
x = keras.layers.Lambda(lambda image: tf.image.decode_jpeg(image))(input_tensor)
output_tensor = model(x)
new_model = Model(input_tensor, output_tensor)
Where model() is the Keras keras.models.Model model that I have pre-trained.
I am expecting new_model() to be the new Keras model that has 1 extra layer on top of my previous model, which accepts base64-string and outputs a NumPy array into the next layer.
However, the third line of my code raises the following error:
TypeError: Input 'contents' of 'DecodeJpeg' Op has type float32 that does not match expected type of string.
My understanding of this is that the 'image' in the Lambda layer that uses the decode_jpeg() is a float32 instead of a string, which seems odd to me as I have set the dtype of both the placeholder as well as the Input layer to tf.string.
I have searched all over stackoverflow for this but can't find a solution for this error. It appears this question also has not been able to find a solution for this specific issue.
EDIT 1: corrected typo and added full error message
The full error message is show below:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py in _apply_op_helper(self, op_type_name, name, **keywords)
509 as_ref=input_arg.is_ref,
--> 510 preferred_dtype=default_dtype)
511 except TypeError as err:
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in internal_convert_to_tensor(value, dtype, name, as_ref, preferred_dtype, ctx)
1103 if ret is None:
-> 1104 ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
1105
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in _TensorTensorConversionFunction(t, dtype, name, as_ref)
946 "Tensor conversion requested dtype %s for Tensor with dtype %s: %r" %
--> 947 (dtype.name, t.dtype.name, str(t)))
948 return t
ValueError: Tensor conversion requested dtype string for Tensor with dtype float32: 'Tensor("lambda_28/Placeholder:0", shape=(?, 1), dtype=float32)'
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
<ipython-input-47-5793b0703860> in <module>
1 image = tf.placeholder(shape=[], dtype=tf.string)
2 input_tensor = Input(shape = (1,), tensor = image, dtype=tf.string)
----> 3 x = Lambda(lambda image: tf.image.decode_jpeg(image))(input_tensor)
4 output_tensor = model(x)
5
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/keras/engine/base_layer.py in __call__(self, inputs, **kwargs)
472 if all([s is not None
473 for s in to_list(input_shape)]):
--> 474 output_shape = self.compute_output_shape(input_shape)
475 else:
476 if isinstance(input_shape, list):
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/keras/layers/core.py in compute_output_shape(self, input_shape)
650 else:
651 x = K.placeholder(shape=input_shape)
--> 652 x = self.call(x)
653 if isinstance(x, list):
654 return [K.int_shape(x_elem) for x_elem in x]
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/keras/layers/core.py in call(self, inputs, mask)
685 if has_arg(self.function, 'mask'):
686 arguments['mask'] = mask
--> 687 return self.function(inputs, **arguments)
688
689 def compute_mask(self, inputs, mask=None):
<ipython-input-47-5793b0703860> in <lambda>(image)
1 image = tf.placeholder(shape=[], dtype=tf.string)
2 input_tensor = Input(shape = (1,), tensor = image, dtype=tf.string)
----> 3 x = Lambda(lambda image: tf.image.decode_jpeg(image))(input_tensor)
4 output_tensor = model(x)
5
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/python/ops/gen_image_ops.py in decode_jpeg(contents, channels, ratio, fancy_upscaling, try_recover_truncated, acceptable_fraction, dct_method, name)
946 try_recover_truncated=try_recover_truncated,
947 acceptable_fraction=acceptable_fraction, dct_method=dct_method,
--> 948 name=name)
949 _result = _op.outputs[:]
950 _inputs_flat = _op.inputs
~/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py in _apply_op_helper(self, op_type_name, name, **keywords)
531 if input_arg.type != types_pb2.DT_INVALID:
532 raise TypeError("%s expected type of %s." %
--> 533 (prefix, dtypes.as_dtype(input_arg.type).name))
534 else:
535 # Update the maps with the default, if needed.
TypeError: Input 'contents' of 'DecodeJpeg' Op has type float32 that does not match expected type of string.

Can anyone tell me what's wrong here in cnn own model in mxnet?

def acc(output, label):
correct_preds = output.argmax(axis=1) == label.astype('float32')
return correct_preds.mean().asscalar()
for epoch in range(10):
train_loss, train_acc, valid_acc = 0., 0., 0.
tic = time()
for data, label in train_data:
data = data.copyto(mx.cpu(0))
label = label.copyto(mx.cpu(0))
with autograd.record():
output = net(data)
loss = softmax_cross_entropy(output, label)
loss.backward()
trainer.step(batch_size)
train_loss += loss.mean().asscalar()
train_acc += acc(output, label)
When running this part I get the error and my dataset is in pascol voc format
ValueError
Traceback (most recent call last)
<ipython-input-7-9926ba7deb21> in <module>()
12 label = label.copyto(mx.cpu(0))
13 with autograd.record():
---> 14 output = net(data)
15 loss = softmax_cross_entropy(output, label)
16
/home/manasi/.local/lib/python2.7/site-packages/mxnet/gluon/block.pyc in __call__(self, *args)
539 hook(self, args)
540
--> 541 out = self.forward(*args)
542
543 for hook in self._forward_hooks.values():
/home/manasi/.local/lib/python2.7/site-packages/mxnet/gluon/nn/basic_layers.pyc in forward(self, x)
51 def forward(self, x):
52 for block in self._children.values():
---> 53 x = block(x)
54 return x
55
/home/manasi/.local/lib/python2.7/site-packages/mxnet/gluon/block.pyc in __call__(self, *args)
539 hook(self, args)
540
--> 541 out = self.forward(*args)
542
543 for hook in self._forward_hooks.values():
/home/manasi/.local/lib/python2.7/site-packages/mxnet/gluon/block.pyc in forward(self, x, *args)
911 params = {i: j.data(ctx) for i, j in self._reg_params.items()}
912 except DeferredInitializationError:
--> 913 self._deferred_infer_shape(x, *args)
914 for _, i in self.params.items():
915 i._finish_deferred_init()
/home/manasi/.local/lib/python2.7/site-packages/mxnet/gluon/block.pyc in _deferred_infer_shape(self, *args)
792 error_msg = "Deferred initialization failed
because shape"\
793 " cannot be inferred. {}".format(e)
--> 794 raise ValueError(error_msg)
795
796 def _call_cached_op(self, *args):
ValueError: Deferred initialization failed because shape cannot be inferred. Error in operator conv2_fwd: [10:56:15] src/operator/nn/convolution.cc:196: Check failed: dilated_ksize_x <= AddPad(dshape[3], param_.pad[1]) (5 vs. 3) kernel size exceed input
kernel size exceed input error is usually seen when your input image is too small for the network. You either need to resize your input image, or change the network architecture to remove layers that reduce the spatial dimensions of the feature maps (e.g. pooling layers, or convolution with stride).