在回归模型中使用Keras ImageDataGenerator

时间:2017-01-19 18:44:53

标签: machine-learning neural-network regression keras

我想使用

flow_from_directory

的方法
ImageDataGenerator

生成回归模型的训练数据,其中目标值可以是介于1和-1之间的任何浮点值。

flow_from_directory

有一个" class_mode"带参数的参数

  

class_mode:"分类","二进制","稀疏"或者没有。默认:   "分类&#34 ;.确定返回的标签数组的类型:   "分类"将是2D单热编码标签,"二进制"将是1D   二进制标签,"稀疏"将是1D整数标签。

我应该选择以下哪些值?他们似乎都不适合......

4 个答案:

答案 0 :(得分:4)

此时(2017年1月21日的最新版Keras)flow_from_directory只能以下列方式运作:

  1. 您需要以下列方式构建目录:

    directory with images\
        1st label\
            1st picture from 1st label
            2nd picture from 1st label
            3rd picture from 1st label
            ...
        2nd label\
            1st picture from 2nd label
            2nd picture from 2nd label
            3rd picture from 2nd label
            ...
        ...
    
  2. flow_from_directory(picture, label)
  3. 的格式返回固定大小的批次

    因此,您可以看到它只能用于分类案例,文档中提供的所有选项仅指定向分类器提供类的方式。但是,有一个巧妙的黑客可以使flow_from_directory对回归任务有用:

    1. 您需要按以下方式构建目录:

      directory with images\
          1st value (e.g. -0.95423)\
              1st picture from 1st value
              2nd picture from 1st value
              3rd picture from 1st value
              ...
          2nd value (e.g. - 0.9143242)\
              1st picture from 2nd value
              2nd picture from 2nd value
              3rd picture from 2nd value
              ...
         ...
      
    2. 您还需要一个列表list_of_values = [1st value, 2nd value, ...]。然后以下列方式定义您的生成器:

      def regression_flow_from_directory(flow_from_directory_gen, list_of_values):
          for x, y in flow_from_directory_gen:
              yield x, list_of_values[y]
      
    3. flow_from_directory_gen class_mode='sparse'让这项工作变得至关重要。当然这有点麻烦,但它有效(我用这个解决方案:))

答案 1 :(得分:4)

我认为使用DataFrame以不同方式组织数据(无需将图像移动到新位置)将允许您运行回归模型。简而言之,在DataFrame中创建包含每个图像的文件路径和目标值的列。这样,即使您在每个时代对数据进行随机播放,您的生成器也可以保持回归值和图像的正确同步。

这是一个示例,显示如何将图像与二项式目标,多项目标和回归目标链接,以显示目标是目标是目标"只有模型可能会改变:

df['path'] = df.object_id.apply(file_path_from_db_id)
df

       object_id   bi  multi                                    path     target
index                                                               
0         461756  dog  white    /path/to/imgs/756/61/blah_461756.png   0.166831
1        1161756  cat  black   /path/to/imgs/756/61/blah_1161756.png   0.058793
2        3303651  dog  white   /path/to/imgs/651/03/blah_3303651.png   0.582970
3        3367756  dog   grey   /path/to/imgs/756/67/blah_3367756.png  -0.421429
4        3767756  dog   grey   /path/to/imgs/756/67/blah_3767756.png  -0.706608
5        5467756  cat  black   /path/to/imgs/756/67/blah_5467756.png  -0.415115
6        5561756  dog  white   /path/to/imgs/756/61/blah_5561756.png  -0.631041
7       31255756  cat   grey  /path/to/imgs/756/55/blah_31255756.png  -0.148226
8       35903651  cat  black  /path/to/imgs/651/03/blah_35903651.png  -0.785671
9       44603651  dog  black  /path/to/imgs/651/03/blah_44603651.png  -0.538359
10      49557622  cat  black  /path/to/imgs/622/57/blah_49557622.png  -0.295279
11      58164756  dog   grey  /path/to/imgs/756/64/blah_58164756.png   0.407096
12      95403651  cat  white  /path/to/imgs/651/03/blah_95403651.png   0.790274
13      95555756  dog   grey  /path/to/imgs/756/55/blah_95555756.png   0.060669

我将通过以下示例详细介绍如何执行此操作:

https://techblog.appnexus.com/a-keras-multithreaded-dataframe-generator-for-millions-of-image-files-84d3027f6f43

答案 2 :(得分:1)

我要指出的是,已接受的答案只有一个小问题。上面的代码失败,并显示以下错误消息:

TypeError: only integer scalar arrays can be converted to a scalar index

这是因为y是一个数组。解决方法很简单:

def regression_flow_from_directory(flow_from_directory_gen,
            list_of_values):
    for x, y in flow_from_directory_gen:
        values = [list_of_values[y[i]] for i in range(len(y))]
        yield x, values

可以在https://stackoverflow.com/a/47944082/4082092

中找到生成list_of_values的方法。

答案 3 :(得分:1)

在Keras 2.2.4中,您可以使用“ .flow_from_dataframe”来解决您要执行的操作,从而允许您从目录中流出图像以解决回归问题。您应该将所有图像存储在一个文件夹中,并加载一个数据帧,该数据帧的一列包含图像ID,另一列包含回归分数(标签),并在“ .flow_from_dataframe”中设置“ class_mode ='other'”。

在这里您可以找到一个示例,其中图像位于“ image_dir”中,带有图像ID和回归分数的数据框已加载了来自“训练文件”中的熊猫

train_label_df = pd.read_csv(train_file, delimiter=' ', header=None, names=['id', 'score'])

train_datagen = ImageDataGenerator(rescale = 1./255, horizontal_flip = True,
                                   fill_mode = "nearest", zoom_range = 0.2,
                                   width_shift_range = 0.2, height_shift_range=0.2,
                                   rotation_range=30) 

train_generator = train_datagen.flow_from_dataframe(dataframe=train_label_df, directory=image_dir, 
                                              x_col="id", y_col="score", has_ext=True, 
                                              class_mode="other", target_size=(img_width, img_height), 
                                              batch_size=bs)