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

如何使用Keras的flow_from_dataframe读取向量形式的目标标签?

解决Keras flow_from_dataframe读取多向量目标标签的问题

我完全懂你的困扰——当你的标签是多个编码后的向量(比如bbox坐标、分类one-hot编码、属性向量)时,flow_from_dataframe默认的class_mode选项确实都不适用,毕竟它们大多是为单标签或单分类场景设计的。下面给你两种实用的解决方案:


方法一:利用class_mode='raw'结合合并标签列

如果你的所有标签可以拼接成一个单一的长向量,这种方法最直接:

  1. 先预处理DataFrame,把多个标签列合并成一个列:
import numpy as np

def combine_labels(row):
    # 按顺序拼接bbox、category、attributes为一维数组
    return np.concatenate([row['bbox'], row['category'], row['attributes']])

df['combined_labels'] = df.apply(combine_labels, axis=1)
  1. 调用flow_from_dataframe时指定class_mode='raw':
from keras.preprocessing.image import ImageDataGenerator

datagen = ImageDataGenerator(rescale=1./255)

generator = datagen.flow_from_dataframe(
    dataframe=df,
    directory=None,  # 如果image_path是绝对路径,这里设为None
    x_col='image_path',
    y_col='combined_labels',
    target_size=(224, 224),  # 根据你的CNN模型输入尺寸调整
    batch_size=32,
    class_mode='raw',  # 关键:直接返回原始的标签数组
    shuffle=True
)

训练时可以把合并的标签拆分回原结构:

for images, combined_labels in generator:
    # 按之前拼接的顺序拆分
    bboxes = combined_labels[:, :4]  # 假设bbox是4维坐标
    categories = combined_labels[:, 4:4+num_categories]
    attributes = combined_labels[:, 4+num_categories:]
    # 传入多输出模型训练
    loss = model.train_on_batch(images, [bboxes, categories, attributes])

方法二:自定义生成器(更灵活)

如果不想合并标签,或者需要保留各个标签的独立结构,自定义生成器会更适配:

  1. 先创建仅加载图片的生成器:
image_generator = datagen.flow_from_dataframe(
    dataframe=df,
    directory=None,
    x_col='image_path',
    target_size=(224, 224),
    batch_size=32,
    class_mode=None,  # 只返回图片,不处理标签
    shuffle=True,
    seed=42  # 设置seed确保图片和标签顺序一致
)
  1. 编写标签生成器,从DataFrame中提取对应标签:
def label_generator(df, batch_size, seed):
    np.random.seed(seed)
    while True:
        # 随机选取批次数据
        batch_indices = np.random.choice(df.index, size=batch_size, replace=False)
        batch_df = df.loc[batch_indices]
        # 把列表形式的标签转为numpy数组
        bboxes = np.array(batch_df['bbox'].tolist())
        categories = np.array(batch_df['category'].tolist())
        attributes = np.array(batch_df['attributes'].tolist())
        yield (bboxes, categories, attributes)
  1. 合并两个生成器,确保图片与标签一一对应:
from itertools import zip_longest

train_generator = zip_longest(image_generator, label_generator(df, 32, 42))

# 训练时的使用示例
for images, labels in train_generator:
    bboxes, categories, attributes = labels
    loss = model.train_on_batch(images, [bboxes, categories, attributes])

小提示

  • 如果image_path是相对路径,记得在flow_from_dataframe中设置directory为图片根目录。
  • 自定义生成器时必须设置相同的seed,否则图片和标签会错位。
  • 若模型是多输出结构,要确保每个输出层的维度和对应标签的维度完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 16:02:28