我有一个 TensorFlow 模型,该模型使用 tf.data.Dataset feedable 迭代器在训练和验证之间进行切换。两个数据集共享相同的结构,即它们具有特征矩阵和相应的标签矢量。为了使用相同的模型和迭代器进行推理(没有标签向量仅是Featurex矩阵),我需要理想地提供零标签向量。有没有更有效,更优雅的方法来使用数据集API进行训练(验证)和推理?
在代码中:
// ** EF6 **
public class IdeaConfiguration : EntityTypeConfiguration<Idea>
{
public IdeaConfiguration()
{
ToTable("Ideas");
HasKey(x => x.Id);
HasMany(x => x.Reactions)
.WithRequired()
.Map(x => x.MapKey("IdeaId")); // This tells EF to use an IdeaId field on Reaction.
}
}
// ** EF Core **
public class IdeaConfiguration : IEntityTypeConfiguration<Idea>
{
void IEntityTypeConfiguration<Idea>.Configure(EntityTypeBuilder<Idea> builder)
{
builder.ToTable("Ideas");
builder.HasKey(x => x.Id);
builder.HasMany(x => x.Reactions)
.WithOne()
.HasForeignKey("IdeaId"); // Creates a shadow property for the association.
}
}
功能和标签在模型内部用作输入占位符。 为了在数据集之间切换,我需要为每个数据集创建一个迭代器:
In [1]: import pandas as pd
In [2]: s = pd.Series(range(10))
In [3]: s
Out[3]:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
dtype: int64
然后创建手柄
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())
如果添加此迭代器,它将抛出异常,因为“组件数不匹配:预期2种类型,但得到1种”。 有什么建议吗?
此帖子How to use tf.Dataset design in both training and inferring?与该问题有关,但是tf.data.Dataset没有解压缩方法。
此问题的最佳做法是什么?
答案 0 :(得分:0)
如果您的图形代码是我想您正在尝试从数据集中提取标签y
的值,对吗?在推论时间,它可能被烘焙到张量流依赖图中。
您在这里有几种选择。可能最简单的解决方案是从代码中重新创建图形(运行您的build_graph()
函数,然后使用类似saver.restore(sess, "/tmp/model.ckpt")
的方式加载权重)。如果以这种方式进行操作,则可以重新创建没有标签y
的图形。我假设y
上没有其他依赖项(有时tensorboard摘要还会添加您需要检查的依赖项)。您的问题现在应该已经解决。
但是,既然我已经编写了上面的注释(由于它仍然是有用的信息,我将其保留不变),我意识到您甚至不需要它。在推论时,您不应在任何地方使用标签(再次,仔细检查张量板摘要)。如果您不需要y
,则tensorflow不应运行任何使用y
的操作。这应包括不尝试从数据集中提取它们。仔细检查您是否不要求tensorflow在推断时在任何地方使用标签。
答案 1 :(得分:0)
我认为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()