在回归模型中使用 Keras ImageDataGenerator
Using Keras ImageDataGenerator in a regression model
我想使用
flow_from_directory
的方法
ImageDataGenerator
为回归模型生成训练数据,目标值可以是 1 到 -1 之间的任意浮点值。
flow_from_directory
有一个 "class_mode" 参数描述
class_mode: one of "categorical", "binary", "sparse" or None. Default:
"categorical". Determines the type of label arrays that are returned:
"categorical" will be 2D one-hot encoded labels, "binary" will be 1D
binary labels, "sparse" will be 1D integer labels.
我应该采用这些值中的哪一个? None 似乎真的很适合...
目前(2017 年 1 月 21 日最新版本的 Keras)flow_from_directory
只能以下列方式工作:
您需要按以下方式构建目录:
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
...
...
flow_from_directory
returns 固定大小的批次,格式为 (picture, label)
.
因此,如您所见,它只能用于 class 化案例,并且文档中提供的所有选项仅指定将 class 提供给您的 [=44] 的方式=] 器。但是,有一个巧妙的 hack 可以使 flow_from_directory
对回归任务有用:
您需要按以下方式构建目录:
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
...
...
您还需要有一个列表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]
flow_from_directory_gen
拥有 class_mode='sparse'
才能完成这项工作至关重要。当然这有点麻烦但它有效(我使用了这个解决方案:))
我认为以不同方式组织数据,使用 DataFrame(不必将图像移动到新位置)将使您能够 运行 回归模型。简而言之,在您的 DataFrame 中创建包含每个图像的文件路径和目标值的列。这允许您的生成器保持回归值和图像正确同步,即使您在每个时期打乱数据。
这是一个示例,展示了如何 link 具有二项式目标、多项式目标和回归目标的图像只是为了表明 "a target is a target is a target" 并且只有模型可能会发生变化:
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
我在此处通过示例详细描述了如何执行此操作:
我想指出已接受的答案中只有一处错误。上面的代码失败并显示如下错误消息:
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
生成list_of_values的方法可以在
中找到
在 Keras 2.2.4 中,您可以使用“.flow_from_dataframe”来解决您想要做的事情,从而允许您从目录中流动图像以解决回归问题。您应该将所有图像存储在一个文件夹中,并加载一个数据框,其中一列包含图像 ID,另一列包含回归分数(标签),并在“.flow_from_dataframe”中设置 "class_mode='other'"。
在这里您可以找到一个示例,其中图像在 "image_dir" 中,具有图像 ID 和回归分数的数据框从 "train file"
中加载 pandas ]
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)
我想使用
flow_from_directory
的方法
ImageDataGenerator
为回归模型生成训练数据,目标值可以是 1 到 -1 之间的任意浮点值。
flow_from_directory
有一个 "class_mode" 参数描述
class_mode: one of "categorical", "binary", "sparse" or None. Default: "categorical". Determines the type of label arrays that are returned: "categorical" will be 2D one-hot encoded labels, "binary" will be 1D binary labels, "sparse" will be 1D integer labels.
我应该采用这些值中的哪一个? None 似乎真的很适合...
目前(2017 年 1 月 21 日最新版本的 Keras)flow_from_directory
只能以下列方式工作:
您需要按以下方式构建目录:
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 ... ...
flow_from_directory
returns 固定大小的批次,格式为(picture, label)
.
因此,如您所见,它只能用于 class 化案例,并且文档中提供的所有选项仅指定将 class 提供给您的 [=44] 的方式=] 器。但是,有一个巧妙的 hack 可以使 flow_from_directory
对回归任务有用:
您需要按以下方式构建目录:
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 ... ...
您还需要有一个列表
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]
flow_from_directory_gen
拥有 class_mode='sparse'
才能完成这项工作至关重要。当然这有点麻烦但它有效(我使用了这个解决方案:))
我认为以不同方式组织数据,使用 DataFrame(不必将图像移动到新位置)将使您能够 运行 回归模型。简而言之,在您的 DataFrame 中创建包含每个图像的文件路径和目标值的列。这允许您的生成器保持回归值和图像正确同步,即使您在每个时期打乱数据。
这是一个示例,展示了如何 link 具有二项式目标、多项式目标和回归目标的图像只是为了表明 "a target is a target is a target" 并且只有模型可能会发生变化:
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
我在此处通过示例详细描述了如何执行此操作:
我想指出已接受的答案中只有一处错误。上面的代码失败并显示如下错误消息:
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
生成list_of_values的方法可以在
中找到在 Keras 2.2.4 中,您可以使用“.flow_from_dataframe”来解决您想要做的事情,从而允许您从目录中流动图像以解决回归问题。您应该将所有图像存储在一个文件夹中,并加载一个数据框,其中一列包含图像 ID,另一列包含回归分数(标签),并在“.flow_from_dataframe”中设置 "class_mode='other'"。
在这里您可以找到一个示例,其中图像在 "image_dir" 中,具有图像 ID 和回归分数的数据框从 "train file"
中加载 pandas ]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)