如何在发生器提供的Keras自定义损失函数中访问样本权重? [英] How to access sample weights in a Keras custom loss function supplied by a generator?

查看:403
本文介绍了如何在发生器提供的Keras自定义损失函数中访问样本权重?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a generator function that infinitely cycles over some directories of images and outputs 3-tuples of batches the form

[img1, img2], label, weight

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

where img1 and img2 are batch_size x M x N x 3 tensors, and label and weight are each batch_size x 1 tensors.

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

I provide this generator to the fit_generator function when training a model with Keras.

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

For this model I have a custom cosine contrastive loss function,

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)

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

Structurally everything runs OK with my model. There are no errors and it is consuming the inputs and labels from the generator as expected.

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

But now I am seeking to directly use the weights parameter per each batch and perform some customized logic inside of cosine_contrastive_loss based on the sample-specific weight.

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

How can I access this parameter from the structure of a batch of samples at the moment of the loss function being executed?

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

Note that since it is an infinitely cycling generator, it is not possible to precompute weights or compute them on the fly to either curry the weights into the loss function or generate them.

它们必须与所生成的样本一致地生成,并且确实在我的数据生成器中存在自定义逻辑,该逻辑可以在确定时立即根据img1img2label的属性动态确定权重.批量生成.

They have to be generated in unison with the samples being generated, and indeed there is custom logic in my data generator that determines the weights dynamically from properties of img1, img2 and label at the moment they are generated for a batch.

推荐答案

手动训练循环替代方案

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

Manual training loop alternative

The only thing I can think of is a manual training loop where you get the weights yourself.

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

Have a weights tensor and a non variable batch size:

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

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

Use them in your custom loss:

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没有公开权重,它们会自动应用于某些隐藏的源代码中.

I know this answer is not optimal because it does not parallelize getting data from the generator as it happens with fit_generator. But it's the best easy solution I can think of. Keras didn't expose the weights, they are applied automatically in some hidden source code.

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

If calculating the weights can be done from x and y, you can delegate this task to the loss function itself.

这有点骇人听闻,但可能会起作用:

This is sort of hacky, but may work:

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 .... #

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

The issue here is whether you can or not calculate the weigths as a tensor from the inputs.

这篇关于如何在发生器提供的Keras自定义损失函数中访问样本权重?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆