![](/img/trans.png)
[英]Inputs to eager execution function cannot be Keras symbolic tensors, but found
[英]Inputs to eager execution function cannot be Keras symbolic tensors
我正在嘗試在tf.Keras
(TensorFlow 2.0.0rc0) 中為具有稀疏注釋數據的 3-D U-Net (Cicek 2016, arxiv:1606.06650) 實現依賴於tf.Keras
和像素的相關損失加權。
這是我的代碼:
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.')
這在禁用 Eager Execution 時運行良好,但 TensorFlow 2 的要點之一是默認情況下具有 Eager Execution。 正如你所看到的,我和那個目標之間的區別是自定義損失函數(使用'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>]
我該怎么做才能使這種結構與急切執行一起工作?
我的一個想法是將w
連接到輸出y
並將y_pred
分離為損失函數中的原始y_pred
和w
,但這是我想避免的一種黑客行為。 不過,它的工作原理是用# 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.')
還有其他想法嗎?
一種替代解決方案是將權重作為附加輸出特征而不是輸入特征傳遞。
這使模型完全沒有任何與權重相關的東西,權重只出現在損失函數和.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)
一個缺點仍然是,在numpy.stack()
合並y
和w
時,您需要操作(可能)大型數組,因此將不勝感激更多類似 TensorFlow 的方法。
其它的辦法:
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))
我認為這是最優雅的解決方案。
如果您將 fit 行替換為
model.fit((data_x, data_y, data_w))
所以:
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.')
此外,我發現在損失函數中實現的 tf.reduce_mean、K.mean、tf.square、tf.exp 等會導致相同的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.