Skip to main content
 首页 » 编程设计

python之改变批量大小的 Tensorflow 数据集计算训练期间的测试损失

2024年09月07日28yyy_WW

我正在尝试运行一个训练循环,我会定期确定当前的平均损失并将其打印到控制台。为了确定损失,我想使用不同的批量大小。所以它是这样的:

dataset = create_dataset().shuffle(1000).repeat().batch(minibatch_size) 
iterator = dataset.make_one_shot_iterator() # using this iterator in the graph 
 
while ...: 
 session.run(...) # perform training 
 
 if epoch % 10 = 0: 
  test_avg_loss = session.run(avg_loss) # want a different number of items here 

我希望训练期间的小批量大小为 10,但我想使用 100 个数据点进行测试以获得对平均损失的更好估计。如何让数据集在这里返回不同数量的项目?我尝试将 placeholder 传递给 batch 但它似乎不受支持。错误是:

'ValueError : Cannot capture a placeholder (name:batchSize, type:Placeholder) by value.'

如果这看起来是更好的解决方案,我愿意完全使用不同的代码结构。我知道出于性能原因不使用 feedDict 传递数据很重要,因此使用 dataset 似乎是可行的方法。我不是在寻求某种黑客攻击,但我想知道执行此操作的正确方法是什么。

请您参考如下方法:

一个好的解决方案是使用可重新初始化的迭代器,它可以让您在两个(或多个)Dataset 之间切换,通常一个用于训练,一个用于验证。

The example in the documentation实际上非常整洁:

# Define training and validation datasets with the same structure. 
training_dataset = tf.data.Dataset.range(100).map( 
    lambda x: x + tf.random_uniform([], -10, 10, tf.int64)) 
validation_dataset = tf.data.Dataset.range(50) 
 
# A reinitializable iterator is defined by its structure. We could use the 
# `output_types` and `output_shapes` properties of either `training_dataset` 
# or `validation_dataset` here, because they are compatible. 
iterator = tf.data.Iterator.from_structure(training_dataset.output_types, 
                                           training_dataset.output_shapes) 
next_element = iterator.get_next() 
 
training_init_op = iterator.make_initializer(training_dataset) 
validation_init_op = iterator.make_initializer(validation_dataset) 
 
# Run 20 epochs in which the training dataset is traversed, followed by the 
# validation dataset. 
for _ in range(20): 
  # Initialize an iterator over the training dataset. 
  sess.run(training_init_op) 
  for _ in range(100): 
    sess.run(next_element) 
 
  # Initialize an iterator over the validation dataset. 
  sess.run(validation_init_op) 
  for _ in range(50): 
    sess.run(next_element) 

只要确保您创建的迭代器的批量大小未知即可。