自定义损失,用于取消 Keras 多任务模型中回归输出的类贡献

custom loss to nullify a class contribution for the regression output in a keras multi task model

提问人:bio 提问时间:11/15/2023 更新时间:11/15/2023 访问量:20

问:

我有一个模型,它执行两个基本任务,二元分类和回归。 对于回归任务,一个类的贡献必须无效,而它对于分类当然很重要。

由于 中的损失函数必须具有类似 的签名,如果我想知道实际样本属于哪个类,我必须用类似以下内容包装该函数:kerasmyloss(y_true, y_pred)myloss

def wrap_loss(ctarget):
    def myloss(y_true, y_pred):
        # Create a mask to exclude samples of class 1
        mask = tf.where(tf.math.not_equal(ctarget, 1), 1.0, 0.0)
        squared_difference = tf.square(y_true - y_pred) * mask

        return tf.reduce_mean(squared_difference, axis=-1)

    return myloss

由于我有一个输入,所以我将我的模型定义为TFRecordDataset

model = keras.Model(
    inputs={
        "input1": input1,
        "input2": input2,
    },
    outputs={
        "regr_out": regr_output, 
        "class_id": class_output
    }
)

现在,理想情况下,我想在编译模型时指定损失,以将用于回归的损失与用于分类的损失分开:

model.compile(
    optimizer=opt,
    loss={
        "regr_out": wrap_loss(clf_labels),
        "class_id": keras.losses.BinaryCrossentropy(),
    },
    metrics={
        "regr_out": regr_metrics,
        "class_id": clf_metrics,
    },
)

然后调用将数据集作为输入传递的方法。fit

问题出在变量上:我怎样才能传递它?数据集不可下标,对于回归任务,我只有可用的回归目标。 我编写的解析器在元组的第二个字典中返回,如下所示:clf_labelstfrecordclass_id

def parse_tfrec_for_training(example):
    [...]
    return (
        {'input1': example['input1'], 'input2': example['input2']},
        {'regr_out': example['regr_target'], 'class_id': example['class_id']}
    )

但我不能用它来传递给.dataset.batch(BATCH_SIZE)['class_id']wrap_loss

我应该写一个自定义的火车循环吗? 我仍然想使用和方法;我阅读了自定义拟合函数编写自定义循环的指南,但我不确定如何实现这一点。compilefitkeras

Python 机器学习 Keras TensorFlow2.0 tensorflow-datasets

评论


答: 暂无答案