首页 > 解决方案 > 生成器从多个文件中读取作为 keras 的输入进行多处理

问题描述

我正在用 keras 训练一个神经网络,并希望通过多处理来加速我的预处理/数据增强。原则上,在workers=Nuse_multiprocessing=True中这似乎很简单fit_generator,但在我的情况下,避免从并行生成器获取类似数据是很棘手的。

我的数据在几个文件中,每个文件都有几百万条记录(直到文件末尾才知道总数)。对于每个文件,生成器逐条记录,将记录处理为网络的正确输入/输出格式,并进行一些数据增强。没有唯一的 ID,尽管我想我可以即时创建一个。

我想知道是否有多个并行生成器最容易,每个生成器处理一个单独的文件列表。我实际上并没有批量使用所有数据,因此如果一个生成器在其文件列表的开头重新启动在其他生成器之前重新启动并不重要。如果在生成器中我可以访问诸如工人编号(1 到 N)之类的东西,那将很容易完成。

标签: pythonkerasmultiprocessinggenerator

解决方案


我不确定如何实施您的建议。更高级的解决方案是实例化 a tf.data.TextLineDataset,它可以处理多个文本文件。为了用这个来训练 Keras 模型,您必须将 的输出与模型iteratorInput张量联系起来。这些方面的东西:

import tensorflow as tf 
# Parsing, augmentation etc
def __parse_record(record):
    ...
    return parsed_record

# Construct a TextLineDataset
ds = tf.data.TextLineDataset(filenames).map(_parse_record)
ds.shuffle().batch(batch_size) # Shuffle and batch

# Turn into an iterator
iterator = tf.data.Iterator.from_structure(ds.output_types, ds.output_shapes)
ds_init = iterator.make_initializer(ds)
# The iterator will yield inputs and labels
x,y = iterator.get_next()

# Tie output of iterator into Input of keras model via the tensor argument
model_input = Input(tensor=x)
# ... model definition

# Upon compiling the model specify target tensors
model.compile(loss, optimizer, target_tensors=[y])

# Now you can use model.fit() instead of fit_generator()
with K.get_session() as sess:
    sess.run(ds_init)
    model.fit(epochs, steps_per_epoch)

这应该训练得很快,但是,它带来了一些缺点。根据相关的Keras 示例

输入张量也有重要的缺点。特别是,输入张量在模型构建时是固定的,因为尚不支持重新布线网络。因此,更改数据输入源意味着必须保存模型权重并从头开始重建模型以连接新的输入数据。目前无法在训练进行时执行验证,必须在训练完成后执行。


推荐阅读