tf.data.Dataset 用于训练和推理的可馈送迭代器
tf.data.Dataset feedable iterator for training and inference
我有一个 TensorFlow 模型,它使用 tf.data.Dataset feedable 迭代器在训练和验证之间切换。两个数据集共享相同的结构,即它们具有特征矩阵和相应的标签向量。为了使用相同的模型和迭代器进行推理(没有标签向量只有 featurex 矩阵)我需要理想地提供一个零标签向量。是否有更高效和优雅的方式来使用数据集 API 进行训练(验证)和推理?
在代码中:
training_dataset = tf.data.Dataset.from_tensor_slices((X_train, y_train))
validation_dataset = tf.data.Dataset.from_tensor_slices((X_validation, y_validation))
handle = tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(handle, training_dataset.output_types, training_dataset.output_shapes)
features, labels = iterator.get_next()
特征和标签在模型中用作输入占位符。
为了在数据集之间切换,我需要为每个数据集创建一个迭代器:
training_iterator = training_dataset.make_initializable_iterator()
validation_iterator = validation_dataset.make_initializable_iterator()
然后创建句柄
training_handle = sess.run(training_iterator.string_handle())
validation_handle = sess.run(validation_iterator.string_handle())
并使用handle
到select使用哪个数据集,例如:
sess.run(next_element, feed_dict={handle: training_handle})
现在,如果我有没有标签的推理数据会怎样?
inference_dataset = tf.data.Dataset.from_tensor_slices(X_inference) # NO y values
inferece_iterator = inference_dataset.make_initializable_iterator()
如果我添加这个迭代器,它会抛出异常,因为 "Number of components does not match: expected 2 types but got 1."
有什么建议吗?
这个post How to use tf.Dataset design in both training and inferring?和这个问题有关,但是tf.data.Dataset没有解压方法。
这个问题的最佳做法是什么?
如果你的图表代码我假设你正在尝试从数据集中提取标签 y
的值,对吗?在推理时,它可能被烘焙到 tensorflow 依赖图中。
您在这里有几个选择。可能最简单的解决方案是从代码重新创建图表(运行 你的 build_graph()
函数,然后使用 saver.restore(sess, "/tmp/model.ckpt")
之类的东西加载权重)。如果你这样做,你可以重新创建没有标签 y
的图表。我假设 y
上没有其他依赖项(有时 tensorboard 摘要会添加您也需要检查的依赖项)。您的问题现在应该已经解决了。
但是,既然我已经写了上面的评论(我将保留原样,因为它仍然是有用的信息),我意识到您可能甚至不需要它。在推理时,你不应该在任何地方使用标签(再次,仔细检查张量板摘要)。如果你不需要 y
那么 tensorflow 不应该 运行 任何使用 y
的操作。这应该包括不要试图从数据集中提取它们。仔细检查您是否没有要求 tensorflow 在推理时在任何地方使用您的标签。
我认为 David Parks 提出的第一个解决方案看起来像这样,我认为比在代码中乱用 tf.cond 更好。
import tensorflow as tf
import numpy as np
def build_model(features, labels=None, train=False):
linear_model = tf.layers.Dense(units=1)
y_pred = linear_model(features)
if train:
loss = tf.losses.mean_squared_error(labels=labels, predictions=y_pred)
optimizer = tf.train.GradientDescentOptimizer(1e-4)
train = optimizer.minimize(loss)
return train, loss
else:
return y_pred
X_train = np.random.random(100).reshape(-1, 1)
y_train = np.random.random(100).reshape(-1, 1)
training_dataset = tf.data.Dataset.from_tensor_slices((X_train, y_train))
training_dataset = training_dataset.batch(10)
training_dataset = training_dataset.shuffle(20)
handle = tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(handle, training_dataset.output_types, training_dataset.output_shapes)
features, labels = iterator.get_next()
training_iterator = training_dataset.make_one_shot_iterator()
train, loss = build_model(features, labels, train=True)
saver = tf.train.Saver()
init = tf.global_variables_initializer()
sess = tf.Session()
training_handle = sess.run(training_iterator.string_handle())
sess.run(init)
for i in range(10):
_, loss_value = sess.run((train, loss), feed_dict={handle: training_handle})
print(loss_value)
saver.save(sess, "tmp/model.ckpt")
sess.close()
tf.reset_default_graph()
X_test = np.random.random(10).reshape(-1, 1)
inference_dataset = tf.data.Dataset.from_tensor_slices(X_test)
inference_dataset = inference_dataset.batch(5)
handle = tf.placeholder(tf.string, shape=[])
iterator_inference = tf.data.Iterator.from_string_handle(handle, inference_dataset.output_types, inference_dataset.output_shapes)
inference_iterator = inference_dataset.make_one_shot_iterator()
features_inference = iterator_inference.get_next()
y_pred = build_model(features_inference)
saver = tf.train.Saver()
sess = tf.Session()
inference_handle = sess.run(inference_iterator.string_handle())
saver.restore(sess, "tmp/model.ckpt") # Restore variables from disk.
print(sess.run(y_pred, feed_dict={handle: inference_handle}))
sess.close()
我有一个 TensorFlow 模型,它使用 tf.data.Dataset feedable 迭代器在训练和验证之间切换。两个数据集共享相同的结构,即它们具有特征矩阵和相应的标签向量。为了使用相同的模型和迭代器进行推理(没有标签向量只有 featurex 矩阵)我需要理想地提供一个零标签向量。是否有更高效和优雅的方式来使用数据集 API 进行训练(验证)和推理?
在代码中:
training_dataset = tf.data.Dataset.from_tensor_slices((X_train, y_train))
validation_dataset = tf.data.Dataset.from_tensor_slices((X_validation, y_validation))
handle = tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(handle, training_dataset.output_types, training_dataset.output_shapes)
features, labels = iterator.get_next()
特征和标签在模型中用作输入占位符。 为了在数据集之间切换,我需要为每个数据集创建一个迭代器:
training_iterator = training_dataset.make_initializable_iterator()
validation_iterator = validation_dataset.make_initializable_iterator()
然后创建句柄
training_handle = sess.run(training_iterator.string_handle())
validation_handle = sess.run(validation_iterator.string_handle())
并使用handle
到select使用哪个数据集,例如:
sess.run(next_element, feed_dict={handle: training_handle})
现在,如果我有没有标签的推理数据会怎样?
inference_dataset = tf.data.Dataset.from_tensor_slices(X_inference) # NO y values
inferece_iterator = inference_dataset.make_initializable_iterator()
如果我添加这个迭代器,它会抛出异常,因为 "Number of components does not match: expected 2 types but got 1." 有什么建议吗?
这个post How to use tf.Dataset design in both training and inferring?和这个问题有关,但是tf.data.Dataset没有解压方法。
这个问题的最佳做法是什么?
如果你的图表代码我假设你正在尝试从数据集中提取标签 y
的值,对吗?在推理时,它可能被烘焙到 tensorflow 依赖图中。
您在这里有几个选择。可能最简单的解决方案是从代码重新创建图表(运行 你的 build_graph()
函数,然后使用 saver.restore(sess, "/tmp/model.ckpt")
之类的东西加载权重)。如果你这样做,你可以重新创建没有标签 y
的图表。我假设 y
上没有其他依赖项(有时 tensorboard 摘要会添加您也需要检查的依赖项)。您的问题现在应该已经解决了。
但是,既然我已经写了上面的评论(我将保留原样,因为它仍然是有用的信息),我意识到您可能甚至不需要它。在推理时,你不应该在任何地方使用标签(再次,仔细检查张量板摘要)。如果你不需要 y
那么 tensorflow 不应该 运行 任何使用 y
的操作。这应该包括不要试图从数据集中提取它们。仔细检查您是否没有要求 tensorflow 在推理时在任何地方使用您的标签。
我认为 David Parks 提出的第一个解决方案看起来像这样,我认为比在代码中乱用 tf.cond 更好。
import tensorflow as tf
import numpy as np
def build_model(features, labels=None, train=False):
linear_model = tf.layers.Dense(units=1)
y_pred = linear_model(features)
if train:
loss = tf.losses.mean_squared_error(labels=labels, predictions=y_pred)
optimizer = tf.train.GradientDescentOptimizer(1e-4)
train = optimizer.minimize(loss)
return train, loss
else:
return y_pred
X_train = np.random.random(100).reshape(-1, 1)
y_train = np.random.random(100).reshape(-1, 1)
training_dataset = tf.data.Dataset.from_tensor_slices((X_train, y_train))
training_dataset = training_dataset.batch(10)
training_dataset = training_dataset.shuffle(20)
handle = tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(handle, training_dataset.output_types, training_dataset.output_shapes)
features, labels = iterator.get_next()
training_iterator = training_dataset.make_one_shot_iterator()
train, loss = build_model(features, labels, train=True)
saver = tf.train.Saver()
init = tf.global_variables_initializer()
sess = tf.Session()
training_handle = sess.run(training_iterator.string_handle())
sess.run(init)
for i in range(10):
_, loss_value = sess.run((train, loss), feed_dict={handle: training_handle})
print(loss_value)
saver.save(sess, "tmp/model.ckpt")
sess.close()
tf.reset_default_graph()
X_test = np.random.random(10).reshape(-1, 1)
inference_dataset = tf.data.Dataset.from_tensor_slices(X_test)
inference_dataset = inference_dataset.batch(5)
handle = tf.placeholder(tf.string, shape=[])
iterator_inference = tf.data.Iterator.from_string_handle(handle, inference_dataset.output_types, inference_dataset.output_shapes)
inference_iterator = inference_dataset.make_one_shot_iterator()
features_inference = iterator_inference.get_next()
y_pred = build_model(features_inference)
saver = tf.train.Saver()
sess = tf.Session()
inference_handle = sess.run(inference_iterator.string_handle())
saver.restore(sess, "tmp/model.ckpt") # Restore variables from disk.
print(sess.run(y_pred, feed_dict={handle: inference_handle}))
sess.close()