gpt4 book ai didi

performance - TensorFlow:使用队列提供数据与使用 feed_dict 直接提供数据

转载 作者:行者123 更新时间:2023-12-04 01:58:50 24 4
gpt4 key购买 nike

我一直在使用 feed_dict 来直接输入 placeholder在像 MNIST 这样的小问题中练习编码。 TensorFlow 还支持使用 queue 馈送数据和 queue runner ,它需要一些努力来学习。

有没有人对这两种方法进行比较并衡量性能?是否值得花时间学习使用队列来馈送数据?

我想使用队列不仅是为了性能,也是为了更清晰的代码,这意味着什么。也许一个数据集的代码可以很容易地用于另一个数据集(一旦我将数据转换为 TFRecord)?

然而,this post似乎说队列可能比 feed_dict 方法慢。现在还是这样吗?如果代码更慢且更难编码,我为什么要使用队列?

感谢您的投入。

最佳答案

我的 NMT 模型有 2 层,512 个隐藏单元。我用最大句子长度 = 50,批量大小 = 32 进行训练,看到 feed_dict 和队列之间的速度相似,大约每秒 2400-2500 个目标词(我使用这个指标来衡量基于此 paper 的速度)。

我发现 feed_dict 非常直观且易于使用。排队很难。使用队列,您必须:

1/将您的数据转换为 tfrecords。我实际上需要谷歌一下以了解如何将我的 seq2seq 数据转换为 tfrecords,因为文档不是很有帮助。

2/从 tfrecords 解码您的数据。您会发现用于生成 tfrecords 和解码的函数并不直观匹配。例如,如果我的每个训练示例都有 3 个序列(只有 3 个整数列表)src_input, trg_input, trg_target我想记录src_input的长度也是(它的一些元素可能是 PADDING,所以不要计算),这里是如何从每个示例生成 tfrecord:

def _make_example(src_input, src_seq_length, trg_input, trg_seq_length, trg_target, target_weight):
context = tf.train.Features(
feature={
'src_seq_length': int64_feature(src_seq_length)
})
feature_lists = tf.train.FeatureLists(
feature_list={
'src_input': int64_featurelist(src_input),
'trg_input': int64_featurelist(trg_input),
'trg_target': int64_featurelist(trg_target)
})

return tf.train.SequenceExample(context=context, feature_lists=feature_lists)

这是解码它的方法:
def _read_and_decode(filename_queue):
reader = tf.TFRecordReader(options=self.tfrecord_option)
_, serialized_ex = reader.read(filename_queue)

context_features = {
'src_seq_length': tf.FixedLenFeature([], dtype=tf.int64)
}
sequence_features = {
'src_input': tf.FixedLenSequenceFeature([], dtype=tf.int64),
'trg_input': tf.FixedLenSequenceFeature([], dtype=tf.int64),
'trg_target': tf.FixedLenSequenceFeature([], dtype=tf.int64)
}
context, sequences = tf.parse_single_sequence_example(
serialized_ex,
context_features=context_features,
sequence_features=sequence_features)

src_seq_length = tf.cast(context['src_seq_length'], tf.int32)
src_input = tf.cast(sequences['src_input'], tf.int32)
trg_input = tf.cast(sequences['trg_input'], tf.int32)
trg_target = tf.cast(sequences['trg_target'], tf.int32)

return src_input, src_seq_length, trg_input, trg_target

并生成每个 tfrecord 功能/功能列表:
def int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

def int64_featurelist(l):
feature = [tf.train.Feature(int64_list=tf.train.Int64List(value=[x])) for x in l]
return tf.train.FeatureList(feature=feature)

http://gph.is/2cg7iKP

3/训练/开发设置。我相信定期训练模型一段时间,然后在开发集上评估,然后重复是一种常见的做法。我不知道如何用队列来做到这一点。使用 feed_dict,您只需在同一 session 下构建两个具有共享参数的图形,一个用于训练,另一个用于开发。当您对开发集进行评估时,只需将开发数据提供给开发图,就是这样。但是对于队列,队列的输出是图本身的一部分。要运行队列,你必须启动队列运行器,创建一个协调器,使用这个协调器来管理队列。完成后,队列已关闭!!!。目前,我不知道如何最好地编写我的代码以使火车/开发设置与队列一致,除了打开新 session ,每次评估时为开发构建新图。提出了同样的问题 here ,你可以在 Stackoverflow 上谷歌搜索类似的问题。

但是,很多人说 queue 比 feed_dict 更快。我的猜测是,如果您以分布式方式训练,队列是有益的。但对我来说,我经常只在 1 个 GPU 上训练,到目前为止,我对队列根本没有印象。嗯,只是我的猜测。

关于performance - TensorFlow:使用队列提供数据与使用 feed_dict 直接提供数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38416824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com