【发布时间】:2019-08-30 13:13:52
【问题描述】:
我正在尝试在 keras 中编写自定义损失函数,该函数基于训练期间模型的多次预测。 我有一个以前的列表/字典,例如 dict = {X1: [X2,X3,X4], X2:[X1, X6, X7]} 等。
给定输入 X1,我需要在训练期间预测 X2、X3、X4。
model.predict 不工作,报错 ValueError:将符号张量提供给模型时,我们希望张量具有静态批量大小。得到具有形状的张量:(None, 36)
from keras.layers import *
from keras.models import Model
import keras.backend as K
input_tensor = Input(shape=(36,))
hidden = Dense(100, activation='relu')(input_tensor)
out = Dense(1, activation='linear')(hidden)
def custom_loss(input_tensor, dict):
def inner(y_true, y_pred):
X2 = dict[input_tensor][0]
X3 = dict[input_tensor][1]
X4 = dict[input_tensor][2]
X2_pred = model.predict(X2)
X3_pred = model.predict(X3)
X4_pred = model.predict(X4)
return K.mean(max(X2_pred, X3_pred, X4_pred)-y_true)
return inner
custom_loss_final = custom_loss(input_tensor = input_tensor, dict = dict)
model = Model(input_tensor, out)
model.compile(loss = custom_loss_final, optimizer='adam')
model.fit(x = Train_X, y = Train_y, batch_size= 100)
根据 Anakin 的解决方案进行编辑: 我试过你的代码,实际上在 np.append 我需要使用axis = 0。
现在我有: INPUT_X.shape (100, 36) INPUT_Y.shape (100,3,36)
INPUT_X:我有 100 个训练样本,每个都是 36 len 数组。
INPUT_Y:这些是 X2、X3 等。
实际上我的代码中甚至不需要 Y_true,因为我将使用模型(X2)等。
我按照你的建议将它们传递给 model.fit,在损失函数中我打印了一些类型/形状:
(输入张量)
(?, 36)
("y_true")
(?, ?)
(pred_y)
(?, 1)
我不知道为什么 y_true 形状是 (?,?) 而不是 (3,36)。我不能放模型(pred_y[:,0]),因为我得到:
ValueError:形状必须为 2 级,但对于“loss_56/dense_114_loss/model_57/dense_113/MatMul”(操作:“MatMul”)的输入形状为 1 级:[?]、[36,300]。
##为了清楚起见,现在隐藏层的大小是 300。
【问题讨论】:
-
我不确定您到底想做什么。您想在自定义损失中使用输入张量吗?
-
我想使用输入张量来查找 X2,X3,X4,但是正如您在下面建议的那样,直接使用 Train_X 传递会更容易,而不是在里面寻找它。
-
您能否在类似于我的
extra = data[:, 1:]的自定义损失函数中以 numpy 数组的形式获取额外数据?你可以做x2 = data[ :, 0, :],x3 = data[:. 1, :]。验证检查切片。那么也许你需要将它们重塑为 (100, 36)。这是我的直觉。 -
我想你的每个 X2、X3 等都有
(None, 36)的形状 -
不完全是,X2、X3 等具有 (36,) 形状。 (100,3,36) 表示 100 个训练样本,每个有 3 个 X-es,每个有 36 个 len。我在将张量 int 转换为数组时遇到问题(而且我不知道为什么要这样做,因为我可以 model() 一个张量。主要问题是它以错误的形式传递给函数(?,?形状,而不是 ? 36)
标签: python-3.x keras