Reputation: 4954
I am using gaussian noise per the tf.random.normal
method (or K.random_normal
via the keras
API).
It is used from within a custom tensorflow
Layer
, which, in turn, is used by a custom Model
.
For some reason, everything works as intended when calling the layer / model directly, or when using a custom training loop via tf.GradientTape()
, but it throws a puzzling error when attempting to use the fit
method instead.
It appears to have something to do with inferring the batch dimension, which presents as None
when calling the fit
method.
I suspect this has something to do with compilation and symbolic tensors vs. eager tensors, but I'm none-the-wiser as to how this would actually be resolved?
I've tried to strip the problem down to a minimal example that reproduces the issue:
import numpy as np
import tensorflow.keras.backend as K
from tensorflow.keras import models
import tensorflow as tf
class Demo(models.Model):
def __init__(self):
super().__init__()
def call(self, inputs, training=None, mask=None):
# batch gives "2" when called directly or via GradientTape()
# gives "None" when called via fit
batch = K.int_shape(inputs)[0]
dim = K.int_shape(inputs)[1]
noise = tf.random.normal(shape=(batch, dim), mean=0.0, stddev=1.0)
# manually specifying the batch dimension does work, e.g.
# noise = tf.random.normal(shape=(2, dim), mean=0.0, stddev=1.0)
return inputs * noise
test_data = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]])
tester = Demo()
tester.compile(optimizer='adam')
# manual calling works
print(test_data - tester(test_data))
# but calling fit does not
tester.fit(x=test_data)
# raises: TypeError: Failed to convert object of type <class 'tuple'> to Tensor.
# Contents: (None, 4). Consider casting elements to a supported type.
Any suggestions for what the problem might be?
Upvotes: 1
Views: 1093
Reputation: 1377
In the call
method, instead of using keras.backend
to get batch
and dim
, use tensorflow directly.
batch = tf.shape(inputs)[0]
dim = tf.shape(inputs)[1]
Upvotes: 1