【发布时间】:2019-03-26 17:01:18
【问题描述】:
为了加快模型的训练速度,在 CPU 上填充/生成批次并在 GPU 上并行运行模型训练似乎是一种好习惯。为此,可以用 Python 编写一个继承 Sequence 类的生成器类。
这里是文档的链接: https://www.tensorflow.org/api_docs/python/tf/keras/utils/Sequence
文档中重要的一点是:
Sequence是一种更安全的多处理方式。这种结构 保证网络只会在每个样本上训练一次 生成器不是这样的纪元。
并给出了一个简单的代码示例如下:
from skimage.io import imread
from skimage.transform import resize
import numpy as np
import math
# Here, `x_set` is list of path to the images
# and `y_set` are the associated classes.
class CIFAR10Sequence(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 math.ceil(len(self.x) / 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 np.array([
resize(imread(file_name), (200, 200))
for file_name in batch_x]), np.array(batch_y)
据我了解,理想情况下需要在模型中创建此生成器类的实例并将其提供给fit_generator(...) 函数。
gen = CIFAR10Sequence(x_set, y_set, batch_size)
# Train the model
model.fit_generator(generator=gen,
use_multiprocessing=True,
workers=6)
这是来自 Keras 文档的引用:
使用
keras.utils.Sequence保证订购和保证 每个时期每个输入的单一使用使用时use_multiprocessing=True.
在这个形状中,我假设这个设置是线程安全的。 问题 1) 我的假设正确吗?
一个令人困惑的事情是,参数use_multiprocessing 在 Windows 10 上可能没有设置为 True。Keras 不允许这样做。似乎它只能在 Linux 上设置为 True 。 (我不知道在其他平台上是怎样的。)但是workers参数仍然可以设置为大于0的值。
我们来看看这2个参数的定义:
workers:整数。使用时启动的最大进程数 基于进程的线程。如果未指定,workers 将默认为 1。如果 0,将在主线程上执行生成器。
use_multiprocessing:布尔值。如果为 True,则使用基于进程的线程。如果 未指定,use_multiprocessing 将默认为 False。注意 因为这个实现依赖于多处理,你不应该 将不可腌制的参数传递给生成器,因为它们无法传递 易于子进程。
因此,通过使用workers 参数,似乎可以创建多个进程来加速训练,而与use_multiprocessing 是否为真无关。
如果想要使用继承Sequence 的生成器类(在 Windows 10 上),他/她必须将 use_multiprocessing 设置为 False,如下所示:
gen = CIFAR10Sequence(x_set, y_set, batch_size)
# Train the model
model.fit_generator(generator=gen,
use_multiprocessing=False, # CHANGED
workers=6)
而且这里还有多个进程在运行,因为workers = 6。
问题 2) 在将 use_multiprocessing 参数设置为 False 后,此设置仍然是线程安全的还是线程安全特性现在丢失了?我无法根据文档说清楚。
问题 3) 还是和这个话题有关...当以这种方式进行训练时,数据由 CPU 生成并在 GPU 上训练,如果正在训练的模型很浅,由于 GPU 一直在等待来自 CPU 的数据,因此 GPU 利用率最终会非常低,而 CPU 利用率会显着提高。在这种情况下,有没有办法利用一些 GPU 资源来生成数据?
【问题讨论】:
-
+1 @edn 我和你有同样的问题。您在这件事上找到任何有用的答案/资源吗?
-
@AaronDT,感谢您的提醒。我会尽快提供答案。
标签: python tensorflow keras generator