环境: Tensorflow2.4.1
报错: Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that you're trying to pass a symbolic value to a NumPy call, which is not supported. Or, you may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.
产生原因: 采用了tf下的Keras 自定义损函数
分析:
损失函数部分代码:
def vae_loss(x, x_decoded_mean):
xent_loss = original_dim * losses.binary_crossentropy(x, x_decoded_mean)
print(type(xent_loss))
kl_loss = -0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
print(type(kl_loss))
return xent_loss + kl_loss
这是变分自编码的自定义损失函数,从中可以发现分别得到两种张量:
xent_loss --> tensorflow.python.framework.ops.Tensor
kl_loss --> tensorflow.python.keras.engine.keras_tensor.KerasTensor
自定义函数的输入是KerasTensor,但是默认的loss函数输出的是Tensor,KerasTensor和Tensor是完全不同的类,kera_tensor源码中可以发现Keras可以将Tensor转成KerasTensor,但是没发现将KerasTensor转成Tensor的部分。。。
所以。。。我们可以说:
Tensor+KerasTensor = KerasTensor
但是keras自定义损失函数输入的是KerasTensor,默认输出的是Tensor,而这里会导致输出KerasTensor,所以就报错了。
解决方案: 我采用的解决方案如下:
# 一般情况下采用该代码能够解决问题,可以发现函数返回结果已经转化成tensorflow.python.framework.ops.Tensor类了
from tensorflow.python.framework.ops import disable_eager_execution
disable_eager_execution()
所以keras还是避免使用吧,还是用的不太灵活的亚子,我还是老老实实学明白tensorflow怎么用吧~