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

使用Keras函数式API构建多实例模型:实例与包标签预测问题

多实例学习:Keras同时预测实例与包标签的解决方案

核心问题解决与实现思路

1. 实现实例分支的权重共享

你当前的代码在循环中重复创建Dense层,导致每个实例分支权重独立。正确的做法是先定义一个共享的实例处理子模型,所有实例输入复用该子模型:

import tensorflow as tf
from tensorflow.keras.layers import *

# 定义共享的实例特征提取子模型
def build_instance_submodel(n_feat, n_classes):
    inputs = Input(shape=(n_feat,))
    x = Dense(256, activation='relu')(inputs)
    x = Dense(128, activation='relu')(x)
    x = Dense(64, activation='relu')(x)
    # 实例级输出:n_classes+1类的sigmoid概率
    outputs = Dense(n_classes + 1, activation='sigmoid')(x)
    return tf.keras.Model(inputs, outputs)

# 初始化共享子模型
instance_submodel = build_instance_submodel(n_feat, n_classes)

2. 调整张量形状为(n_instances, n_classes)

用tf.stack替代Concatenate,将多个实例的输出堆叠成三维张量(批量维度 × 实例数 × 类别数),满足后续损失计算和包处理的需求:

inputs = []
instance_outputs = []

for i in range(n_instances):
    inp = Input(shape=(n_feat,))
    inputs.append(inp)
    # 复用共享子模型,权重自动共享
    instance_out = instance_submodel(inp)
    instance_outputs.append(instance_out)

# 堆叠实例输出,形状变为(None, n_instances, n_classes+1)
stacked_instance_outputs = tf.stack(instance_outputs, axis=1)

3. 从实例预测推导包标签的实现策略

针对多实例包的标签预测,推荐以下三种常用方案:

方案1:最大池化(简单高效)

取每个类别下所有实例的最大概率,作为包的类别概率:

# 对实例维度做最大池化,输出形状(None, n_classes+1)
bag_max = GlobalMaxPool1D()(stacked_instance_outputs)
bag_output = Dense(n_classes, activation='softmax')(bag_max)

方案2:平均池化(反映整体分布)

对所有实例的概率做平均,适合包标签由多数实例决定的场景:

# 对实例维度做平均池化,输出形状(None, n_classes+1)
bag_avg = GlobalAveragePooling1D()(stacked_instance_outputs)
bag_output = Dense(n_classes, activation='softmax')(bag_avg)

方案3:注意力机制(自适应加权,效果更优)

学习每个实例对包标签的贡献权重,加权求和后预测包类别:

# 注意力权重计算:先将实例特征映射为权重
attention = Dense(1, activation='sigmoid')(stacked_instance_outputs)
# 加权求和:(None, n_instances, n_classes+1) × (None, n_instances, 1) → (None, n_classes+1)
weighted_sum = tf.reduce_sum(stacked_instance_outputs * attention, axis=1)
bag_output = Dense(n_classes, activation='softmax')(weighted_sum)

完整模型构建

将实例输出和包输出整合为多输出模型,同时优化实例级和包级损失:

# 实例级输出:保持堆叠后的形状,方便计算CategoricalCrossEntropy
instance_final_output = stacked_instance_outputs

# 构建多输出模型
model = tf.keras.Model(inputs=inputs, outputs=[instance_final_output, bag_output])

# 编译模型:指定两个损失函数,可设置权重平衡
model.compile(
    optimizer='adam',
    loss=[
        tf.keras.losses.CategoricalCrossentropy(),  # 实例级损失
        tf.keras.losses.CategoricalCrossentropy()   # 包级损失
    ],
    loss_weights=[0.3, 0.7],  # 根据需求调整权重,比如更侧重包标签预测
    metrics=['accuracy']
)

关键说明

  • 权重共享:通过复用同一个子模型,确保所有实例使用完全相同的特征提取权重,避免过拟合单个实例。
  • 张量形状:tf.stack(axis=1)将多个实例的一维输出(类别概率)堆叠为二维结构,完美匹配CategoricalCrossEntropy对输入形状的要求(批量×样本数×类别数)。
  • 多输出训练:模型同时输出实例预测和包预测,可通过loss_weights平衡两个任务的训练优先级,让模型端到端学习实例与包标签的关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:25:28