我使用了tf.random.normal
方法(或通过keras
API 的K.random_normal
)来生成高斯噪声。
它在自定义的tensorflow
Layer
中使用,而该Layer
又被自定义的Model
使用。
不知为何,直接调用层/模型,或者通过tf.GradientTape()
使用自定义训练循环时,一切正常工作,但尝试使用fit
方法时却抛出了一个令人困惑的错误。
这似乎与推断批次维度有关,在调用fit
方法时,批次维度显示为None
。
我怀疑这与编译以及符号张量和急切张量有关,但我并不清楚如何实际解决这个问题?
我尝试将问题简化为一个最小示例来重现这个问题:
import numpy as npimport tensorflow.keras.backend as Kfrom tensorflow.keras import modelsimport tensorflow as tfclass Demo(models.Model): def __init__(self): super().__init__() def call(self, inputs, training=None, mask=None): # 直接调用或通过GradientTape()时,batch给出“2” # 通过fit调用时,batch给出“None” 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) # 手动指定批次维度是可以工作的,例如 # noise = tf.random.normal(shape=(2, dim), mean=0.0, stddev=1.0) return inputs * noisetest_data = np.array([[1., 2., 3., 4.], [5., 6., 7., 8.]])tester = Demo()tester.compile(optimizer='adam')# 手动调用正常工作print(test_data - tester(test_data))# 但调用fit则不行tester.fit(x=test_data)# 引发: TypeError: Failed to convert object of type <class 'tuple'> to Tensor.# Contents: (None, 4). Consider casting elements to a supported type.
有什么建议可以解决这个问题吗?
回答:
在call
方法中,不要使用keras.backend
来获取batch
和dim
,而是直接使用tensorflow。
batch = tf.shape(inputs)[0]dim = tf.shape(inputs)[1]