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

Keras多标签回归任务中如何查看每个标签的损失值?

如何在Keras多变量回归任务中跟踪每个标签的单独损失

你现在的场景是用Keras做多变量回归,输出层的n个神经元对应不同的回归目标,但默认的MAE损失是所有标签的平均值,没法单独查看每个标签的损失,训练进度条也只显示合并后的数值。你希望history里能记录每个标签的单独损失(比如{'loss': {'speed': 0.5, 'height': 0.3}}这种形式),同时训练时的进度条也能实时展示各标签的损失情况。

之前你考虑过为每个标签写单独的自定义指标,但觉得这是权宜之计,下面给你两种更系统的解决方案:


方法一:拆分输出层为独立输出分支(推荐方案)

Keras原生支持多输出模型,与其用一个Dense(n)输出所有标签,不如把每个回归目标做成单独的输出节点。这样Keras会自动为每个输出计算损失,训练时会分别展示各标签的损失值,history里也会单独记录每个输出的损失和指标。

示例代码如下:

from keras.layers import Input, Dense, Conv2D, Flatten
from keras.models import Model

# 假设输入是单通道图片
input_layer = Input(shape=(28, 28, 1))
x = Conv2D(32, (3,3), activation='relu')(input_layer)
x = Flatten()(x)
x = Dense(64, activation='relu')(x)

# 每个回归目标单独创建输出层,并指定名称
output_speed = Dense(1, activation='linear', name='speed')(x)
output_height = Dense(1, activation='linear', name='height')(x)
# 若有更多标签,继续添加类似的output_xxx = Dense(1, ...)

# 定义多输出模型
model = Model(inputs=input_layer, outputs=[output_speed, output_height])

# 编译时为每个输出指定损失和指标,支持字典或列表形式
model.compile(
    loss={'speed': 'mean_absolute_error', 'height': 'mean_absolute_error'},
    optimizer='sgd',
    metrics={'speed': ['mean_squared_error'], 'height': ['mean_squared_error']}
)

# 训练时,标签数据要对应输出的结构(字典或列表)
# 假设y_train是形状为(样本数, 2)的数组,第一列是speed,第二列是height
history = model.fit(
    X_train,
    {'speed': y_train[:, 0], 'height': y_train[:, 1]},
    epochs=10,
    batch_size=32
)

这样训练时,进度条会显示loss(总损失,默认是各输出损失的平均值)、speed_loss、height_loss等字段;history.history里也会有speed_loss、height_loss、speed_mean_squared_error这些单独的键,完全满足你跟踪每个标签损失的需求,这也是最符合Keras设计逻辑的方案。


方法二:通用自定义指标(适合不改动模型结构的场景)

如果你不想重构现有的单输出层模型,可以写一个通用的指标生成函数,避免为每个标签重复写代码:

import keras.backend as K

def mae_for_label(label_index, label_name):
    def mae(y_true, y_pred):
        # 提取对应索引的标签真实值和预测值
        true = y_true[:, label_index]
        pred = y_pred[:, label_index]
        return K.mean(K.abs(pred - true))
    # 给指标命名,方便在history和进度条中识别
    mae.__name__ = f'mae_{label_name}'
    return mae

# 假设你的标签列表是['speed', 'height'],对应索引0和1
custom_metrics = [
    mae_for_label(0, 'speed'),
    mae_for_label(1, 'height'),
    # 更多标签可继续添加
]

# 保持原有的单输出模型结构不变
input_layer = Input(shape=shape)
# ... 中间层定义 ...
x = Dense(n, activation='linear')(x)
model = Model(inputs=input_layer, outputs=x)

# 编译时加入自定义指标
model.compile(
    loss='mean_absolute_error',
    optimizer='sgd',
    metrics=['mean_squared_error'] + custom_metrics
)

history = model.fit_generator(...)

这种方式下,history.history里会出现mae_speed、mae_height等键,训练进度条也会显示这些指标。不过要注意:这里的总损失还是所有标签的平均MAE,自定义指标只是用来单独跟踪每个标签的损失情况,如果需要把总损失也拆分为各标签的单独值,还是方法一更合适。

内容的提问来源于stack exchange,提问作者0vbb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:43:03