我想定义一个自定义成本函数
def custom_objective(y_true, y_pred):
....
return L
不仅取决于y_true
和y_pred
,还取决于生成x
的相应y_pred
的某些功能。我能想到这样做的唯一方法是“隐藏”y_true
中的相关功能,以便y_true = [usual_y_true, relevant_x_features]
或类似的内容。
我在实施这个问题时遇到两个主要问题:
1)改变y_true
的形状意味着我需要用一些垃圾填充y_pred
,以便它们的形状相同。我可以通过模仿我模型的最后一层来做到这一点
2)我像这样使用数据扩充:
datagen = ImageDataGenerator(preprocessing_function=my_augmenter)
其中my_augmenter()
是一个函数,它还应该为我提供在x
上面使用的相关custom_objective()
功能。但是,培训
model.fit_generator(datagen.flow(x_train, y_train, batch_size=1), ...)
似乎无法让我访问使用my_augmenter
计算的功能。
我想我可以隐藏增强版x_train
中的功能,在我的模型设置中立即复制它们,然后直接将它们反馈到y_true
或类似的东西,但肯定必须有更好的方法吗?
答案 0 :(得分:2)
也许你可以创建一个两部分模型:
因此,假设您已经定义了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)
。 help page显示了如何。
所以,让我们编译和训练外部模型(这也训练内部模型,以便您以后可以使用它进行预测):
outerModel.compile(optimizer=..., loss=finalLoss)
outerModel.fit_generator(customGenerator(originalGenerator), batchesInOriginalGenerator,
epochs=...)