Keras/Tensorflow:单个输出的组合损失函数

Sar*_*ran 8 python keras tensorflow loss-function

我的模型只有一个输出,但我想结合两个不同的损失函数:

def get_model():
    # create the model here
    model = Model(inputs=image, outputs=output)

    alpha = 0.2
    model.compile(loss=[mse, gse],
                      loss_weights=[1-alpha, alpha]
                      , ...)
Run Code Online (Sandbox Code Playgroud)

但它抱怨我需要有两个输出,因为我定义了两个损失:

ValueError: When passing a list as loss, it should have one entry per model outputs. 
The model has 1 outputs, but you passed loss=[<function mse at 0x0000024D7E1FB378>, <function gse at 0x0000024D7E1FB510>]
Run Code Online (Sandbox Code Playgroud)

我是否可以编写我的最终损失函数而不必创建另一个损失函数(因为这会限制我更改损失函数之外的 alpha)?

我该怎么做(1-alpha)*mse + alpha*gse


更新:

我的两个损失函数都相当于任何内置 keras 损失函数的函数签名,接受y_truey_pred返回损失的张量(可以使用 将其减少为标量K.mean()),但我相信,这些损失函数是如何定义的?只要它们返回有效的损失,就不会影响答案。

def gse(y_true, y_pred):
    # some tensor operation on y_pred and y_true
    return K.mean(K.square(y_pred - y_true), axis=-1)
Run Code Online (Sandbox Code Playgroud)

jde*_*esa 11

为损失指定一个自定义函数:

model = Model(inputs=image, outputs=output)

alpha = 0.2
model.compile(
    loss=lambda y_true, y_pred: (1 - alpha) * mse(y_true, y_pred) + alpha * gse(y_true, y_pred),
    ...)
Run Code Online (Sandbox Code Playgroud)

或者,如果您不希望丑陋的 lambda 成为实际函数:

def my_loss(y_true, y_pred):
    return (1 - alpha) * mse(y_true, y_pred) + alpha * gse(y_true, y_pred)

model = Model(inputs=image, outputs=output)

alpha = 0.2
model.compile(loss=my_loss, ...)
Run Code Online (Sandbox Code Playgroud)

编辑:

如果你alpha不是一些全局常量,你可以有一个“损失函数工厂”:

def make_my_loss(alpha):
    def my_loss(y_true, y_pred):
        return (1 - alpha) * mse(y_true, y_pred) + alpha * gse(y_true, y_pred)
    return my_loss

model = Model(inputs=image, outputs=output)

alpha = 0.2
my_loss = make_my_loss(alpha)
model.compile(loss=my_loss, ...)
Run Code Online (Sandbox Code Playgroud)