ImageDataGenerator用于使用flow_from_directory在Keras中进行多任务输出

时间:2020-03-10 15:38:17

标签: tensorflow keras

我正在创建一个多任务CNN模型,我有两个不同的分类属性(一个具有10个类,第二个具有5个类),并且我的目录结构如下所示:

    -Train
       - image1.jpg
          ...
       - imageN.jpg
   
    -Test
       - image1.jpg
             ...
       - imageN.jpg

    -Vald
       - image1.jpg
          ...
       - imageN.jpg

trainlabel是一个数据帧,其中包含Image,PFRType,FuelType列

我正在尝试使用flow_from_dataframe,而我的生成器是:

trainGen = ImageDataGenerator()
trainGenDf = trainGen.flow_from_dataframe(trainLabel,
                                         directory = '../MTLData/train/',
                                         x_col = "Image",y_col=["PFRType","FuelType"],
                                         class_mode='multi_ouput',
                                         target_size=(224,224),
                                         batch_size=32)

我得到的错误是: 检查目标时出错:预期PFR的形状为(10,),但数组的形状为(1,)

PFR是具有10个类输出的子任务层

这是模型图。 enter image description here

2 个答案:

答案 0 :(得分:2)

您可以使用flow_from_dataframe。 您只需要将包含标签的csv文件解析为pandas数据框,即可将文件名映射到其相应的标签。

例如,如果数据框看起来像:

import ReactJson from "react-json-view";
import React from "react";

class JsonDialog extends React.Component {
constructor(props) {
    super(props);

    this.state = {
      checked: false,
      copied: false
    };
  }
render(){
    const themeName = this.props.dark ? 'apathy':'apahty:inverted'
    return    <ReactJson src={json} theme={themeName} /> // here I need to apply theme on the basis of dark or light mode
  } 
}

您可以为每个子集创建一个生成器:

| image_path | label_task_a | label_task_b | subset |
|------------|--------------|--------------|--------|
| image1.jpg | foo          | bla          | Train  |
| ...        | ...          | ...          | ...    |
| imageN.jpg | baz          | whatever     | Vald   |

编辑1:

关于您的错误:如果设置train_generator_task_a = datagen.flow_from_dataframe( dataframe=df[df.subset == 'Train']], directory='data/Train', x_col='image_path', y_col=['label_task_a', 'label_task_b'], # outputs for both tasks. batch_size=32, seed=42, shuffle=True, class_mode='categorical') ,Keras希望标签为一维numpy整数标签数组。您是否尝试将其设置为class_mode='sparse'

答案 1 :(得分:0)

我已将自定义函数用于生成器,到目前为止,该功能不支持随机播放!

def get_data_generator(data, split ,batch_size=16):
        imagePath = ''
        df =''

        if split == 'train':
            imagePath = '../MTLData/train/'
            df = data[data.dir == 'train']
        elif split == 'test':
            imagePath = '../MTLData/test/'
            df = data[data.dir == 'test']
        elif split == 'vald':
            imagePath = '../MTLData/vald/'
            df = data[data.dir == 'vald']

        pfrID = len(data.PFRType.unique())
        ftID = len(data.FuelType.unique())
        images, pfrs,fts = [], [], []
        while True:
            for i in range(0,df.shape[0]):
                r = df.iloc[i]
                file, pfr, ft = r['Image'], r['PFRType'], r['FuelType']
                im = Image.open(imagePath+file)
                im = im.resize((224, 224))
                im = np.array(im) / 255.0
                images.append(im)
                pfrs.append(to_categorical(pfr, pfrID))
                fts.append(to_categorical(ft, ftID))
                if len(images) >= batch_size:
                    yield np.array(images), [np.array(pfrs), np.array(fts)]
                    images, pfrs, fts = [], [], []