我构建了一个简单的生成器,tuple(inputs, targets)在inputs和targets列表中只生成一个单项.基本上,它一次抓取数据集,一个样本项.
我把这个发生器传递给:
model.fit_generator(my_generator(),
nb_epoch=10,
samples_per_epoch=1,
max_q_size=1 # defaults to 10
)
Run Code Online (Sandbox Code Playgroud)
我明白了:
nb_epoch 是训练批次的运行次数samples_per_epoch 是每个时期训练的样本数量但它是什么max_q_size,为什么它会默认为10?我认为使用生成器的目的是将数据集批量化为合理的块,那么为什么要添加额外的队列呢?
我有一个大型数据集存储在tfrecord333 之类的文件中用于训练,因此我将数据分成多个文件,例如 1024 tfrecords 文件而不是一个文件。我在 tf.Dataset Api 中使用了输入管道。喜欢:
ds= ds.TFRecordsDataset(files).shuffle().repeat().shuffle().repeat()
ds = ds.prefetch(1)
Run Code Online (Sandbox Code Playgroud)
而且我有自己的生成器,可以生成batch_x, batch_y.
我的问题是代码仅在我设置workers=0in时才有效fit_generator()。
每当我将其设置为大于 0 时,都会出现以下错误
ValueError: Tensor("PrefetchDataset:0", shape=(), dtype=variant) 必须与 Tensor("Iterator:0", shape=(), dtype=resource) 来自同一图。
workers =他们说,如果0 还不够,则有关这意味着什么的文档
如果为 0,将在主线程上执行生成器。
我在 github here 中发现了类似的问题,但还没有解决方案。
这里发布了另一种类似的问题,但我不同,因为我使用的是 Keras 而不是张量流,而且我没有使用 with tf.Graph().as_default(). 建议有两个图而不是一个图,因此解决方案是删除tf.Graph().as_default(). 当我检查图形时,我注意到与我的输入管道相关的所有映射函数在不同的图形(子图形)中,并且它不能附加到主图形中。像下面这样:
我应该提到,这是一个两阶段的培训。首先,我使用基于图像的数据集构建了一个网络,并且该网络在imagenet上进行了预训练,我刚刚训练了我的分类器。数据集在hdf5文件中,可以放入内存中。在第二阶段,我在第一阶段使用经过训练的网络并将一些块附加到它上面,我的数据集这里是tfrecod文件,这就是为什么我使用 atf.Dataset API作为我的输入管道的原因。所以这个新的输入管道不存在于第一阶段的第一个图中。但没关系,我只是将预处理过的网络用作基本模式,然后向其添加不同的块。所以它是全新的模型。
而我想换工人的主要原因,因为我的 GPU 利用率始终为零,这意味着 CPU 是瓶颈,这意味着 Cpu 需要花费大量时间来提取数据。我的 GPU 总是在等待。这就是为什么训练需要很长时间,比如一个 epoch …
在fit_generator()的文档(文档:https ://keras.io/models/sequential/#fit_generator )中,它说参数use_multiprocessing接受一个布尔值,如果将其设置为True,则该布尔值允许基于进程的线程。
它还说,参数worker是一个整数,它指定如果使用基于进程的线程处理,要启动多少个进程。显然,它默认为1(基于单个进程的线程),如果设置为0,它将在主线程上执行生成器。
我的意思是,如果use_multiprocessing = True且workers> 0(以6为例),它将启动6个独立运行生成器的进程。但是,当我对此进行测试时,我认为我一定会误会某些东西(请参阅下文)。
我感到困惑的原因是,如果我将use_multiprocessing设置为False并且worker = 1,那么在我的任务管理器中,我可以看到我的所有12个虚拟内核都被平均地利用,并且在训练模型时我的CPU使用率约为50% (作为参考,我有一个i6-8750H CPU,它具有6个支持虚拟化的内核,并且在BIOS中启用了虚拟化)。如果增加工人数量,CPU使用率将达到100%,培训速度将大大提高。如果我将工作程序的数量减少到0以便它在主线程上运行,我可以看到我的所有虚拟内核仍在使用中,但是似乎有些不平衡,CPU使用率约为36%。
不幸的是,如果我将multiprocessing设置为True,那么我将得到一个坏管道错误。我尚未解决此问题,但我想更好地了解我要在此处解决的问题。
如果有人可以解释use_multiprocessing = True和use_multiprocessing = False进行训练之间的区别,以及当worker = 0、1和> 1时的区别,我将不胜感激。如果有关系,我将tensorflow(gpu版本)作为IPython控制台在Spyder中使用python 3.6的keras后端。
我的怀疑是,当True时use_multiprocessing实际上启用了多处理,而当use_multiprocessing = False时worker> 1设置了线程数,但这只是一个猜测。