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

单标签多分类任务的自定义损失函数设计咨询

损失函数设计方案

核心思路

针对「允许预测多个指定类别、仅严厉惩罚预测非允许类别」的需求,我们可以基于负对数似然变种设计损失:只要模型在任意一个允许类别上的预测概率足够高,损失就会很低;只有当高概率集中在非允许类别时,才会产生较高损失,完全贴合你「预测任意允许类别即可」的要求。

具体实现步骤(以PyTorch为例)

假设输入张量:

  • preds: 模型输出的logits,形状为(bs, n, nc),未经过softmax
  • targets: 标签张量,形状与preds一致,targets[i,j,k]=1表示第i个batch point的第j个vector point允许预测类别k,0表示不允许

步骤1:转换为概率分布

对preds在类别维度(nc)做softmax,得到每个类别的预测概率:

probs = torch.softmax(preds, dim=-1)  # 形状保持(bs, n, nc)

步骤2:计算单个vector point的损失

将非允许类别的概率置0,只保留允许类别的概率,再取每个vector point允许类别中的最大概率,最后取其负对数作为该样本的损失(负对数越大,说明模型在允许类别上的最高概率越低,损失越高):

# 过滤出允许类别的概率,非允许类别置为0
allowed_probs = probs * targets
# 提取每个vector point在允许类别上的最大概率,维度变为(bs, n)
max_allowed_probs = torch.max(allowed_probs, dim=-1)[0]
# 计算损失,加1e-8避免log(0)导致数值报错
loss_per_vector = -torch.log(max_allowed_probs + 1e-8)  # 形状(bs, n)

步骤3:按要求聚合损失

  • 先对每个batch point内的n个vector point损失取平均,得到单个batch point的损失(维度变为(bs))
  • 再对所有bs个batch point的损失取平均,得到最终总损失:
# 单个batch point内的损失平均(n维度取平均)
loss_per_batch_point = torch.mean(loss_per_vector, dim=1)  # 形状(bs)
# 总损失(所有batch point取平均)
total_loss = torch.mean(loss_per_batch_point)

变种方案:加权允许类别

如果需要对不同允许类别设置优先级(比如某些允许类别更接近真实类别),可以修改步骤2,用加权求和代替最大概率:

# 假设targets中的数值为对应类别的权重(如1表示完全允许,0.7表示次要允许)
weighted_probs = probs * targets
# 计算加权后的概率和
sum_weighted_probs = torch.sum(weighted_probs, dim=-1)
# 计算损失
loss_per_vector = -torch.log(sum_weighted_probs + 1e-8)

注意事项

  • 若模型输出已经是经过softmax的概率,可直接跳过步骤1
  • 1e-8用于避免数值不稳定,可根据实际精度需求调整
  • 聚合损失时,也可根据任务需求用「求和」代替「平均」,比如样本不均衡时对不同batch point设置权重

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:55:17