我的主要问题是:我有200 GB的训练tfrecord文件,有200万张图像,28GB用于验证tf.record文件,302900张图像.培训一个时代需要8个小时,培训需要33天.我想通过使用多个线程和分片加快速度,但我对一些事情有点困惑.
在tf.data.Dataset API中有shard函数,所以在文档中他们提到了关于shard函数的以下内容:
创建仅包含此数据集的1/num_shards的数据集.
此数据集运算符在运行分布式培训时非常有用,因为它允许每个工作者读取唯一的子集.
读取单个输入文件时,可以跳过如下元素:
d = tf.data.TFRecordDataset(FLAGS.input_file)
d = d.shard(FLAGS.num_workers, FLAGS.worker_index)
d = d.repeat(FLAGS.num_epochs)
d = d.shuffle(FLAGS.shuffle_buffer_size)
d = d.map(parser_fn, num_parallel_calls=FLAGS.num_map_threads)
Run Code Online (Sandbox Code Playgroud)
重要提示:
在使用任何随机化运算符(例如shuffle)之前,请务必进行分片.通常,最好在数据集管道的早期使用分片运算符.>例如,从一组TFRecord文件中读取时,在转换之前将分片>数据集输入样本.这样可以避免读取每个工作人员的每个文件.以下是完整>管道中有效分片策略的示例:
d = Dataset.list_files(FLAGS.pattern)
d = d.shard(FLAGS.num_workers, FLAGS.worker_index)
d = d.repeat(FLAGS.num_epochs)
d = d.shuffle(FLAGS.shuffle_buffer_size)
d = d.repeat()
d = d.interleave(tf.data.TFRecordDataset,
cycle_length=FLAGS.num_readers, block_length=1)
d = d.map(parser_fn, num_parallel_calls=FLAGS.num_map_threads)
Run Code Online (Sandbox Code Playgroud)
这些是我的问题:
1- tf.records文件的数量与分片数量之间是否有任何关系?是碎片数量(工人)取决于你拥有的CPU数量,或者你拥有的tf.records文件的数量?以及如何创建它,只需将分片数设置为特定数字?,或者我们需要将文件拆分为多个文件,然后设置特定的分片数.请注意参考碎片数量的工人数量
2-创建多个tf.records文件有什么好处?有些人说这里是关于什么时候你需要以更好的方式改变tf.records,但是在tf.Dataset API中存在Shuufle方法我们不需要这样做,而其他人在这里说它只是分裂你的数据到较小尺寸的零件.我的问题我是否需要将我的tf.records文件拆分为多个文件
3-现在我们来到map函数中的num_threads(在新版本的tensorflwo中的num_paralle_calls)应该与你拥有它的碎片数量相同.当我搜索时,我发现有人说如果你有10个分片和2个线程,每个线程将需要5个分片.
4-关于d.interleave函数,我知道它是如何工作的,就像在这个例子中提到的那样.但是我再次错过了连接num_threads,例如循环长度
5-如果我想使用多个GPU,我应该使用分片吗?如此处接受的评论中所述
作为总结,我对(tf.records文件的数量,num_shards(工人),循环长度,num_thread(num_parallel_calls)之间的关系感到困惑.为了最大限度地缩短两种情况的训练时间,创建的情况更好(使用多个GPU,并使用单GPU)
我的 Keras 模型有两个输入和三个输出。我的 tfrecords 文件有一对图像和一对标签。如果我使用fit_generator
,它会正常工作。在其中我创建了自己的生成器,为两个模型输入提供两个图像,三个标签提供三个模型输出。但我想用model.fit
. 在其中我可以直接传递数据集实例。所以任何人都知道如何将 (x1, x2(, (y1, y2, y3) 的元组传递给 Keras 模型 vi tf.dataset API。
我之前用过的:
def _parse_function_all(example_proto):
features = {'image_raw1': tf.FixedLenFeature([], tf.string),
'image_raw2': tf.FixedLenFeature([], tf.string),
'label1': tf.FixedLenFeature([], tf.int64),
'label2': tf.FixedLenFeature([], tf.int64),
'label3': tf.FixedLenFeature([], tf.int64),
}
features = tf.parse_single_example(example_proto, features)
image1 = tf.decode_raw(features['image_raw1'], tf.uint8)
image2 = tf.decode_raw(features['image_raw2'], tf.uint8)
image1.set_shape([ 224 * 224 * 3])
image2.set_shape([ 224 * 224 * 3])
image1= tf.reshape(image1, ( 224 , 224 , 3))
image2 = tf.reshape(image2, (224 , 224 …
Run Code Online (Sandbox Code Playgroud) 我的问题是,如果要为我的数据创建一个tfrecords文件,大约需要15天才能完成它,它有500000对模板,每个模板为32帧(图像)。为了节省时间,我有3个GPU,因此我想可以在一个GPU上创建三个tfrocords文件,每个文件一个,然后在5天内完成创建tfrecords的操作。但是后来我搜索了将这三个文件合并到一个文件中的方法,但找不到合适的解决方案。
因此,有没有办法将这三个文件合并到一个文件中,或者有没有办法知道我使用的是Dataset API,通过提供从这三个tfrecords文件提取的一批示例来训练我的网络。
我有一个大型数据集存储在tfrecord
333 之类的文件中用于训练,因此我将数据分成多个文件,例如 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=0
in时才有效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()
. 当我检查图形时,我注意到与我的输入管道相关的所有映射函数在不同的图形(子图形)中,并且它不能附加到主图形中。像下面这样:
我应该提到,这是一个两阶段的培训。首先,我使用基于图像的数据集构建了一个网络,并且该网络在imagene
t上进行了预训练,我刚刚训练了我的分类器。数据集在hdf5
文件中,可以放入内存中。在第二阶段,我在第一阶段使用经过训练的网络并将一些块附加到它上面,我的数据集这里是tfrecod
文件,这就是为什么我使用 atf.Dataset API
作为我的输入管道的原因。所以这个新的输入管道不存在于第一阶段的第一个图中。但没关系,我只是将预处理过的网络用作基本模式,然后向其添加不同的块。所以它是全新的模型。
而我想换工人的主要原因,因为我的 GPU 利用率始终为零,这意味着 CPU 是瓶颈,这意味着 Cpu 需要花费大量时间来提取数据。我的 GPU 总是在等待。这就是为什么训练需要很长时间,比如一个 epoch …
我有不平衡的training
数据集,这就是为什么我建立自定义 weighted categorical cross entropy loss
功能.但问题是我的validation
设置是平衡的,我想使用常规的分类交叉熵损失.那么我可以为Keras中的验证集传递不同的损失函数吗?我指的是用于培训的受损者和用于验证集的常规用品?
def weighted_loss(y_pred, y_ture):
'
'
'
return loss
model.compile(loss= weighted_loss, metric='accuracy')
Run Code Online (Sandbox Code Playgroud)