首页 > 解决方案 > 如何使用 Keras 构建自定义损失函数

问题描述

我有为连体网络实现的损失函数。在 Keras 中,如果您必须构建自己的损失函数,它应该只将输入参数作为 (y_true, y_pred)。但就我而言,我有 y_pred1, y_pred1, y_true1(class_label), y_true2(class_label), y_true3(similarity label)

所以我的解决方案是连接我喜欢的东西:

def my loss ( y_true, y_pred):
    y_true1 = y_true[:, 0]
    y_true2 = y_true[:, 1]
    label = y_true[:, 2]

    y_pred1 = y_pred[:, 0]
    y_pred2 = y_pred[:, 1]

第二个问题是,我有一个参数 (alpha),它是当前纪元数的函数,我也应该将它传递给损失函数。

一般来说,如果您必须传递一些其他参数,您可以使用包装函数作为此处建议的解决方案。

但在我的情况下它对我没有帮助,因为我的 alpha 应该根据当前的纪元数而改变。它基本上是当前时代的 Sigmoied 函数。

我可以跟踪纪元数的唯一方法是在我自己的生成器中,因为我在 tfrecords 中构建了数据集。所以我使用自己的生成器将数据提供给模型。

所以有人知道我该怎么做吗?我如何跟踪当前的纪元数并使用它。

标签: keras

解决方案


重要的!你的情况是哪一个?

  • 案例 1:具有 3 个输出的模型
  • 案例 2:一个输出是三个输出串联的模型?

没有 alpha 的示例

情况1

你需要三个独立的损失函数,每个函数只能看到自己的y_truey_pred

def loss1(yTrue,yPred):
    ...
def loss2(yTrue,yPred):
    ...
def loss3(yTrue,yPred):
    ...

model.compile(loss=[loss1,loss2,loss3],...)

案例2

在这种情况下,您将能够按照您建议的方式进行操作。

def my loss ( y_true, y_pred):
    y_true1 = y_true[:, 0]
    y_true2 = y_true[:, 1]

    y_pred1 = y_pred[:, 0]
    y_pred2 = y_pred[:, 1]

使用阿尔法

Alpha 必须是“张量”,而不是普通的 var:

alpha = K.variable(someInitialNpArray, dtype=...)

alpha 的值必须“更改”,而不是重新分配:

K.set_value(alpha, newValues)

现在,创建一个LambdaCallbackforon_epoch_end以更改 alpha 的值:

def changeAlpha(epoch,logs):
    #maybe use epoch+1, because it starts with 0
    K.set_value(alpha, valuesBasedOn(epoch))

alphaChanger = LambdaCallback(on_epoch_end=changeAlpha) #or on_epoch_begin (or start?)

失利:

def loss(true,pred):
    #blablabla

    #you can use alpha here

训练:

model.fit(..... callbacks = [alphaChanger])
model.fit_generator(......, callbacks = [alphaChanger])

推荐阅读