简体   繁体   English

急切执行函数的输入不能是 Keras 符号张量

[英]Inputs to eager execution function cannot be Keras symbolic tensors

I am trying to implement sample- and pixel-dependent dependent loss weighting in tf.Keras (TensorFlow 2.0.0rc0) for a 3-D U-Net with sparse annotation data (Cicek 2016, arxiv:1606.06650).我正在尝试在tf.Keras (TensorFlow 2.0.0rc0) 中为具有稀疏注释数据的 3-D U-Net (Cicek 2016, arxiv:1606.06650) 实现依赖于tf.Keras和像素的相关损失加权。

This is my code:这是我的代码:

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, losses, models

# disabling eager execution makes this example work:
# tf.python.framework_ops.disable_eager_execution()


def get_loss_fcn(w):
    def loss_fcn(y_true, y_pred):
        loss = w * losses.mse(y_true, y_pred)
        return loss
    return loss_fcn


data_x = np.random.rand(5, 4, 1)
data_w = np.random.rand(5, 4)
data_y = np.random.rand(5, 4, 1)

x = layers.Input([4, 1])
w = layers.Input([4])
y = layers.Activation('tanh')(x)
model = models.Model(inputs=[x, w], outputs=y)
loss = get_loss_fcn(model.input[1])

# using another loss makes it work, too:
# loss = 'mse'

model.compile(loss=loss)
model.fit((data_x, data_w), data_y)

print('Done.')

This runs fine when disabling eager execution, but one of the points of TensorFlow 2 is to have eager execution by default.这在禁用 Eager Execution 时运行良好,但 TensorFlow 2 的要点之一是默认情况下具有 Eager Execution。 What stands between me and that goal is the custom loss function, as you can see (using 'mse' as a loss removes that error, too):正如你所看到的,我和那个目标之间的区别是自定义损失函数(使用'mse'作为损失也消除了该错误):

  File "MWE.py", line 30, in <module>
    model.fit((data_x, data_w), data_y)
[...]
tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'input_2:0' shape=(None, 4) dtype=float32>]

What can I do to make this kind of structure work with eager execution?我该怎么做才能使这种结构与急切执行一起工作?

One idea that I had was to concatenate w to the output y and separate y_pred into the original y_pred and w in the loss function, but this is a hack I'd like to avoid.我的一个想法是将w连接到输出y并将y_pred分离为损失函数中的原始y_predw ,但这是我想避免的一种黑客行为。 It works, though, with changes marked by # HERE :不过,它的工作原理是用# HERE标记的更改:

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, losses, models


# HERE
def loss_fcn(y_true, y_pred):
    w = y_pred[:, :, -1]  # HERE
    y_pred = y_pred[:, :, :-1]  # HERE
    loss = w * losses.mse(y_true, y_pred)
    return loss


data_x = np.random.rand(5, 4, 1)
data_w = np.random.rand(5, 4, 1)  # HERE
data_y = np.random.rand(5, 4, 1)

x = layers.Input([4, 1])
w = layers.Input([4, 1])  # HERE
y = layers.Activation('tanh')(x)
output = layers.Concatenate()([y, w])  # HERE
model = models.Model(inputs=[x, w], outputs=output)  # HERE
loss = loss_fcn  # HERE

model.compile(loss=loss)
model.fit((data_x, data_w), data_y)

print('Done.')

Any other ideas?还有其他想法吗?

One alternative solution is to pass weights as additional output features rather than input features.一种替代解决方案是将权重作为附加输出特征而不是输入特征传递。

This keeps the model completely free of anything weights related, and the weights appear only in the loss function and the .fit() call:这使模型完全没有任何与权重相关的东西,权重只出现在损失函数和.fit()调用中:

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, losses, models

data_x = 2 * np.ones((7, 11, 15, 3), dtype=float)
data_y = 5 * np.ones((7, 9, 13, 5), dtype=float)

x = layers.Input(data_x.shape[1:])
y = layers.Conv2D(5, kernel_size=3)(x)
model = models.Model(inputs=x, outputs=y)


def loss(y_true, y_pred):
    (y_true, w) = tf.split(y_true, num_or_size_splits=[-1, 1], axis=-1)
    loss = tf.squeeze(w, axis=-1) * losses.mse(y_true, y_pred)

    tf.print(tf.math.reduce_mean(y_true), "== 5")
    tf.print(tf.math.reduce_mean(w), "== 3")

    return loss


model.compile(loss=loss)

data_w = 3 * np.ones((7, 9, 13, 1), dtype=float)
data_yw = np.concatenate((data_y, data_w), axis=-1)
model.fit(data_x, data_yw)

One drawback still is that you need to manipulate (potentially) large arrays when merging y and w in numpy.stack() , so anymore more TensorFlow-like will be appreciated.一个缺点仍然是,在numpy.stack()合并yw时,您需要操作(可能)大型数组,因此将不胜感激更多类似 TensorFlow 的方法。

Another way:其它的办法:

from tensorflow.keras import layers, models, losses
import numpy as np

def loss_fcn(y_true, y_pred, w):
    loss = w * losses.mse(y_true, y_pred)
    return loss


data_x = np.random.rand(5, 4, 1)
data_w = np.random.rand(5, 4)
data_y = np.random.rand(5, 4, 1)

x = layers.Input([4, 1])
y_true = layers.Input([4, 1])
w = layers.Input([4])
y = layers.Activation('tanh')(x)


model = models.Model(inputs=[x, y_true, w], outputs=y)
model.add_loss(loss_fcn(y, y_true, w))


model.compile()
model.fit((data_x, data_y, data_w))

I think this is the most elegant solution.我认为这是最优雅的解决方案。

Your code works just fine with latest tensorflow (2.3) if you replace your fit row with如果您将 fit 行替换为

model.fit((data_x, data_y, data_w))

So:所以:

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, losses, models


# HERE
def loss_fcn(y_true, y_pred):
    w = y_pred[:, :, -1]  # HERE
    y_pred = y_pred[:, :, :-1]  # HERE
    loss = w * losses.mse(y_true, y_pred)
    return loss


data_x = np.random.rand(5, 4, 1)
data_w = np.random.rand(5, 4, 1)  # HERE
data_y = np.random.rand(5, 4, 1)

x = layers.Input([4, 1])
w = layers.Input([4, 1])  # HERE
y = layers.Activation('tanh')(x)
output = layers.Concatenate()([y, w])  # HERE
model = models.Model(inputs=[x, w], outputs=output)  # HERE
loss = loss_fcn  # HERE

model.compile(loss=loss)
model.fit((data_x, data_y, data_w))

print('Done.')

Further, I found tf.reduce_mean, K.mean, tf.square, tf.exp etc. implemented in a loss funtion cause the same error.此外,我发现在损失函数中实现的 tf.reduce_mean、K.mean、tf.square、tf.exp 等会导致相同的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 急切执行 function 的输入不能是 Keras 符号张量,但可以找到 - Inputs to eager execution function cannot be Keras symbolic tensors, but found 在 Keras 中训练变分自动编码器引发“SymbolicException:急切执行 function 的输入不能是 Keras 符号张量” - Training Variational Autoencoder in Keras raises “SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors” 无法将数据输入自定义损失:急切执行 function 的输入不能是 Keras 符号张量 - Can't input data to custom loss: Inputs to eager execution function cannot be Keras symbolic tensors 自定义损失问题:急切执行的输入 function 不能是 keras 符号张量但找到 - Custom loss problem: inputs to eager execution function cannot be keras symbolic tensors but found tf.keras 两个损失,中间层作为其中一个的输入错误:急切执行的输入 function 不能是 Keras 符号张量 - tf.keras two losses, with intermediate layers as input to of one of them error:Inputs to eager execution function cannot be Keras symbolic tensors 自定义损失 function Tensorflow 2 [Keras 符号输入/输出未实现] - Custom loss function Tensorflow 2 [Keras symbolic inputs/outputs do not implement] 在Keras中使用2个张量输入定义自定义层 - Define a custom layer with 2 tensors inputs in Keras 使用 Tensorflow 2.0 和没有 Keras 的急切执行 - Using Tensorflow 2.0 and eager execution without Keras Keras 的 TensorFlow 后端是否依赖于 Eager Execution? - Does the TensorFlow backend of Keras rely on the eager execution? 急于执行时,Tensor对象不可迭代…使用Keras形状函数时 - Tensor Objects are not iterable when eager execution… while using Keras shape function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM