gpt4 book ai didi

tensorflow - 如何使用 Tensorflow 的 tf.cond() 和两个不同的数据集迭代器而不迭代两者?

转载 作者:行者123 更新时间:2023-12-03 09:43:46 26 4
gpt4 key购买 nike

我想为 CNN 提供张量“图像”。当占位符 is_training 为 True 时,我希望这个张量包含来自训练集的图像(大小为 FIXED),否则我希望它包含来自测试集的图像(大小为 NOT FIXED)。

这是必需的,因为在训练中我从训练图像中随机抽取固定裁剪,而在测试中我想执行密集评估并将整个图像馈送到网络中(它是完全卷积的,所以它会接受它们)

当前的 NOT WORKING 方法是创建两个不同的迭代器,并尝试在 session.run(images,{is_training:True/False}) 中使用 tf.cond 选择训练/测试输入。

问题是两个迭代器都被评估了。训练和测试数据集的大小也不同,所以直到最后我都无法迭代它们。有没有办法使这项工作?或者以更聪明的方式重写它?

我已经看到了一些关于此的问题/答案,但他们总是使用 tf.assign 它接受一个 numpy 数组并将其分配给一个张量。在这种情况下,我不能使用 tf.assign 因为我已经有一个来自迭代器的张量。

我拥有的当前代码是这个。它只是检查张量“图像”的形状:

train_filenames, train_labels = list_images(args.train_dir)
val_filenames, val_labels = list_images(args.val_dir)

graph = tf.Graph()
with graph.as_default():

# Preprocessing (for both training and validation):
def _parse_function(filename, label):
image_string = tf.read_file(filename)
image_decoded = tf.image.decode_jpeg(image_string, channels=3)
image = tf.cast(image_decoded, tf.float32)

return image, label

# Preprocessing (for training)
def training_preprocess(image, label):

# Random flip and crop
image = tf.image.random_flip_left_right(image)
image = tf.random_crop(image, [args.crop,args.crop, 3])

return image, label

# Preprocessing (for validation)
def val_preprocess(image, label):

flipped_image = tf.image.flip_left_right(image)
batch = tf.stack([image,flipped_image],axis=0)

return batch, label

# Training dataset
train_filenames = tf.constant(train_filenames)
train_labels = tf.constant(train_labels)
train_dataset = tf.contrib.data.Dataset.from_tensor_slices((train_filenames, train_labels))
train_dataset = train_dataset.map(_parse_function,num_threads=args.num_workers, output_buffer_size=args.batch_size)
train_dataset = train_dataset.map(training_preprocess,num_threads=args.num_workers, output_buffer_size=args.batch_size)
train_dataset = train_dataset.shuffle(buffer_size=10000)
batched_train_dataset = train_dataset.batch(args.batch_size)

# Validation dataset
val_filenames = tf.constant(val_filenames)
val_labels = tf.constant(val_labels)
val_dataset = tf.contrib.data.Dataset.from_tensor_slices((val_filenames, val_labels))
val_dataset = val_dataset.map(_parse_function,num_threads=1, output_buffer_size=1)
val_dataset = val_dataset.map(val_preprocess,num_threads=1, output_buffer_size=1)

train_iterator = tf.contrib.data.Iterator.from_structure(batched_train_dataset.output_types,batched_train_dataset.output_shapes)
val_iterator = tf.contrib.data.Iterator.from_structure(val_dataset.output_types,val_dataset.output_shapes)

train_images, train_labels = train_iterator.get_next()
val_images, val_labels = val_iterator.get_next()

train_init_op = train_iterator.make_initializer(batched_train_dataset)
val_init_op = val_iterator.make_initializer(val_dataset)

# Indicates whether we are in training or in test mode
is_training = tf.placeholder(tf.bool)

def f_true():
with tf.control_dependencies([tf.identity(train_images)]):
return tf.identity(train_images)

def f_false():
return val_images

images = tf.cond(is_training,f_true,f_false)

num_images = images.shape

with tf.Session(graph=graph) as sess:

sess.run(train_init_op)
#sess.run(val_init_op)

img = sess.run(images,{is_training:True})
print(img.shape)

问题是,当我只想使用训练迭代器时,我注释了初始化 val_init_op 的行,但出现以下错误:
FailedPreconditionError (see above for traceback): GetNext() failed because the iterator has not been initialized. Ensure that you have run the initializer operation for this iterator before getting the next element.
[[Node: IteratorGetNext_1 = IteratorGetNext[output_shapes=[[2,?,?,3], []], output_types=[DT_FLOAT, DT_INT32], _device="/job:localhost/replica:0/task:0/cpu:0"](Iterator_1)]]

如果我不评论该行,一切都按预期工作,当 is_training 为真时,我得到训练图像,当 is_training 为假时,我得到验证图像。问题是两个迭代器都需要初始化,当我评估其中一个时,另一个也会增加。正如我所说,它们的大小不同,这会导致问题。

希望有办法解决!提前致谢

最佳答案

诀窍是调用iterator.get_next()里面f_true()f_false()职能:

def f_true():
train_images, _ = train_iterator.get_next()
return train_images

def f_false():
val_images, _ = val_iterator.get_next()
return val_images

images = tf.cond(is_training, f_true, f_false)

相同的建议适用于任何具有副作用的 TensorFlow 操作,例如分配给变量:如果您希望有条件地发生该副作用,则必须在传递给 tf.cond() 的适当分支函数内创建操作。 .

关于tensorflow - 如何使用 Tensorflow 的 tf.cond() 和两个不同的数据集迭代器而不迭代两者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46622490/

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