You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TensorFlow自定义损失函数中单独处理神经网络多输出及y_true形状

在TensorFlow中为双输出模型实现依赖多值的自定义损失函数

首先,先明确你关心的y_true张量结构问题:它的形状和结构完全匹配你的模型输出形式,分两种常见情况:

1. y_true的结构与模型输出对应

情况A:模型输出是独立的两个张量

如果你的模型最后返回的是两个分开的输出(比如两个Dense层的结果),像这样:

input_layer = tf.keras.layers.Input(shape=(10,))
x = tf.keras.layers.Dense(32, activation='relu')(input_layer)
output1 = tf.keras.layers.Dense(1, name="pred1")(x)
output2 = tf.keras.layers.Dense(1, name="pred2")(x)
model = tf.keras.Model(inputs=input_layer, outputs=[output1, output2])

那传入自定义损失函数的y_true会是一个列表/元组,里面的两个元素分别对应output1和output2的真实标签,每个元素的形状和对应输出的形状一致(比如这里都是(batch_size, 1))。

情况B:模型输出是合并的单张量

如果你的模型把两个输出合并成一个形状为(batch_size, 2)的张量(比如用一个Dense(2)层输出):

input_layer = tf.keras.layers.Input(shape=(10,))
x = tf.keras.layers.Dense(32, activation='relu')(input_layer)
combined_output = tf.keras.layers.Dense(2, name="combined")(x)
model = tf.keras.Model(inputs=input_layer, outputs=combined_output)

那y_true就是一个和combined_output形状完全相同的张量,每一列对应一个输出的真实值(第一列对应第一个预测值,第二列对应第二个)。

2. 如何单独提取各个输出计算自定义损失

不管是哪种输出形式,你都可以在自定义损失函数里轻松拆分出各个部分,然后按照你的公式计算(因为你的损失依赖所有相关值,所以不需要拆分模型损失)。

示例1:模型输出为独立张量的情况

import tensorflow as tf
from tensorflow.keras import backend as K

def custom_loss(y_true, y_pred):
    # 拆分y_true和y_pred为各自的分量
    y_true1, y_true2 = y_true  # 两个真实标签张量
    y_pred1, y_pred2 = y_pred  # 两个预测输出张量
    
    # 这里写你的自定义损失公式——比如依赖y_true1、y_pred1、y_pred2三个值的情况
    term1 = K.square(y_pred1 - y_true1)
    term2 = K.abs(y_pred2 - y_true1) * K.mean(y_pred1)
    total_loss = term1 + 0.5 * term2
    
    # 返回批量的平均损失
    return K.mean(total_loss)

# 编译模型时直接传入这个自定义损失
model.compile(optimizer="adam", loss=custom_loss)

示例2:模型输出为合并张量的情况

def custom_loss_combined(y_true, y_pred):
    # 通过切片拆分张量
    y_true1 = y_true[:, 0:1]  # 提取第一列作为第一个真实值
    y_true2 = y_true[:, 1:2]  # 提取第二列作为第二个真实值
    y_pred1 = y_pred[:, 0:1]  # 提取第一个预测输出
    y_pred2 = y_pred[:, 1:2]  # 提取第二个预测输出
    
    # 自定义损失计算——这里示例一个依赖所有四个值的公式,你可以替换成你的需求
    loss = K.square(y_pred1 - y_true1) + K.square(y_pred2 - (y_pred1 + y_true2))
    return K.mean(loss)

# 编译模型
model.compile(optimizer="adam", loss=custom_loss_combined)

补充说明

  • 训练时,你的输入真实标签要和模型输出结构匹配:如果模型输出是列表,训练数据就传[y1_train, y2_train];如果是合并张量,就传形状为(samples, 2)的二维数组。
  • 这种自定义损失的方式完全满足你的需求——不需要拆分模型为两个输出单独定义损失,因为你可以在同一个函数里访问所有需要的输出和真实值分量。

内容的提问来源于stack exchange,提问作者Dr. Hans-Peter Störrr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:40:50