具有增强图像和其他功能的 Keras 迭代器
Keras iterator with augmented images and other features
假设您有一个数据集,其中包含图像和每个图像的 .csv
中的一些数据。
您的目标是创建一个具有卷积分支和另一个卷积分支(在我的例子中是 MLP)的神经网络。
现在,有很多关于如何创建网络的指南 (one here, another one),这不是问题所在。
这里的问题是,当 convolution_input
来自添加增强图像的 Keras ImageDataGenerator
flow 时,我如何以 [[convolution_input, other_features], target]
的形式创建迭代器。
更具体地说,当第 n 个图像(可能是增强图像,也可能不是增强图像)被馈送到 NN 时,我希望它的原始特征在 other_features
。
我发现了一些尝试(here and here,第二个看起来很有希望,但我无法弄清楚如何处理增强图像)正是这样做的,但它们似乎没有考虑到Keras 生成器可能进行的数据集操作。
假设您有一个 CSV,这样您的图像和其他功能都在文件中。
其中id
代表图像名称,后面是特征,然后是你的目标,(class表示class化,数字表示回归)
| id | feat1 | feat2 | feat3 | class |
|---------------------|-------|-------|-------|-------|
| 1_face_IMG_NAME.jpg | 1 | 0 | 1 | A |
| 3_face_IMG_NAME.jpg | 1 | 0 | 1 | B |
| 2_face_IMG_NAME.jpg | 1 | 0 | 1 | A |
| ... | ... | ... | ... | ... |
首先,让我们定义一个数据生成器,稍后我们可以覆盖它。
让我们从 pandas 数据框中的 CSV 中读取数据,并使用 keras 的 flow_from_dataframe
从数据框中读取数据。
df = pandas.read_csv("dummycsv.csv")
datagen = ImageDataGenerator(rescale=1/255.)
generator = datagen.flow_from_dataframe(
df,
directory="out/",
x_col="id",
y_col=df.columns[1:],
class_mode="raw",
batch_size=1)
您可以随时在 ImageDataGenerator
中添加增强内容。
上面代码中需要注意的地方flow_from_dataframe
是
x_col
= 图片名称
y_col
= 通常带有 class 名称的列,但让我们稍后通过首先在 CSV 中提供所有其他列来覆盖它。即 feat_1
、feat_2
...直到 class_label
class_mode
= raw
,建议生成器按原样 return y
中的所有值。
现在让我们 override/inherit 上面的生成器并创建一个新的,这样它 returns [img, otherfeatures], [target]
下面是带有注释解释的代码:
def my_custom_generator():
# to keep track of complete epoch
count = 0
while True:
if count == len(df.index):
# if the count is matching with the length of df,
# the one pass is completed, so reset the generator
generator.reset()
break
count += 1
# get the data from the generator
data = generator.next()
# the data looks like this [[img,img] , [other_cols,other_cols]] based on the batch size
imgs = []
cols = []
targets = []
# iterate the data and append the necessary columns in the corresponding arrays
for k in range(batch_size):
# the first array contains all images
imgs.append(data[0][k])
# the second array contains all features with last column as class, so [:-1]
cols.append(data[1][k][:-1])
# the last column in the second array from data is the class
targets.append(data[1][k][-1])
# this will yield the result as you expect.
yield [imgs,cols], targets
为您的验证生成器创建一个类似的函数。如果需要,使用 train_test_split
拆分数据框并创建 2 个生成器并覆盖它们。
像这样传递model.fit_generator
中的函数
model.fit_generator(my_custom_generator(),.....other params)
假设您有一个数据集,其中包含图像和每个图像的 .csv
中的一些数据。
您的目标是创建一个具有卷积分支和另一个卷积分支(在我的例子中是 MLP)的神经网络。
现在,有很多关于如何创建网络的指南 (one here, another one),这不是问题所在。
这里的问题是,当 convolution_input
来自添加增强图像的 Keras ImageDataGenerator
flow 时,我如何以 [[convolution_input, other_features], target]
的形式创建迭代器。
更具体地说,当第 n 个图像(可能是增强图像,也可能不是增强图像)被馈送到 NN 时,我希望它的原始特征在 other_features
。
我发现了一些尝试(here and here,第二个看起来很有希望,但我无法弄清楚如何处理增强图像)正是这样做的,但它们似乎没有考虑到Keras 生成器可能进行的数据集操作。
假设您有一个 CSV,这样您的图像和其他功能都在文件中。
其中id
代表图像名称,后面是特征,然后是你的目标,(class表示class化,数字表示回归)
| id | feat1 | feat2 | feat3 | class |
|---------------------|-------|-------|-------|-------|
| 1_face_IMG_NAME.jpg | 1 | 0 | 1 | A |
| 3_face_IMG_NAME.jpg | 1 | 0 | 1 | B |
| 2_face_IMG_NAME.jpg | 1 | 0 | 1 | A |
| ... | ... | ... | ... | ... |
首先,让我们定义一个数据生成器,稍后我们可以覆盖它。
让我们从 pandas 数据框中的 CSV 中读取数据,并使用 keras 的 flow_from_dataframe
从数据框中读取数据。
df = pandas.read_csv("dummycsv.csv")
datagen = ImageDataGenerator(rescale=1/255.)
generator = datagen.flow_from_dataframe(
df,
directory="out/",
x_col="id",
y_col=df.columns[1:],
class_mode="raw",
batch_size=1)
您可以随时在 ImageDataGenerator
中添加增强内容。
上面代码中需要注意的地方flow_from_dataframe
是
x_col
= 图片名称
y_col
= 通常带有 class 名称的列,但让我们稍后通过首先在 CSV 中提供所有其他列来覆盖它。即 feat_1
、feat_2
...直到 class_label
class_mode
= raw
,建议生成器按原样 return y
中的所有值。
现在让我们 override/inherit 上面的生成器并创建一个新的,这样它 returns [img, otherfeatures], [target]
下面是带有注释解释的代码:
def my_custom_generator():
# to keep track of complete epoch
count = 0
while True:
if count == len(df.index):
# if the count is matching with the length of df,
# the one pass is completed, so reset the generator
generator.reset()
break
count += 1
# get the data from the generator
data = generator.next()
# the data looks like this [[img,img] , [other_cols,other_cols]] based on the batch size
imgs = []
cols = []
targets = []
# iterate the data and append the necessary columns in the corresponding arrays
for k in range(batch_size):
# the first array contains all images
imgs.append(data[0][k])
# the second array contains all features with last column as class, so [:-1]
cols.append(data[1][k][:-1])
# the last column in the second array from data is the class
targets.append(data[1][k][-1])
# this will yield the result as you expect.
yield [imgs,cols], targets
为您的验证生成器创建一个类似的函数。如果需要,使用 train_test_split
拆分数据框并创建 2 个生成器并覆盖它们。
像这样传递model.fit_generator
中的函数
model.fit_generator(my_custom_generator(),.....other params)