【问题标题】:Keras custom loss as a function of multiple outputsKeras 自定义损失作为多个输出的函数
【发布时间】:2019-01-11 19:56:20
【问题描述】:

我使用 keras(一个卷积网络)构建了一个自定义架构。该网络有 4 个头,每个头输出一个不同大小的张量。我正在尝试编写一个自定义损失函数作为这 4 个输出的函数。我之前一直在实施自定义损失,但它要么是每个人头的不同损失,要么是每个人头的相同损失。在这种情况下,我需要结合 4 个输出来计算损失。

我已经习惯了:

def custom_loss(y_true, y_pred):
    return something
model.compile(optimizer, loss=custom_loss)

但在我的情况下,我需要 y_pred 作为 4 个输出的列表。我可以用零填充输出并在我的模型中添加一个连接层,但我想知道是否有更简单的方法。

编辑

我的损失函数比较复杂,能不能写成这样:

model.add_loss(custom_loss(input1, input2, output1, output2))

自定义损失定义为:

def custom_loss(input1, input2, output1, output2):
    return loss

【问题讨论】:

    标签: keras deep-learning loss-function


    【解决方案1】:

    你可以试试model.add_loss() 函数。这个想法是将您的自定义损失构建为张量而不是函数,将其添加到模型中,然后在不进一步指定损失的情况下编译模型。另请参阅变分自动编码器的this implementation,其中使用了类似的想法。

    例子:

    import keras.backend as K
    from keras.layers import Input, Dense
    from keras.models import Model
    from keras.losses import mse
    import numpy as np
    
    # Some random training data
    features = np.random.rand(100,20)
    labels_1 = np.random.rand(100,4)
    labels_2 = np.random.rand(100,1)
    
    # Input layer, one hidden layer
    input_layer = Input((20,))
    dense_1 = Dense(128)(input_layer)
    
    # Two outputs
    output_1 = Dense(4)(dense_1)
    output_2 = Dense(1)(dense_1)
    
    # Two additional 'inputs' for the labels
    label_layer_1 = Input((4,))
    label_layer_2 = Input((1,))
    
    # Instantiate model, pass label layers as inputs
    model = Model(inputs=[input_layer, label_layer_1, label_layer_2], outputs=[output_1, output_2])
    
    # Construct your custom loss as a tensor
    loss = K.mean(mse(output_1, label_layer_1) * mse(output_2, label_layer_2))
    
    # Add loss to model
    model.add_loss(loss)
    
    # Compile without specifying a loss
    model.compile(optimizer='sgd')
    
    dummy = np.zeros((100,))
    model.fit([features, labels_1, labels_2], dummy, epochs=2)
    

    【讨论】:

    • 如何使用这种方法传递验证数据?括号不遵循 val_data = (Xval, [Yval1, Yval2, ...]) 的正常定义
    • 此方案对tensorflow==2.1.0无效,对Keras==2.3.1无效。您能否帮助修改此答案以反映更新的软件包?是否有可能回忆起用于生成此答案的软件包版本?
    • 嗨,这在 tensorflow 1.x 中是肯定的。我现在真的没有时间弄清楚,但我会在我的答案中添加免责声明
    • 这对我有用!我正在使用tensorflow==2.2.0 和tf.keras。也许香草 keras 没有这个功能?
    • 我看不出这不起作用的原因。事实上它确实如此,只是用今天最新的每晚(2.5.0.dev20201028)进行了测试。损失函数中只有一个 type-o 并且 fit 调用不正确,后者导致人们认为这不再起作用。我已经编辑了答案,希望很快会被接受。
    【解决方案2】:

    拟合模型时不需要虚拟变量

    所以,你可以使用 model.fit([features, labels_1, labels_2], epochs=2)

    那么它在下面工作得很好

    张量流版本'1.14.0' keras.版本 '2.3.1'

    【讨论】:

      猜你喜欢
      • 2020-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      • 2017-12-18
      • 2020-03-27
      • 1970-01-01
      • 2019-06-19
      相关资源
      最近更新 更多