如何在发生器提供的Keras自定义损失函数中访问样本权重?

时间:2019-09-18 18:58:00

标签: python tensorflow keras deep-learning loss-function

我有一个生成器函数,可以无限循环浏览某些目录的图像,并以表格形式输出三元组的批处理

[img1, img2], label, weight

其中img1img2batch_size x M x N x 3张量,labelweight分别是batch_size x 1张量。

在使用Keras训练模型时,我将此生成器提供给fit_generator函数。

对于此模型,我有一个自定义余弦对比损失函数,

def cosine_constrastive_loss(y_true, y_pred):
    cosine_distance = 1 - y_pred
    margin = 0.9
    cdist = y_true * y_pred + (1 - y_true) * keras.backend.maximum(margin - y_pred, 0.0)
    return keras.backend.mean(cdist)

结构上,一切正常。没有错误,它正在按预期使用生成器的输入和标签。

但是现在我正在寻求直接使用每批次的权重参数,并根据特定于样本的权重在cosine_contrastive_loss内部执行一些自定义的逻辑。

在执行损失函数时,如何从一批样本的结构中访问此参数?

请注意,由于它是一个无限循环的生成器,因此不可能预先计算权重或实时计算权重以将权重引入损失函数或生成它们。

必须与生成的样本一致地生成它们,并且确实在我的数据生成器中存在自定义逻辑,该逻辑根据img1img2和{{1}的属性动态确定权重目前,它们是为一批生成的。

2 个答案:

答案 0 :(得分:2)

手动训练循环替代方法

我唯一能想到的是手动训练循环,您可以自己获得重量。

具有权重张量和不变的批量大小:

weights = K.variable(np.zeros((batch_size,)))

在您的自定义损失中使用它们:

def custom_loss(true, pred):
    return someCalculation(true, pred, weights)

对于“发电机”:

for e in range(epochs):
    for s in range(steps_per_epoch):
        x, y, w = next(generator) #or generator.next(), not sure
        K.set_value(weights, w)

        model.train_on_batch(x, y)

对于keras.utils.Sequence

for e in range(epochs):
    for s in range(len(generator)):
        x,y,w = generator[s]

        K.set_value(weights, w)
        model.train_on_batch(x,y)

我知道这个答案不是最佳的,因为它不会像fit_generator那样并行化从生成器获取数据。但这是我能想到的最好的简单解决方案。 Keras没有公开权重,它们会自动应用于某些隐藏的源代码中。


让模型计算权重替代方案

如果可以从xy中计算权重,则可以将此任务委托给损失函数本身。

这有点骇人听闻,但可能有效:

input1 = Input(shape1)
input2 = Input(shape2)

# .... model creation .... #

model = Model([input1, input2], outputs)

让损失者可以使用input1input2

def custom_loss(y_true, y_pred):
    w = calculate_weights(input1, input2, y_pred)
    # .... rest of the loss .... #

这里的问题是,您是否可以根据输入将韦氏值计算为张量。

答案 1 :(得分:-1)

Keras Tensorflow v2中的损失函数以样品重量进行调用

output_loss = loss_fn(y_true, y_pred, sample_weight=sample_weight)

https://github.com/keras-team/keras/blob/tf-2/keras/engine/training.py


您可以使用GradientTape进行自定义训练,请参见https://www.tensorflow.org/guide/keras/train_and_evaluate#part_ii_writing_your_own_training_evaluation_loops_from_scratch