python - 将张量元组传递给多个损失函数时,Tensorflow/keras 仅使用 .fit 传递元组中的一个张量
问题描述
训练数据的形状为:
pred: [
([batch], 52, 52, 3, 6),
([batch], 26, 26, 3, 6),
([batch], 13, 13, 3, 6),
]
true: [
[
([batch], 52, 52, 3, 6),
([batch], 128, 4),
],
[
([batch], 26, 26, 3, 6),
([batch], 128, 4),
],
[
([batch], 13, 13, 3, 6),
([batch], 128, 4),
]
]
我有 3 个输出,并通过将损失列表传递给 model.compile 为每个输出指定了一个损失函数。问题是在训练时,损失函数只接收到它应该接收的两个值之一。当我手动调用它时,它工作正常。
例如:与
model.compile(
optimizer=tf.optimizers.Adam(),
loss = losses
)
这会产生正确的行为
losses[0](y[0], model(x)[0])
这个的输出:
def loss(target, output):
print(output.shape)
print(target[0].shape)
print(target[1].shape)
是:
(1, 52, 52, 18)
(1, 52, 52, 3, 6)
(1, 128, 4)
但是当使用以下方法调用损失时:
model.fit(x,y,batch_size=1)
我得到这些尺寸:
(1, 52, 52, 18)
(52, 52, 3, 6)
然后这个错误:
ValueError: slice index 1 of dimension 0 out of bounds
建议在通过 .fit 调用时,一次只传递元组中的一个张量
我真的很想避免自定义训练循环以利用回调等功能。所以有没有办法一次将两个张量传递给元组中的损失函数?
解决方案
这重现了这个问题:
import tensorflow as tf
import numpy as np
x = tf.data.Dataset.from_tensor_slices(np.full((100,1), 1.0))
y0 = tf.data.Dataset.from_tensor_slices(np.full((100,1), 2.0))
y1 = tf.data.Dataset.from_tensor_slices(np.full((100,1), 3.0))
y = tf.data.Dataset.zip((y0, y1))
train_data = tf.data.Dataset.zip((x, y))
inputs = tf.keras.Input(shape=(1,))
outputs = tf.keras.layers.Dense(1)(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
def myloss(y_true, y_pred):
y0 = y_true[0]
y1 = y_true[1]
return tf.reduce_mean((y0 - y_pred)**2 + 0.5*(y1 - y_pred)**2)
model.compile(tf.keras.optimizers.Adam(), loss=myloss)
model.fit(train_data, epochs=1)
这里的目标 y 是一个元组,但是当将它传递给损失函数 model.fit 时,它只包含元组的第一个元素。
推荐阅读
- php - 我的网络表单中的蜜罐似乎并没有阻止机器人提交
- c++ - 有什么技巧可以避免模板类中的“typename”关键字?
- r - 'x' 和 'y' 长度在自定义熵函数中不同
- docker - 我在通过命令在 ejabberd 中注册管理员用户时遇到错误(“无效字符 '<' 寻找值的开头”)?
- python - 需要给句子中的字母和非字母分配不同的值
- javascript - 如何使用 CSS 定位/对齐按钮
- azure - docker swarm - 无法连接到服务
- java - 无法使用 mongodb Java 驱动程序初始化类 com.mongodb.connection.MongoQueryAnalyzer
- c++ - MSVC UTF8 字符串编码使用不正确的代码点
- generics - 对 Kotlin 何时推断平台类型感到困惑