如何在每次K次训练迭代后评估验证集,使用单独的队列进行训练和验证数据,而不需要tf.Sessions在多个进程中分开?鉴于我的特殊问题,似乎没有一种干净的方法来实现这一点,而我目前的解决方法(我认为可行)会给我一些未定义的行为.救命!
我想在每次K训练迭代中评估验证集,我无法弄清楚如何在TensorFlow中正确实现这一点.这应该是最常见的操作之一,但感觉TensorFlow的API /架构在这里对我有用,或者至少让事情变得不必要.
我的假设是:
训练输入管道设置如下:
tf.train.slice_input_producer()生成(混洗)文件名列表,每个文件名都引用原始输入数据.tf.train.shuffle_batch()在被送入网络之前排队等候.由于[A3],[A4],[A5],验证输入管道以几乎相同的方式设置,除了最终输入队列是通过生成tf.train.batch(),因为不希望进行混洗.由于上述假设,基于feed_dict的方法也是不可行的,并且看起来与使用更高级别的功能(例如,使用更高级别的功能)不相容tf.train.batch.
但是,使用两组不同的队列进行培训和验证的直接实现不起作用.据我了解,我有两个选择:
[B1]将num_epochs验证的参数设置tf.train.slice_input_producer为None.
在这种情况下,验证集会无休止地循环,但我需要提前知道验证集的大小,以明确限制每次运行验证集时要评估的批次数.此外,如果验证集大小不能被批量大小整除,我将在最后一批中总是拉一点.由于这会每次都改变验证数据的评估顺序,因此这是不可接受的.
[B2]将num_epochs验证的参数设置tf.train.slice_input_producer为1,并另外将函数的allow_smaller_final_batch参数设置tf.train.batch为True.
在这种情况下,验证集只循环一次,之后相应的队列永远关闭.默认情况下,这将使评估验证集不可能两次或多次.由于我不知道在TensorFlow中重新打开队列的好方法,我需要解决这个限制.
由于选项[B1]的更大限制,我选择解决选项[B2]的问题.概述我当前方法的(伪)代码如下:
训练循环应该是相当规范的.每次K次迭代,都会调用一个评估验证集的函数.请注意,我只启动名称以"train_"开头的队列; 这些是为收集生成的训练数据而设置的队列.为了做到这一点,我创建了两个辅助函数,get_queues_by_name和start_queue_runners.
def train_loop(train_ops, vali_ops, ...):
with tf.Session() as sess:
coord = tf.train.Coordinator()
sess.run([tf.initialize_all_variables(), tf.initialize_local_variables()])
load_latest_snapshot(sess, loader, snapshot_file)
# Launch the queue runners
queues …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个自定义模型,其中我正在编写一个自定义train_step函数
我正在从自定义数据生成器创建一个“tf.data.Dataset”,例如
tds = tf.data.Dataset.from_generator(tdg.__iter__,args=None,output_types = (tf.float32,tf.int32),output_shapes = (tf.TensorShape([16,64,64,3]),tf.TensorShape([16])))
tds = tds.batch(1)
Run Code Online (Sandbox Code Playgroud)
在自定义 DataGenerator 中,该__iter__方法定义为
def __iter__(self):
for item in (self[i] for i in range(len(self))):
yield item
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试检索train_step函数内的数据时,x,y = data我得到
Tensor("IteratorGetNext:0", shape=(None, 16, 64, 64, 3), dtype=float32)
和
Tensor("IteratorGetNext:1", shape=(None, 16), dtype=int32) 作为输出
如果我跑print(x[0])那么我得到
Tensor("strided_slice:0", shape=(16,), dtype=int32)
我没有得到具有numpy()属性的张量
这是哪里出错了??
我最近改变了我的建模框架以使用自定义Tensorflow Estimators和Datasets,并且对这个工作流程非常满意.
但是,我刚刚注意到我的dataset_input_fn如何从tfrecords加载数据的问题.我的输入函数是在Tensorflow文档中的示例之后建模的.当我有更多的例子而不是我可以适应RAM时,会出现问题.如果我有1e6个示例,并将我的shuffle buffer_size设置为1e5,则选择1e5示例的子集一次,随机,然后迭代.这意味着我的模型仅在我的整个数据集的10%上进行训练.设置此行为的代码完全来自Tensorflow文档示例代码:
dataset = dataset.map(parser)
dataset = dataset.shuffle(buffer_size=10000)
dataset = dataset.batch(32)
dataset = dataset.repeat(num_epochs)
iterator = dataset.make_one_shot_iterator()
Run Code Online (Sandbox Code Playgroud)
我的问题:当我训练时,是否有可能在最初的1e5之外用新的例子填充shuffle缓冲区?one_shot_iterator是否支持此类功能?我需要使用可初始化的迭代器吗?
谢谢!
我正在尝试使用tensorflow的每晚1.4,因为我需要Dataset.from_generator将一些可变长度数据集放在一起.这个简单的代码(来自这里的想法):
import tensorflow as tf
Dataset = tf.contrib.data.Dataset
it2 = Dataset.range(5).make_one_shot_iterator()
def _dataset_generator():
while True:
try:
try:
get_next = it2.get_next()
yield get_next
except tf.errors.OutOfRangeError:
continue
except tf.errors.OutOfRangeError:
return
# Dataset.from_generator need tensorflow > 1.3 !
das_dataset = Dataset.from_generator(_dataset_generator,
output_types=(tf.float32, tf.float32))
das_dataset_it = das_dataset.make_one_shot_iterator()
with tf.Session() as sess:
while True:
print(sess.run(it2.get_next()))
print(sess.run(das_dataset_it.get_next()))
Run Code Online (Sandbox Code Playgroud)
失败了,相当神秘:
C:\Dropbox\_\PyCharmVirtual\TF-NIGHTLY\Scripts\python.exe C:/Users/MrD/.PyCharm2017.2/config/scratches/scratch_55.py
0
2017-10-01 12:51:39.773135: W C:\tf_jenkins\home\workspace\tf-nightly-windows\M\windows\PY\35\tensorflow\core\framework\op_kernel.cc:1192] Invalid argument: 0-th value returned by pyfunc_0 is int32, but expects int64
[[Node: PyFunc = PyFunc[Tin=[], Tout=[DT_INT64], …Run Code Online (Sandbox Code Playgroud)