EDIT3 :你原来不能这样做,我标记了这样说的答案。但是,我在下面的另一个答案中为那些好奇的人发布了一个示例解决方案。
EDIT2 :下面是问题复制的简单代码。
编辑:这不是关于如何排队/批量处理多个时代的问题,这是重复/建议的帖子解释的内容,我具体询问如何获取非完美的批量大小正常工作。那篇文章简单地提到了" allow_smaller_final_batch=True
"参数应考虑到这种情况,但似乎没有(在下面的代码中证明)。
在我的TF神经网络中,我使用tf.train.slice_input_producer
和tf.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 ;一个切片的时代?
答案 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