【问题标题】:Keras custom loss - Combining loss of multiple branchKeras 自定义损失 - 合并多个分支的损失
【发布时间】:2021-01-22 13:01:27
【问题描述】:

我有一个 2 分支网络,其中一个分支输出回归值,另一个分支输出分类标签。

model = Model(inputs=inputs, outputs=[output1, output2])    
model.compile(loss=[my_loss_reg, my_loss_class], optimizer='adam')

我想为回归分支实现一个自定义损失函数 (my_loss_reg()),以便在回归结束时添加一部分分类损失,如下所示,

def my_loss_reg(y_true, y_pred):
        loss_mse=K.mean(K.sum(K.square(y_true-y_pred)))
        #loss_reg = calculate_classification_loss() # How to implement this? 
        final_loss = some_function(loss_mse, loss_reg) # Can calculate only if loss_reg is available
        return final_loss

y_truey_pred 是回归分支处的真实回归值和预测回归值。要计算分类损失,我需要真实和预测的分类标签,这在 my_loss_reg() 中不可用。

我的问题是如何计算或访问网络回归端的分类损失?同样,我想在为分类计算自定义损失函数my_loss_class()时得到分类端的回归损失。

我该怎么做?任何代码 sn-ps 都会有所帮助。我找到了this solution,但这对于最新版本的 Tensorflow 和 Keras 不再有效。

【问题讨论】:

    标签: python-3.x tensorflow machine-learning keras loss-function


    【解决方案1】:

    所有你需要的只是在原生 keras 中可用

    您可以使用loss_weights 参数自动组合多个损失

    在下面的示例中,我尝试重现一个任务,其中我将回归的 mse 损失和分类任务的 sparse_categorical_crossentropy 组合在一起

    features,n_sample,n_class = 10, 200, 3
    
    X = np.random.uniform(0,1, (n_sample,features))
    y = np.random.randint(0,n_class, n_sample)
    
    inp = Input(shape=(features,))
    x = Dense(64, activation='relu')(inp)
    hidden = Dense(16, activation='relu')(x)
    x = Dense(64, activation='relu')(hidden)
    out_reg = Dense(features, name='out_reg')(x) # output regression
    x = Dense(32, activation='relu')(hidden)
    out_class = Dense(n_class, activation='softmax', name='out_class')(x) # output classification
    
    model = Model(inp, [out_reg,out_class])
    model.compile(optimizer='adam', 
                  loss = {'out_reg':'mse', 'out_class':'sparse_categorical_crossentropy'},
                  loss_weights = {'out_reg':1., 'out_class':0.5})
    
    model.fit(X, [X,y], epochs=10)
    

    在这种特定情况下,损失是1*out_reg + 0.5*out_class的结果

    如果您想输入自定义损失,您只需以这种方式进行

    def my_loss_reg(y_true, y_pred):
        return ...
    
    def my_loss_class(y_true, y_pred):
        return ...
    
    model.compile(optimizer='adam', 
                  loss = {'out_reg':my_loss_reg, 'out_class':my_loss_class},
                  loss_weights = {'out_reg':1., 'out_class':0.5})
    
    model.fit(X, [X,y], epochs=10)
    

    【讨论】:

    • 这不是我想要的。根据您的回答,组合损失 1*out_reg + 0.5*out_class 将通过共享层而不是单个分支传播。但我想自定义单个分支的损失,损失是其他分支损失的函数。
    • 请记住,SINGLE 损失被最小化(所有输出的组合损失)。你不能在同一个网络中独立地最小化每个分支
    • 据我了解,个别分支具有个别的损失值(这就是它们是个别的原因)。共享层具有组合损失。
    • 我找到了这个解决方案,但该解决方案不再适用于最新版本的 TensorFlow 和 Keras。 stackoverflow.com/questions/51680818/…
    • @Saikat 你错了......来自文档:'如果模型有多个输出......模型将最小化的损失值将是所有个体损失的总和' (合理)tensorflow.org/api_docs/python/tf/keras/Model#compile
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 2020-12-19
    • 2017-12-18
    • 2020-03-27
    相关资源
    最近更新 更多