Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用于训练和推理的tf.data.Dataset可反馈迭代器_Python_Tensorflow_Tensorflow Datasets - Fatal编程技术网

Python 用于训练和推理的tf.data.Dataset可反馈迭代器

Python 用于训练和推理的tf.data.Dataset可反馈迭代器,python,tensorflow,tensorflow-datasets,Python,Tensorflow,Tensorflow Datasets,我有一个TensorFlow模型,它使用tf.data.Dataset feedable迭代器在训练和验证之间切换。两个数据集共享相同的结构,即它们有一个特征矩阵和相应的标签向量。为了使用相同的模型和迭代器进行推理(无标签向量仅featurex矩阵),理想情况下,我需要提供零标签向量。是否有一种更高效、更优雅的方法来使用dataset API进行培训(验证)和推理 代码: training_dataset = tf.data.Dataset.from_tensor_slices((X_train

我有一个TensorFlow模型,它使用tf.data.Dataset feedable迭代器在训练和验证之间切换。两个数据集共享相同的结构,即它们有一个特征矩阵和相应的标签向量。为了使用相同的模型和迭代器进行推理(无标签向量仅featurex矩阵),理想情况下,我需要提供零标签向量。是否有一种更高效、更优雅的方法来使用dataset 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())
并使用
句柄
选择要使用的数据集,例如:

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()
如果我添加这个迭代器,它将抛出和异常,因为“组件的数量不匹配:预期为2个类型,但得到1个。” 有什么建议吗

这篇文章与这个问题有关,但是tf.data.Dataset没有解压方法


解决此问题的最佳做法是什么

如果您的图形代码,我假设您正在尝试从数据集中提取标签
y
的值,对吗?在推理时,这可能被烘焙到tensorflow依赖关系图中

你有几个选择。最简单的解决方案可能是从代码中重新创建图形(运行
build\u 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()

谢谢你的回答,但是问题不是我在图中使用了
y
。如果使用feed_dict,则使用相同的图形,它工作正常(仅将X作为输入传递)。当我尝试使用迭代器时,会出现这个错误,它期望底层数据集有两个组件
X
y
。所以我想知道,是否可以在生产中使用迭代器和数据集进行训练和推理,而推理数据集只有
X
?在图形运行时,如果该组件未使用,它不应该尝试从迭代器中提取第二个组件。至少我希望是这样。也许您正在重建图形并试图从迭代器中提取2个值,在这种情况下,一个简单的基于python的
if
语句应该可以解决这个问题。另一种解决方案可能是显式命名dataset元素。这应该是相当简单的事情,只是某个细节。问题是否发生在图形运行时(在
sess.run
)或构建图形时(例如在python land中)?它发生在图形运行时。您能否提供第二种解决方案的示例,即明确命名数据集元素?这是一个与命名数据集中元素相关的问题:如果是图形出错,您也可以尝试实现
tf.cond
,尽管我觉得有一个更干净的解决方案: