Open Johansmm opened 1 week ago
Hi @Johansmm -
Thanks for reporting the issue. Here in your code there are multiple corrections required.
If you want to create MaskedTensor using ExtensionType, then you can can use it like this:
class MaskedTensor(tf.experimental.ExtensionType):
"""A tensor paired with a boolean mask, indicating which values are valid."""
values: tf.Tensor
mask: tf.Tensor
shape
and dtype
argument from input_spec
x = tf.keras.layers.Input(type_spec=input_spec)
, Input layer doesn't have type_spec
argument. So need to correct like this: x = tf.keras.layers.Input(batch_size=2,shape=(10,5))
.Attached gist for your reference.
Hi @mehtamansi29 thanks for your response. However, I don't think I have been clear in explaining what the purpose of the code is: I want to know how I can write RNN models with custom cell that works with Extension types tensors.
For this, I have written the example to show my problem based on :
tf.keras.layer.Input
with Extension type through type_spec
field (as I made in the example). Note in the guide is marked : 'They must have a field or property named shape. shape[0] is assumed to be the batch dimension.'I hope that my model can make inferences with MaskedTensor
inputs, but with the corrections you make the following code does not work:
import tensorflow as tf
mt = MaskedTensor(tf.random.uniform((2,10,5)), tf.ones((2,10,5)))
model(mt)
Error:
ValueError: Exception encountered when calling Functional.call().
Attempt to convert a value (MaskedTensor(values=<tf.Tensor: shape=(2, 10, 5), dtype=float32, numpy=
array([[[0.28294933, 0.89941823, 0.6277088 , 0.3004167 , 0.4065286 ],
[0.59596014, 0.7929536 , 0.6331537 , 0.15866613, 0.29780304],
[0.31396973, 0.87872875, 0.13612425, 0.7689322 , 0.6524085 ],
[0.65356696, 0.74440706, 0.381616 , 0.3481027 , 0.44483578],
[0.2988621 , 0.0631609 , 0.5148549 , 0.89417315, 0.4907987 ],
[0.23625493, 0.78680897, 0.6701437 , 0.2609341 , 0.16422784],
[0.09855855, 0.5578295 , 0.8797028 , 0.17377365, 0.9087467 ],
[0.91141987, 0.7385657 , 0.5835092 , 0.5579853 , 0.8384237 ],
[0.08012462, 0.56617975, 0.700922 , 0.18580115, 0.61618245],
[0.47631788, 0.3428775 , 0.1811893 , 0.2038809 , 0.19900978]],
[[0.4667045 , 0.64295805, 0.35533714, 0.46243107, 0.28277063],
[0.3471583 , 0.32578683, 0.39409876, 0.5108174 , 0.3006178 ],
[0.5338242 , 0.23265481, 0.06676841, 0.6289011 , 0.10211515],
[0.9826255 , 0.50816226, 0.995906 , 0.28830194, 0.7350259 ],
[0.20371187, 0.75276816, 0.03341246, 0.22956371, 0.14091146],
[0.5101521 , 0.5355145 , 0.77825236, 0.11842644, 0.09967971],
[0.5528343 , 0.12923944, 0.9135002 , 0.31218648, 0.09520006],
[0.6237818 , 0.46556568, 0.45628858, 0.22421765, 0.6033968 ],
[0.10589111, 0.08551514, 0.20975125, 0.5542921 , 0.14889371],
[0.04052258, 0.3114897 , 0.3219484 , 0.05069757, 0.7502247 ]]],
dtype=float32)>, mask=<tf.Tensor: shape=(2, 10, 5), dtype=float32, numpy=
array([[[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]],
[[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]]], dtype=float32)>, shape=TensorShape([2, 10, 5]))) with an unsupported type (<class '__main__.MaskedTensor'>) to a Tensor.
I hope that the purpose of my question is clearer.
Hi @Johansmm -
Here is the reference where you can create custom RNN layer using subclassing.
And for creating RNN models with custom cell that works with Extension types tensors.
class MaskedTensor(tf.experimental.ExtensionType):
"""A tensor paired with a boolean mask, indicating which values are valid."""
values: tf.Tensor
mask: tf.Tensor
@keras.saving.register_keras_serializable()
class RNNCell(keras.layers.Layer):
def __init__(self, units, **kwargs):
super().__init__(**kwargs)
self.units = units
self.state_size = units
def build(self, input_shape):
self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
initializer='uniform',
name='kernel')
self.recurrent_kernel = self.add_weight(
shape=(self.units, self.units),
initializer='uniform',
name='recurrent_kernel')
self.built = True
def call(self, inputs, states):
prev_output = states[0]
h = ops.matmul(inputs, self.kernel)
output = h + ops.matmul(prev_output, self.recurrent_kernel)
return output, [output]
batch_size= 32
input_shape = (10,)
input= keras.Input(shape=input_shape,batch_size=batch_size)
values= tf.random.normal(shape=(batch_size, 10))
mask= tf.random.uniform(shape=(batch_size, 10)) > 0.5
input_spec= MaskedTensor(values=values, mask=mask)
print(type(input_spec))
rnn= keras.layers.RNN(RNNCell(units=32))(input)
model = keras.models.Model(input,rnn)
model.summary()
Attached gist for the reference.
Hi @mehtamansi29, I do not thing to understand your example, because you are creating a RNNCell
layer that does not use MaskedTensor in call(). I think the two topics are being separated, but my goal is to write an RNNCell layer whose inputs/states are MaskedTensor.
With your example it is not possible to make an inference with _inputspec:
y = model(input_spec)
# Raise the following error:
# ValueError: Inputs to a layer should be tensors. Got 'MaskedTensor ....
Issue type
Feature Request
Have you reproduced the bug with TensorFlow Nightly?
Yes
Source
source
TensorFlow version
2.15
Custom code
Yes
OS platform and distribution
Windows 11
Mobile device
No response
Python version
3.11
Bazel version
No response
GCC/compiler version
No response
CUDA/cuDNN version
No response
GPU model and memory
No response
Current behavior?
I want to write a Keras-like model with keras.layers.RNN that supports Extension types, both for inputs and states.
Standalone code to reproduce the issue
Relevant log output