相关疑难解决方法(0)

TensorFlow:如何在培训期间多次评估验证数据队列?

TL;博士

如何在每次K次训练迭代后评估验证集,使用单独的队列进行训练和验证数据,而不需要tf.Sessions在多个进程中分开?鉴于我的特殊问题,似乎没有一种干净的方法来实现这一点,而我目前的解决方法(我认为可行)会给我一些未定义的行为.救命!

整个故事

我想在每次K训练迭代中评估验证集,我无法弄清楚如何在TensorFlow中正确实现这一点.这应该是最常见的操作之一,但感觉TensorFlow的API /架构在这里对我有用,或者至少让事情变得不必要.

我的假设是:

  • [A1]此处描述的培训/验证多进程模型https://www.tensorflow.org/how_tos/reading_data/#multiple_input_pipelines不适用于我的问题,因为我必须假设没有足够的GPU内存可用加载变量两次.
  • [A2]我想在每次K训练迭代中评估验证集.
  • [A3]训练和验证数据都不能简单地从磁盘读取,而是在运行中生成.这使得不可能预先可靠地预先计算验证集的大小.
  • [A4]验证集太大,无法预先计算并存储到磁盘上.
  • [A5]有效验证集大小不一定是批量大小的倍数.

训练输入管道设置如下:

  • A 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_producerNone.

    在这种情况下,验证集会无休止地循环,但我需要提前知道验证集的大小,以明确限制每次运行验证集时要评估的批次数.此外,如果验证集大小不能被批量大小整除,我将在最后一批中总是拉一点.由于这会每次都改变验证数据的评估顺序,因此这是不可接受的.

  • [B2]将num_epochs验证的参数设置tf.train.slice_input_producer1,并另外将函数的allow_smaller_final_batch参数设置tf.train.batchTrue.

    在这种情况下,验证集只循环一次,之后相应的队列永远关闭.默认情况下,这将使评估验证集不可能两次或多次.由于我不知道在TensorFlow中重新打开队列的好方法,我需要解决这个限制.

由于选项[B1]的更大限制,我选择解决选项[B2]的问题.概述我当前方法的(伪)代码如下:

训练循环应该是相当规范的.每次K次迭代,都会调用一个评估验证集的函数.请注意,我只启动名称以"train_"开头的队列; 这些是为收集生成的训练数据而设置的队列.为了做到这一点,我创建了两个辅助函数,get_queues_by_namestart_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)

python machine-learning tensorflow

18
推荐指数
1
解决办法
4303
查看次数

tf.data.Dataset 迭代器返回 Tensor("IteratorGetNext:1", shape=(None, 16), dtype=int32) 但无法获取张量的值

我正在尝试编写一个自定义模型,其中我正在编写一个自定义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()属性的张量

这是哪里出错了??

keras tensorflow tensorflow-datasets tf.keras tensorflow2.0

8
推荐指数
1
解决办法
1848
查看次数

使用比Ram更多数据的Tensorflow数据集和估算器

我最近改变了我的建模框架以使用自定义Tensorflow EstimatorsDatasets,并且对这个工作流程非常满意.

但是,我刚刚注意到我的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 tensorflow-datasets tensorflow-estimator

6
推荐指数
1
解决办法
759
查看次数

Tensorflow Dataset.from_generator因pyfunc异常而失败

我正在尝试使用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)

python yield generator tensorflow tensorflow-datasets

4
推荐指数
1
解决办法
3223
查看次数