如何使用Keras构建自定义损失函数

时间:2018-06-21 17:42:48

标签: keras

我有针对暹罗网络实现的丢失功能。在Keras中,如果必须构建自己的损失函数,则应仅将输入参数作为(y_true,y_pred)。 但就我而言,我有y_pred1,y_pred1,y_true1(class_label),y_true2(class_label),y_true3(相似性标签)

所以我的解决方案是将我喜欢的东西串联起来:

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),它是当前时期数的函数,我也应该将其传递给损失函数。

通常,如果必须传递其他参数,则可以使用wrapper函数作为建议的here解决方案。

但是对于我来说,这无济于事,因为我的alpha值应根据当前纪元数进行更改。它基本上是当前时代的Sigmoied函数。

我可以跟踪时期号的唯一方法是在自己的生成器中,因为我在tfrecords中内置了数据集。因此,我正在使用自己的生成器将数据输入模型。

所以任何人都知道我该怎么办?如何跟踪当前纪元编号并使用它。

1 个答案:

答案 0 :(得分:1)

重要!您是哪种情况?

  • 情况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

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

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

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

K.set_value(alpha, newValues)

现在,为LambdaCallback创建一个on_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])