如何使用Keras的flow_from_dataframe读取向量形式的目标标签?
解决Keras flow_from_dataframe读取多向量目标标签的问题
我完全懂你的困扰——当你的标签是多个编码后的向量(比如bbox坐标、分类one-hot编码、属性向量)时,flow_from_dataframe默认的class_mode选项确实都不适用,毕竟它们大多是为单标签或单分类场景设计的。下面给你两种实用的解决方案:
方法一:利用class_mode='raw'结合合并标签列
如果你的所有标签可以拼接成一个单一的长向量,这种方法最直接:
- 先预处理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)
- 调用
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])
方法二:自定义生成器(更灵活)
如果不想合并标签,或者需要保留各个标签的独立结构,自定义生成器会更适配:
- 先创建仅加载图片的生成器:
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确保图片和标签顺序一致 )
- 编写标签生成器,从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)
- 合并两个生成器,确保图片与标签一一对应:
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
相关产品推荐
相关产品推荐

