我开始使用新的数据集API,而我想做的一件事没有在doc(https://www.tensorflow.org/programmers_guide/datasets#training_workflows)上进行描述。)
我的数据适合内存,因此我希望将其加载到TensorFlow中,以使训练有效,为此我看到了两种方法:
一个人直接将数据直接加载到图中:
dataset = tf.contrib.data.Dataset.from_tensor_slices((X, Y))
iterator = dataset.make_initializable_iterator()
next_element = iterator.get_next()
# loop on epochs
for _ in range(5):
# Initialize an iterator over the training dataset.
sess.run(iterator.initializer)
# loop over all the batch
for _ in range(1000):
s = time.time()
try:
sess.run(next_element)
except tf.errors.OutOfRangeError:
print("Finish epoch")
另一个是将数据加载到占位符中,因此数据不能保存在图中:
features_placeholder = tf.placeholder(features.dtype, features.shape)
labels_placeholder = tf.placeholder(labels.dtype, labels.shape)
dataset = tf.contrib.data.Dataset.from_tensor_slices((features_placeholder, labels_placeholder))
iterator = dataset.make_initializable_iterator()
next_element = iterator.get_next()
# loop on epochs
for _ in range(5):
# Initialize an iterator over the training dataset.
sess.run(iterator.initializer, feed_dict={features_placeholder: X, labels_placeholder: Y})
# loop over all the batch
for _ in range(1000):
s = time.time()
try:
sess.run(next_element)
except tf.errors.OutOfRangeError:
print("Finish epoch")
第二个是我认为最好保存内存,但我不想在每个时期喂数据。这确实是一无所有的表现。
有没有办法只用占位符初始化迭代器?
类似的东西:
sess.run(iterator.initializer, feed_dict={features_placeholder: X, labels_placeholder: Y})
# loop on epochs
for _ in range(5):
# Initialize an iterator over the training dataset.
sess.run(iterator.initializer)
# loop over all the batch
for _ in range(1000):
s = time.time()
try:
sess.run(next_element)
except tf.errors.OutOfRangeError:
print("Finish epoch")
这样,我们可以保持第一个解决方案的性能并保存记忆,例如第二个解决方案。
注意:
一种解决方案是用
dataset.repeat()
定义时期数 方法但是,我们对我们所处位置有些松散的跟踪 培训。我想在每个时期之后检查(一个通过所有数据) 损失的演变。
首先,我建议每次初始化迭代器时量化feeding X
和 Y
的性能开销。对于诸如tf.int32
和tf.float32
之类的原始类型,通常可以在不复制任何数据的情况下喂食一个值,在这种情况下,开销可以忽略不计。即使需要副本,它也会需要一个memcpy()
,这可能很快。(另一方面,喂食tf.string
张量可能更昂贵,因为它需要多个小副本才能在Python和C 字符串表示之间进行转换。)
假设这是一个重要的开销,您可以通过将输入数据存储在tf.Variable
中来使其成为一次性成本。例如:
placeholder_X = tf.placeholder(X.dtype, X.shape)
var_X = tf.Variable(placeholder_X)
placeholder_Y = tf.placeholder(Y.dtype, Y.shape)
var_Y = tf.Variable(placeholder_Y)
dataset = tf.contrib.data.Dataset.from_tensor_slices((var_X, var_Y))
iterator = dataset.make_initializable_iterator()
# ...
# The contents of `X` and `Y` will be copied once, in this call.
sess.run(tf.global_variables_initializer(), feed_dict={
placeholder_X: X, placeholder_Y = Y})
for _ in range(5):
# The iterator will be initialized from the variables with no copy.
sess.run(iterator.initializer)
# ...
我认为您不需要在每个时期初始化。您可以在训练循环之前进行一次。但是,当您定义数据集时,您还需要说出数据集在每次迭代时重复和重新填充:
features_placeholder = tf.placeholder(features.dtype, features.shape)
labels_placeholder = tf.placeholder(labels.dtype, labels.shape)
dataset = tf.data.Dataset.from_tensor_slices((features_placeholder, labels_placeholder)).shuffle(buffer_value,reshuffle_each_iteration=True).repeat().batch(batch_num)
iterator = dataset.make_initializable_iterator()
next_element = iterator.get_next()
#Initialize an iterator over the training dataset.
sess.run(iterator.initializer, feed_dict={features_placeholder: X, labels_placeholder: Y})
# loop on epochs
for _ in range(5):
# loop over all the batch
for _ in range(1000):
s = time.time()
sess.run(next_element)
请注意,由于重复已打开,您需要计算一个需要在每个时段中循环一次数据并将其设置在内部循环中的确切迭代次数。