【发布时间】:2019-10-19 19:50:09
【问题描述】:
上下文
为了在 Keras 中使用 fit_generator(),我使用了像这样的生成器函数 pseudocode-one:
def generator(data: np.array) -> (np.array, np.array):
"""Simple generator yielding some samples and targets"""
while True:
for batch in range(number_of_batches):
yield data[batch * length_sequence], data[(batch + 1) * length_sequence]
在 Keras 的 fit_generator() 函数中,我想使用 workers=4 和 use_multiprocessing=True - 因此,我需要一个线程安全生成器。
在here 或here 或Keras docs 等stackoverflow 上的答案中,我读到了关于创建一个继承自Keras.utils.Sequence() 的类,如下所示:
class generatorClass(Sequence):
def __init__(self, x_set, y_set, batch_size):
self.x, self.y = x_set, y_set
self.batch_size = batch_size
def __len__(self):
return int(np.ceil(len(self.x) / float(self.batch_size)))
def __getitem__(self, idx):
batch_x = self.x[idx * self.batch_size:(idx + 1) * self.batch_size]
batch_y = self.y[idx * self.batch_size:(idx + 1) * self.batch_size]
return ...
通过使用Sequences Keras 不会在使用多个工作和多处理时抛出任何警告;生成器应该是线程安全的。
无论如何,由于我使用的是自定义函数,我偶然发现了 github 上提供的 Omer Zohars 代码,它允许通过添加装饰器使我的 generator() 线程安全。
代码如下:
import threading
class threadsafe_iter:
"""
Takes an iterator/generator and makes it thread-safe by
serializing call to the `next` method of given iterator/generator.
"""
def __init__(self, it):
self.it = it
self.lock = threading.Lock()
def __iter__(self):
return self
def __next__(self):
with self.lock:
return self.it.__next__()
def threadsafe_generator(f):
"""A decorator that takes a generator function and makes it thread-safe."""
def g(*a, **kw):
return threadsafe_iter(f(*a, **kw))
return g
现在我可以做:
@threadsafe_generator
def generator(data):
...
问题是:使用此版本的线程安全生成器 Keras 仍然会发出警告,即在使用 workers > 1 和 use_multiprocessing=True 时生成器必须是线程安全的,并且可以通过使用 Sequences 来避免这种情况。
我现在的问题是:
- Keras 是否仅因为生成器未继承
Sequences而发出此警告,或者 Keras 是否也会检查生成器是否通常是线程安全的? - 是否使用我选择作为线程安全的方法作为使用来自Keras-docs 的
generatorClass(Sequence)-version? - Keras 可以处理哪些与这两个示例不同的导致线程安全生成器的方法?
编辑:
在较新的 tensorflow/keras-versions (tf > 2) 中,fit_generator() 已弃用。相反,建议将fit() 与生成器一起使用。但是,这个问题仍然适用于使用生成器的fit()。
【问题讨论】:
标签: python multithreading keras multiprocessing thread-safety