TensorFlow Keras中ImageDataGenerator生成数组的dtype问题求助
解决Keras flow_from_dataframe处理嵌套numpy数组标签的问题
你遇到的核心问题是DataFrame的label列存储的是单个(4,)的numpy数组,这会让该列的dtype变成object。当flow_from_dataframe用class_mode='raw'读取时,会直接将这些嵌套的数组收集成一个一维的object数组,而非二维的float数组,导致后续无法转成Tensor。
以下是三种可行的解决方案:
方案1:拆分标签列为多列(最简单)
把每个(4,)的标签数组拆成4个独立的列,让flow_from_dataframe直接读取多列作为标签:
import pandas as pd # 拆分label列到4个新列 df[['label_0', 'label_1', 'label_2', 'label_3']] = pd.DataFrame(df['label'].tolist(), index=df.index) # 拆分训练集和验证集 train_df, val_df = train_test_split(df, test_size=0.1, random_state=42) datagen = ImageDataGenerator(rescale=1./255) # 修改flow_from_dataframe的y_col为新列名列表 train_gen = datagen.flow_from_dataframe( dataframe=train_df, x_col="photo", y_col=['label_0', 'label_1', 'label_2', 'label_3'], target_size=(32, 32), class_mode='raw', batch_size=b_size ) # 验证结果 generated = train_gen.next() print(generated[1].dtype) # 输出float32 print(generated[1].shape) # 输出(b_size, 4)
方案2:自定义数据生成器(更灵活)
如果不想修改DataFrame结构,可以自己实现生成器,手动处理图片加载和标签转换:
import numpy as np from tensorflow.keras.preprocessing.image import load_img, img_to_array def custom_generator(df, batch_size, target_size): while True: # 随机抽取batch数据 batch_df = df.sample(n=batch_size, replace=True) # 加载并预处理图片 features = [] for img_path in batch_df['photo']: img = load_img(img_path, target_size=target_size) img_arr = img_to_array(img) / 255.0 features.append(img_arr) # 将嵌套的标签数组转成二维numpy数组 labels = np.stack(batch_df['label'].values) yield np.array(features), labels # 使用自定义生成器 train_gen = custom_generator(train_df, b_size, (32, 32)) val_gen = custom_generator(val_df, b_size, (32, 32))
方案3:使用TensorFlow Dataset API(推荐,适合TF2.x)
TF的Dataset API对嵌套数据支持更好,处理起来更高效:
import tensorflow as tf def preprocess_image(img_path, label): # 读取并解码图片 img = tf.io.read_file(img_path) img = tf.image.decode_jpeg(img, channels=3) img = tf.image.resize(img, (32, 32)) img = tf.cast(img, tf.float32) / 255.0 # 将标签转换为float32张量 label = tf.convert_to_tensor(label, dtype=tf.float32) return img, label # 创建训练集Dataset train_ds = tf.data.Dataset.from_tensor_slices((train_df['photo'].values, train_df['label'].values)) train_ds = train_ds.map(preprocess_image).batch(b_size).prefetch(tf.data.AUTOTUNE) # 创建验证集Dataset val_ds = tf.data.Dataset.from_tensor_slices((val_df['photo'].values, val_df['label'].values)) val_ds = val_ds.map(preprocess_image).batch(b_size).prefetch(tf.data.AUTOTUNE) # 训练时直接传入Dataset model.fit(train_ds, validation_data=val_ds, epochs=10)
内容的提问来源于stack exchange,提问作者FarmerZee
相关产品推荐
相关产品推荐

