作为多个输出函数的Keras自定义损失

作为多个输出函数的Keras自定义损失,keras,deep-learning,loss-function,Keras,Deep Learning,Loss Function,我用keras(convnet)构建了一个定制的体系结构。该网络有4个磁头,每个磁头输出不同大小的张量。我试图编写一个自定义损失函数作为这4个输出的函数。我以前一直在实施cusutom亏损,但这不是每个人头的不同亏损,就是每个人头的相同亏损。在这种情况下,我需要结合4个输出来计算损耗 我已经习惯了以下几点: def custom_loss(y_true, y_pred): return something model.compile(optimizer, loss=custom_loss

我用keras(convnet)构建了一个定制的体系结构。该网络有4个磁头,每个磁头输出不同大小的张量。我试图编写一个自定义损失函数作为这4个输出的函数。我以前一直在实施cusutom亏损,但这不是每个人头的不同亏损,就是每个人头的相同亏损。在这种情况下,我需要结合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

您可以尝试使用
model.add_loss()
函数。其思想是将自定义损失构造为张量而不是函数,将其添加到模型中,并编译模型,而无需进一步指定损失。另请参见使用类似想法的变分自动编码器

例如:

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)

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

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

那么它在以下条件下运行良好

tensorflow版本“1.14.0”
keras.版本“2.3.1”

如何使用此方法传递验证数据?括号不符合val_数据=(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)。损失函数中只有一个类型o,fit调用不正确,后者导致人们认为这不再有效。我已经编辑了答案,希望它能很快被接受。