也许您可以创建一个由两部分组成的模型:
- 内部模型:预测期望输出的原始模型
- Outer model:
- 将 y_true 数据作为输入
- 将特征作为输入
- 输出损失本身(而不是预测数据)
所以,假设您已经拥有originalModel
定义的。让我们定义外部模型。
#this model has three inputs:
originalInputs = originalModel.input
yTrueInputs = Input(shape_of_y_train)
featureInputs = Input(shape_of_features)
#the original outputs will become an input for a custom loss layer
originalOutputs = originalModel.output
#this layer contains our custom loss
loss = Lambda(innerLoss)([originalOutputs, yTrueInputs, featureInputs])
#outer model
outerModel = Model([originalInputs, yTrueInputs, featureInputs], loss)
现在,我们自定义的内部损失:
def innerLoss(x):
y_pred = x[0]
y_true = x[1]
features = x[2]
.... calculate and return loss here ....
现在,对于这个“内部”已经包含自定义损失的模型,我们实际上并不想要最终损失函数,但由于 keras 需要它,我们将使用最终损失作为return y_pred
:
def finalLoss(true,pred):
return pred
这将使我们能够训练通过一个假人y_true
.
但当然,我们还需要一个自定义生成器,否则我们无法获得这些功能。
考虑一下你已经拥有了originalGenerator =datagen.flow(x_train, y_train, batch_size=1)
定义:
def customGenerator(originalGenerator):
while True: #keras needs infinite generators
x, y = next(originalGenerator)
features = ____extract features here____(x)
yield (x,y,features), y
#the last y will be a dummy output, necessary but not used
如果您想要随机化批次顺序并使用多重处理的额外功能,您还可以实现class CustomGenerator(keras.utils.Sequence)
遵循相同的逻辑。这帮助页面 https://keras.io/utils/显示如何。
因此,让我们编译并训练外部模型(这也会训练内部模型,以便您稍后可以使用它进行预测):
outerModel.compile(optimizer=..., loss=finalLoss)
outerModel.fit_generator(customGenerator(originalGenerator), batchesInOriginalGenerator,
epochs=...)