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

如何在Keras中利用自定义损失函数优化双输出模型?

看起来你正在构建一个多任务学习模型,同时完成目标值预测和输入矩阵的自编码重构——这个思路很实用,能让模型同时学到数据的通用表征和任务专属的预测能力。我来帮你把这个方案落地,包括损失函数的设计、模型整合和具体代码示例:

1. 模型架构整合优化

你的原始架构已经清晰区分了预测分支和自编码分支,这里有个小优化点:如果希望两个任务共享同一组输入表征,可以让它们复用同一个中间Dense层(当然如果需要独立表征也可以保持分开)。下面是两种版本的架构:

版本1:共享中间层权重(推荐,提升表征效率)

input_matrix = Input(shape=(i_shape,))
# 共享的中间表征层
shared_dense = Dense(100, activation='relu')(input_matrix)
# 预测分支
prediction_output = Dense(3, name='prediction')(shared_dense)
# 自编码分支
reconstruction_output = Dense(i_shape, name='reconstruction')(shared_dense)

版本2:独立中间层权重

就是你最初构想的架构,两个分支各自有自己的Dense(100)层:

input_matrix = Input(shape=(i_shape,))
# 预测分支
layer1 = Dense(100, activation='relu')(input_matrix)
prediction_output = Dense(3, name='prediction')(layer1)
# 自编码分支
autoencoder_mid = Dense(100, activation='relu')(input_matrix)
reconstruction_output = Dense(i_shape, name='reconstruction')(autoencoder_mid)

最后把两个分支的输出整合到同一个模型中:

from tensorflow.keras.models import Model
model = Model(inputs=input_matrix, outputs=[prediction_output, reconstruction_output])
2. 自定义多任务损失函数设计

你需要把预测任务损失和自编码重构损失加权结合,平衡两个任务的优先级。具体实现有两种方式:

方式1:利用Keras多输出损失机制(简单直接)

给每个输出分支命名后,可以分别指定损失函数和权重,Keras会自动计算加权总损失:

from tensorflow.keras.losses import MeanSquaredError

# 定义各分支的损失函数(假设目标值是回归任务,用MSE;如果是分类可以用CategoricalCrossentropy)
losses = {
    'prediction': MeanSquaredError(),
    'reconstruction': MeanSquaredError()
}

# 定义损失权重:根据任务重要性调整,比如预测任务更重要就调高权重
loss_weights = {
    'prediction': 0.7,  # 预测损失占比70%
    'reconstruction': 0.3  # 重构损失占比30%
}

# 编译模型
model.compile(optimizer='adam', loss=losses, loss_weights=loss_weights)

方式2:手动自定义损失函数(更灵活)

如果需要更复杂的损失逻辑(比如动态调整权重、加入正则项等),可以手动编写自定义损失:

def custom_loss(y_true, y_pred):
    # y_true是一个列表:[目标值标签, 输入矩阵本身]
    # y_pred是一个列表:[预测输出, 重构输出]
    pred_true, recon_true = y_true
    pred_pred, recon_pred = y_pred
    
    # 计算两个分支的损失
    pred_loss = tf.keras.losses.MSE(pred_true, pred_pred)
    recon_loss = tf.keras.losses.MSE(recon_true, recon_pred)
    
    # 加权求和
    total_loss = 0.7 * pred_loss + 0.3 * recon_loss
    return total_loss

# 编译时直接传入自定义损失
model.compile(optimizer='adam', loss=custom_loss)
3. 模型训练注意事项

训练时需要传入两个目标值:

  • 预测分支的目标:你的一组目标值(shape=(样本数, 3))
  • 自编码分支的目标:输入矩阵本身(shape=(样本数, i_shape))

示例代码:

# 假设x_train是输入矩阵,y_train是目标值
model.fit(
    x=x_train,
    y=[y_train, x_train],  # 对应两个输出分支的目标
    epochs=50,
    batch_size=32,
    validation_split=0.2
)
额外优化建议
  • 数据归一化:如果输入矩阵和目标值的数值量级差异大,建议先做标准化/归一化,避免某一个损失主导训练过程
  • 激活函数:给中间Dense层加上激活函数(比如relu、gelu),提升模型的非线性表达能力
  • 正则化:可以在Dense层加入kernel_regularizer=l2(0.01)或者Dropout层,防止过拟合
  • 权重调优:可以通过验证集的性能来调整loss_weights的比例,找到最优的任务平衡

内容的提问来源于stack exchange,提问作者sdgaw erzswer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:41:33