Tensorflow - 正确(本机?)处理数据批处理(小批量?)多个时期

时间:2017-05-31 16:18:57

标签: python tensorflow

EDIT3 :你原来不能这样做,我标记了这样说的答案。但是,我在下面的另一个答案中为那些好奇的人发布了一个示例解决方案。

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

编辑:这不是关于如何排队/批量处理多个时代的问题,这是重复/建议的帖子解释的内容,我具体询问如何获取非完美的批量大小正常工作。那篇文章简单地提到了" allow_smaller_final_batch=True"参数应考虑到这种情况,但似乎没有(在下面的代码中证明)。

在我的TF神经网络中,我使用tf.train.slice_input_producertf.train.batch在epochs上批量处理我的数据,当我的批量大小是我的样本数量的完美倍数时,它可以完美地运行。

不幸的是,如果不是,那么最后一批时代就会进入下一个时代(即没有真正的"时代"分裂),这最终意味着每一个时代时代不同。实施例:

2个时期* 12个样本= 24个总值,Batch_size = 5,

什么是正确的:

时代1:[5项],[5项],[2项]

大纪元2:[5项],[5项],[2项]

实际上做了什么:

时代1:[5项],[5项],[5项]

大纪元2:[5项],[4项],[0项目:超出范围]

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

import tensorflow as tf
import numpy as np

batch_size = 5
epochs = 2
Data = list(range(12))
iterations = int(np.ceil(len(Data)/batch_size)*epochs)
sess = tf.InteractiveSession()

x1 = tf.train.slice_input_producer([Data], num_epochs=epochs)
x2 = tf.train.batch(x1, batch_size=batch_size, allow_smaller_final_batch=True)

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):
   temp_batch = sess.run(x2)
   print('\n' + str(temp_batch))
sess.close()

我知道这可能只是tf.train.slice_input_producer如何运作的双重产品,我可以用各种方式手动实现/避免这种情况,但是没有办法在本地区分"结束&#34 ;一个切片的时代?

4 个答案:

答案 0 :(得分:1)

不幸的是,没有办法以原生方式区分每个时代的结束。这是因为一般用法不需要​​将训练过程分成时代。例如,fully_connected_preloaded.py

如果你想在每个时代结束时做一些事情,你必须手动处理它。如果没有,您可以使用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.

答案 1 :(得分:1)

如果有人想根据我的简单示例(非本地)知道如何做到这一点:

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()

答案 2 :(得分:0)

迭代计算不正确

这是你的迭代计算应该

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,可以强制它成为一个浮点,并且数学运算正常。

答案 3 :(得分:0)

@ 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