Python Tensorflow-正确(本机?)处理多个时代的数据批处理重叠(小批?)

Python Tensorflow-正确(本机?)处理多个时代的数据批处理重叠(小批?),python,tensorflow,Python,Tensorflow,EDIT3:您不能以本机方式执行此操作,我标记了这样说的答案。然而,我在下面的另一个答案中为那些好奇的人发布了一个示例解决方案 EDIT2:下面是带有问题复制的简单代码 编辑:这不是一个关于如何在多个时间段内排队/批处理的问题,这是重复/建议的帖子所解释的,我要问的是如何使非完美批处理大小正常工作。那篇文章只是提到“allow\u minger\u final\u batch=True”参数应该解释这个场景,但似乎没有(如下面我的代码所证明的) 在我的TF神经网络中,我使用TF.train.sl

EDIT3:您不能以本机方式执行此操作,我标记了这样说的答案。然而,我在下面的另一个答案中为那些好奇的人发布了一个示例解决方案

EDIT2:下面是带有问题复制的简单代码

编辑:这不是一个关于如何在多个时间段内排队/批处理的问题,这是重复/建议的帖子所解释的,我要问的是如何使非完美批处理大小正常工作。那篇文章只是提到“
allow\u minger\u final\u batch=True
”参数应该解释这个场景,但似乎没有(如下面我的代码所证明的)

在我的TF神经网络中,我使用
TF.train.slice\u input\u producer
TF.train.batch
对各个时期的数据进行批处理,当批处理大小是样本数的完美倍数时,这种方法可以完美地工作

不幸的是,如果不是,一个历元的最后一批将进入下一个历元(即,没有真正的“历元”划分),这最终意味着每个历元都是不同的。例如:

2个时代*12个样本=24个总值,批次大小=5

什么是正确的:

第1纪元:[5项],[5项],[2项]

第二纪元:[5项],[5项],[2项]

它实际上在做什么:

第1纪元:[5项],[5项],[5项]

第二纪元:[5项],[4项],[0项:超出范围]

生成上述示例的代码(与我的NN实现非常类似):

我知道这可能只是
tf.train.slice\u input\u producer
如何工作的一个双产品,我可能可以通过各种方式手动实现/避免这一点,但是没有办法通过切片在本地区分一个时代的“结束”吗?

迭代计算是不正确的 这就是您的迭代计算应该是什么

iterations = int(np.ceil(1.0*len(Data)/batch_size*epochs))
当我更改代码中的那一行时,我得到以下输出

[ 2  5  6 10  3]
[ 9  4  7  8 11]
[ 1  0 10  6  2]
[3 8 9 0 5]
[ 1  4 11  7]

您进行的计算包含len(Data)/batch_size,该值作为整数数学计算,已被截断。通过将它乘以1.0,你可以强制它成为一个浮点数,你的数学也可以工作。

不幸的是,没有办法以一种自然的方式来区分每个时代的结束。这是因为一般用法不需要将训练过程分为不同的时期。例如

如果你想在每个时代结束时做点什么,你必须手动处理它。如果没有,您可以使用
coord.should_stop()
来处理它,而不是自己计算迭代次数并担心任何错误:

try:
    while not coord.should_stop():
        temp_batch = sess.run(x2)
        print('\n' + str(temp_batch))
except tf.errors.OutOfRangeError:
    print("Done training, epoch limit reached.")
finally:
    coord.request_stop()    # Ask the threads to stop.

coord.join(threads)    # Wait for threads to stop.

如果有人想知道如何根据我的简单示例(不是本机)执行此操作:


正如@Wanne be Coder所示,您只需要使用一个整数占位符来控制自己的批量大小。有关部分包括:

batch_size = tf.placeholder(tf.int32, [])
x2 = tf.train.batch(x1, batch_size=batch_size)
batch1 = sess.run(x2, feed_dict={batch_size: 5}) # 5 items in batch1
batch2 = sess.run(x2, feed_dict={batch_size: 5}) # 5 items in batch2
batch3 = sess.run(x2, feed_dict={batch_size: 2}) # 2 items in batch3

可能重复感谢frankyjuang的回复;这里的区别是,我的一般排队工作得很好(这更像那篇文章所问的),但我没有让重叠行为像那篇文章中所描述/暗示的那样工作。你能提供重现这一点的最低代码吗?我现在已经在原始文章中包含了代码,请看一看,在深入研究了一些tf代码之后,我得出了结论。请在我的答案中找到。Heya wontonimo,谢谢你的回复!你得到的输出仍然和我得到的一样,尽管你做了改变,这就是我试图指出的问题。例如,使用您生成的同一个“分布”,输出应该按照[2 5 6 10 3]、[9 4 7 8 11]、[1 0]| | | | | |[10 6 2 3 8]、[9 0 5 1 4]、[11 7]进行分组。希望有道理。啊,是的,我认为你的问题是越界错误。我建议的代码更改修复了这一问题,并在没有try/catch语句的情况下运行了正确的迭代次数;不幸的是,我想这最终会成为现实。很容易适应,但也很悲伤。感谢您对这一点进行调查,以及与
coord.About_stop()
合作的技巧,非常感谢。使用try/catch而不仅仅是修复数学不是一个好方法。我继续做了一个简单的示例,如果您感兴趣,它可以按预期工作,作为附加答案发布。@wontonimo try/catch方法实际上是中提到的官方示例。
import tensorflow as tf
import numpy as np

batch_size = 5
epochs = 2
Data = list(range(12))
iter_epoch = int(np.ceil(len(Data)/batch_size))
iterations = (iter_epoch)*epochs
mini_size = len(Data) % batch_size

def make_nparray(constant):
    return(np.array([np.int32(constant)]))

sess = tf.InteractiveSession()

batch_ph = tf.placeholder(dtype=np.int32,shape=(1,))
x1 = tf.train.slice_input_producer([Data], num_epochs=epochs)
x2 = tf.train.batch(x1, batch_size=batch_ph[0])

sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess,coord=coord)

for i in range(iterations):
    not_mini = (i+1) % iter_epoch != 0
    if not_mini:
        temp_batch = sess.run(x2,feed_dict={batch_ph:make_nparray(batch_size)})
    else:
        temp_batch = sess.run(x2,feed_dict={batch_ph:make_nparray(mini_size)})
    print('\n' + str(temp_batch))
coord.request_stop()
sess.close()
batch_size = tf.placeholder(tf.int32, [])
x2 = tf.train.batch(x1, batch_size=batch_size)
batch1 = sess.run(x2, feed_dict={batch_size: 5}) # 5 items in batch1
batch2 = sess.run(x2, feed_dict={batch_size: 5}) # 5 items in batch2
batch3 = sess.run(x2, feed_dict={batch_size: 2}) # 2 items in batch3