无法将“auto”转换为 dtype float 的 EagerTensor

Sha*_*dri 6 python keras tensorflow

我创建了一个dataset有 27 列的。我创建了一个Autoencoder用于异常检测的目的,如下所示:

input_layer = Input(shape=(27,))

x = layers.Dense(20,activation='relu')(input_layer)
x = layers.Dense(14,activation='relu')(x)
x = layers.Dense(8, activation='relu')(x)
x = layers.Dense(14, activation='relu')(x)
x = layers.Dense(20,activation='relu')(x)

output = layers.Dense(27,activation='relu')(x)

AE = keras.models.Model(inputs=input_layer, outputs=output)

optimizer = keras.optimizers.Adam() 

loss_fn = keras.losses.MeanSquaredError

iterator = iter(train_dataset) 
a = iterator.get_next() 
out = AE(a,training=True)
loss_value = loss_fn(a, out)
Run Code Online (Sandbox Code Playgroud)

为什么会出现以下错误?

TypeError: Cannot convert 'auto' to EagerTensor of dtype float
Run Code Online (Sandbox Code Playgroud)

Bre*_*eno 7

免责声明

这个答案假设我们最初写的是:

import tensorflow
from tensorflow import keras
Run Code Online (Sandbox Code Playgroud)

请注意,如果没有任何示例数据,则很难确定这实际上适用于您的情况。但我通过了解以下内容解决了产生相同错误的问题。

解决方案 1:使用 MeanSquaredError 类

根据tensorflow网站的说法,出现这个问题是因为它keras.losses.MeanSquaredError是一个类。因此,您必须首先使用括号实例化它,而不是像它是一个函数一样给它起别名。()

因此,以下行解决了该问题:

loss_fn = keras.losses.MeanSquaredError()
Run Code Online (Sandbox Code Playgroud)

解决方案2:使用MSE函数

另一种选择是别名,根据该站点keras.losses.MSE这是 的别名。如果查看源代码,您可以看到这是任何类定义之外的函数。keras.metrics.mean_squared_error

因此,以下行解决了该问题:

loss_fn = keras.losses.MSE
Run Code Online (Sandbox Code Playgroud)

重要提示:两种解决方案会产生不同的结果

如果输入有多于一维,则上述两个解决方案的输出不相同。第一个生成标量,第二个生成数组。为了使它们相同,您必须:

  • 在解决方案 1 中实例化类时传递NONE类型缩减。损失值现在是一个数组。
loss_fn = keras.losses.MeanSquaredError(reduction=keras.losses.Reduction.NONE)
Run Code Online (Sandbox Code Playgroud)

或者

  • 另外,从解决方案 2 中损失函数的输出中取平均值。损失值现在是一个标量。
loss_value = tensorflow.reduce_mean(loss_fn(a, out))
Run Code Online (Sandbox Code Playgroud)