【发布时间】:2019-12-02 05:30:24
【问题描述】:
所以基本上我写了一个 keras 生成器来在它训练时从网络服务器下载图像。这是一种加快训练速度的尝试,这样训练就不必等到整批图像下载后才开始训练。
为了真正加快速度,我想在 keras fit_generator 函数上启用多处理。但是,有时 keras 会尝试一次多次下载同一个图像。这不仅效率低下,而且当多个进程试图一次写入同一个文件时,它还会使程序崩溃。当 multiprocessing 为 False 时,即使有多个工作人员,也不会发生此问题。我认为这是由于 GIL。
通常你可以使用锁来确保同一个文件只被写入一次。但是,我看不到如何使用 keras 来做到这一点。如果有人能给我一些建议,那就太好了。感谢阅读。
这是崩溃的代码:
image_name = str(image['image'])
try:
obj = self.client.get_object(Bucket=S3_BUCKET, Key=SRC_IMG_FOLDER + image_name)
obj_image = Image.open(obj['Body'])
if self.image_extension not in image_name:
image_name += self.image_extension
obj_image.save(self.image_path(image_index))
文件的保存是我遇到问题的地方。
【问题讨论】:
-
在第一个 epoch 下载然后重用它们怎么样?在这种情况下,您只需要根据文件名检查文件是否存在。这是我能想到的最简单的解决方案。
-
这样做的问题是,即使在第一个时代,keras 也可以重用相同的图像。事实上,默认行为是我无法控制 keras 选择下载哪些图像。我考虑过在继续之前检查图像是否已经下载,并且我实现了它,它似乎主要解决了问题。但是,在执行检查后,另一个进程仍然可能开始下载图像,就好像语句不是原子的一样。更不用说每次选择图像时检查整个文件夹中的现有图像是昂贵的。
-
你说的是对的。但是如果我们运行更多的 epoch,图像可能会一次又一次地下载,对吗?如果我们不执行任何检查?
-
您是否可以共享在您创建的自定义 data_generator 中执行多线程的代码部分?
-
据我所知,时代在这里并不重要,keras 只是在任何时候使用和重用它想要的任何图像。据我所知,这意味着我们必须在每次 keras 选择新图像时进行检查。我只是不确定如何以原子方式执行此检查。我不手动执行任何多线程。我正在使用一个 keras fit_generator,它允许我传入 multiprocessing=True。这允许 keras 启动多个进程,所有进程都并行访问我的生成器。不过,我会用崩溃的部分编辑我的帖子。
标签: python python-3.x keras io multiprocessing