【问题标题】:ImageDataGenerator flow_from_dataframe multi_output regression and classification syntax problemImageDataGenerator flow_from_dataframe 多输出回归和分类语法问题
【发布时间】:2021-03-01 14:41:24
【问题描述】:

背景

我正在使用 tensorflow.keras.preprocessing.image ImageDataGenerator

from tensorflow.keras.preprocessing.image import ImageDataGenerator

我一直在努力寻找一个“multi_output”自定义生成器的示例,该生成器将浮点向量(例如,代表边界框的 4 个向量)作为标签传递给 2 个网络头之一,以及一个单热编码向量(例如 3 个类)作为另一个头的标签。

第一个网络头将对 4 向量边界框进行回归

First Head

第二个网络头将对“one-hot” 3-vector进行分类。

Second Head

我的结构与找到的here 非常相似。

唯一的区别是我不想一次将所有图像加载到内存中,因此我希望使用生成器。

我认为我的代码很接近,但我发现的各种示例并不是我所需要的。

这是我第一次拥有的(请参阅下面的其他详细信息了解我目前拥有的):

def generate_image_generator(generator, data_directory, data_items, target_size, classes, batch_size, shuffle, class_mode):
frames=[]
for di in data_items:
    df = pd.read_csv(data_directory+di["file"])
    #df["cls"] = df["cls"].apply(lambda x: x.split(","))
    frames.append(df)
df = pd.concat(frames)
a = pd.get_dummies(df['cls'], prefix='cls')
df = pd.concat([df, pd.get_dummies(df['cls'], prefix='cls')], axis=1)
df.head()
#                                              y_col=(['sxu', 'syu', 'exu', 'eyu'], 'cls'),
genImages = generator.flow_from_dataframe(dataframe=df, directory=data_directory, target_size=target_size,
                                          x_col="file",
                                          y_col=[('sxu', 'syu', 'exu', 'eyu'), ('cls_airplane', 'cls_face', 'cls_motorcycle')],
                                          class_mode="multi_output",
                                          classes=classes, batch_size=batch_size, shuffle=shuffle, seed=2)

特别注意以下两行:

 y_col=[('sxu', 'syu', 'exu', 'eyu'), ('cls_airplane', 'cls_face', 'cls_motorcycle')],
 class_mode="multi_output",

第一行应该指定一个包含 2 个标签元素的列表(我的模型中的 2 个头、4 向量回归头和 3 向量分类头各一个)

加载到 pandas 数据框中的 CSV 文件示例如下所示

    id,file,sx,sy,ex,ey,cls,sxu,syu,exu,eyu,w,h
0,motorcycle.0001.jpg,31,19,233,141,motorcycle,0.1183206106870229,0.11801242236024845,0.8893129770992366,0.8757763975155279,262,161
1,motorcycle.0002.jpg,32,15,232,142,motorcycle,0.12167300380228137,0.09259259259259259,0.8821292775665399,0.8765432098765432,263,162

请注意,在上面的代码中,我向 pandas 数据帧添加了额外的“one-hot”列(cls_motorcycle、cls_face、cls_airplane)。这些是在我的“y_col”数组中的第二个元组中引用的列。

The augmented pandas dataframe that includes my one-hot columns

错误

我正在使用 tensorflow 的 keras 实现。我收到的错误是 pandas 数据框中的“关键错误”。

Full Stack Trace

显然 tensorflow keras 不喜欢我为“multi_output”标签传递的元组列表。它认为列表中的第一个元组实际上是一列中的单个键,而不是 4 列中的 4 个键。

问题

如何为flow_from_dataframe 配置一个头的“multi_output”回归标签,第二个头的分类标签?

其他详情

我现在尝试执行以下操作(请注意,我现在为标签生成一个 2 元组 - 这是我努力的最新状态),我认为我更进一步.. 但是我认为这还不正确(代码sn-p下面的堆栈跟踪):

def generate_image_generator(generator, data_directory, data_items, target_size, classes, batch_size, shuffle, class_mode):
frames=[]
for di in data_items:
    df = pd.read_csv(data_directory+di["file"])
    frames.append(df)
df = pd.concat(frames)

labels = ['sxu', 'syu', 'exu', 'eyu', 'cls_onehot']
df['cls_onehot'] = df['cls'].str.get_dummies().values.tolist()

genImages = generator.flow_from_dataframe(dataframe=df, directory=data_directory, target_size=target_size,
                                          x_col="file",
                                          y_col=labels,
                                          class_mode="multi_output",
                                          classes=classes, batch_size=batch_size, shuffle=shuffle, seed=2)

while True:
    images, labels = genImages.next()
    yield images[0], ([labels[0], labels[1], labels[2], labels[3]], labels[4])

我走得更远了,所以也许我的生成器现在没问题,但我现在确实看到了以下跟踪(当我开始训练模型时):

New Stack Trace During First Training Epoch

在下面的 pycharm 调试视图中,您可以看到图像和标签,因为它们存在于生成器“产生”的位置。请注意,我的批量大小是 5。

Batch of Images and Labels yielded by generator

【问题讨论】:

    标签: tensorflow keras tf.keras


    【解决方案1】:

    这似乎是正确的答案:

    def generate_image_generator(generator, data_directory, data_items, target_size, classes, batch_size, shuffle, class_mode):
    frames=[]
    for di in data_items:
        df = pd.read_csv(data_directory+di["file"])
        frames.append(df)
    df = pd.concat(frames)
    
    df['cls_onehot'] = df['cls'].str.get_dummies().values.tolist()
    df['bbox'] = df[['sxu', 'syu', 'exu', 'eyu']].values.tolist()
    
    genImages = generator.flow_from_dataframe(dataframe=df, directory=data_directory, target_size=target_size,
                                              x_col="file",
                                              y_col=['bbox', 'cls_onehot'],
                                              class_mode="multi_output",
                                              classes=classes, batch_size=batch_size, shuffle=shuffle, seed=2)
    
    while True:
        images, labels = genImages.next()
        targets = {
            'class_label': labels[1],
            'bounding_box': labels[0]
        }
        yield images, targets
    

    【讨论】:

    • :( 我仍然遇到这个问题。培训似乎永远不想结束。对此自定义生成器的任何帮助将不胜感激。
    • 好的。看起来这实际上是正确的答案。我唯一剩下的问题是,当我调用 fit 时,我忘记设置每个 epoch 的步数。因此张量流将“永远适合”
    猜你喜欢
    • 2019-03-20
    • 2020-11-22
    • 1970-01-01
    • 2020-05-13
    • 2015-11-23
    • 2019-07-06
    • 2020-03-22
    • 2020-10-27
    • 2016-09-22
    相关资源
    最近更新 更多