ValueError: Tried to convert 'y' to a tensor and failed. Error: None values not supported

ValueError: Tried to convert 'y' to a tensor and failed. Error: None values not supported

不起作用:

from tensorflow.python.keras.layers import Input, Dense
from tensorflow.python.keras.models import Model
from tensorflow.python.keras.optimizers import Nadam
import numpy as np

ipt = Input(shape=(4,))
out = Dense(1, activation='sigmoid')(ipt)

model = Model(ipt, out)
model.compile(optimizer=Nadam(lr=1e-4), loss='binary_crossentropy')

X = np.random.randn(32,4)
Y = np.random.randint(0,2,(32,1))
model.train_on_batch(X,Y)

WORKS:从上面的导入中删除 .python

这是怎么回事,如何解决?


附加信息


调试 1:文件差异

这适用于我的本地安装,而不是 TF 的 Github 分支 masterr2.0; Github files 由于某种原因缺少 api/_v2:

from tensorflow import keras
print(keras.__file__)
from tensorflow.python import keras
print(keras.__file__)
[1] D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\keras\api\_v2\keras\__init__.py
[2] D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\keras\__init__.py

查看 __init__ 的每个 Optimizer

# [1]
from tensorflow.python.keras.optimizer_v2.optimizer_v2 import OptimizerV2 as Optimizer
# [2]
from tensorflow.python.keras import optimizers

# in python.keras.optimizers.py:
# all imports are from tensorflow.python
class Optimizer(object): # <--- does NOT use optimizer_v2 for Optimizer

这似乎是问题的根源,如下所示:

from tensorflow.python.keras.layers import Input, Dense
from tensorflow.python.keras.models import Model
from tensorflow.keras.optimizers import Nadam

然而,这很奇怪,因为直接 import keras 也不使用 optimizer_v2,尽管 keras.optimizersOptimizer 的定义确实不同。


调试 2:执行差异

并行调试,虽然两者使用相同的 training.py,但执行差异相当快:

### TF.KERAS
    if self._experimental_run_tf_function: #  TRUE
### TF.PYTHON.KERAS
    if self._experimental_run_tf_function: #  FALSE

前者在最终失败之前继续调用 training_v2_utils.train_on_batch(...) 和 returns,后者 self._standardize_user_data(...) 和其他人。


调试 3(+ 解决方案?):失败线

if None in grads: # <-- in traceback

在其正上方插入 print(None in grads) 会产生完全相同的错误 - 因此,它似乎与 TF2 可迭代操作相关 - 这有效:

if any([g is None for g in grads]): # <-- works; similar but not equivalent Python logic

不确定它是否是一个完整的修复程序,仍在调试 -- 更新:启动了 Github Pull Request


完整错误跟踪:

  File "<ipython-input-1-2db039c052cf>", line 20, in <module>
    model.train_on_batch(X,Y)
  File "D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 1017, in train_on_batch
    self._make_train_function()
  File "D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2116, in _make_train_function
    params=self._collected_trainable_weights, loss=self.total_loss)
  File "D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\keras\optimizers.py", line 653, in get_updates
    grads = self.get_gradients(loss, params)
  File "D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\keras\optimizers.py", line 92, in get_gradients
    if None in grads:
  File "D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\ops\math_ops.py", line 1336, in tensor_equals
    return gen_math_ops.equal(self, other)
  File "D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\ops\gen_math_ops.py", line 3626, in equal
    name=name)
  File "D:\Anaconda\envs\tf2_env\lib\site-packages\tensorflow_core\python\framework\op_def_library.py", line 545, in _apply_op_helper
    (input_name, err))

ValueError: Tried to convert 'y' to a tensor and failed. Error: None values not supported.

这是一个错误,我的 pull request fix was approved (but isn't yet merged). In the meantime, you can make the change manually, as here. Also, tf.python.keras isn't always meant to be used, if

更新:拉取请求现在是 merged


为什么有效None in gradsany(g == None for g in grads) 相同;问题是,g 可能是一个 tf.Tensor/tf.Variable,其中 .__eq__ 定义为仅对张量进行操作,因此必须使用 is None 代替。

from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
import numpy as np

ipt = Input((16,))
out = Dense(16)(ipt)
model = Model(ipt, out)
model.compile('adam', 'mse')

x = y = np.random.randn(32, 16)
model.train_on_batch(x, y)

W = model.optimizer.weights
W[0] == None
>>> ValueError: Attempt to convert a value (None) with an unsupported type 
    (<class 'NoneType'>) to a Tensor.

检查源代码:

from inspect import getsource
print(getsource(W[0].__eq__))
def __eq__(self, other):
    """Compares two variables element-wise for equality."""
    if ops.Tensor._USE_EQUALITY and ops.executing_eagerly_outside_functions():
        return gen_math_ops.equal(self, other, incompatible_shape_error=False)
    else:
        # In legacy graph mode, tensor equality is object equality
        return self is other

也许你应该更正你的导入

from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Nadam