使用生成器函数和steps_per_epoch的Tensorflow Keras model.fit

问题描述 投票:0回答:1

我有这个型号。适合电话:

transformer.fit(
   x=data_generation.generate_dataset(batch_size, dontchange, train_indices, filenames),
   epochs=epochs,
   steps_per_epoch=len(train_indices),
   validation_data=data_generation.generate_dataset(batch_size, dontchange, val_indices, filenames),
   validation_steps=len(val_indices)
)

然后这是我的generate_dataset函数的一部分:

def generate_dataset(batch_size_in, dontChange, index_list_in, filenames):
    epoch = 0
    while True:
        epoch = epoch + 1
        raw_dataset = tf.data.TFRecordDataset(filenames)
        batch_size = batch_size_in
        index_list = []
        index_list = index_list_in
        cx = 1
        for index in index_list:
            tf.print("Epoch: {}, Batch: {}, Batches total: {}".format(epoch, cx, len(index_list_in)), summarize=32 *
            10 * 250, output_stream="file://logtest.txt")
            cx = cx + 1
            how_much_to_take = batch_size
            batch_of_records = raw_dataset.skip(index).take(how_much_to_take)
            max_number_of_tv_in_batch = 0
            batch = []

    [...]

            yield (tf.stack(input_batch), tf.stack(attention_mask_batch), tf.stack(padding_mask_batch)), tf.stack(output_batch)


因此,对于索引列表中的每个索引,它都会生成一个批次,因此,steps_per_epoch 和validation_steps 等于通过val 生成器和训练生成器中相应的index_list_in 进行一次循环生成的批次数。所以一切都应该顺利进行。

如您所见,我使用 tf.print 将进度打印到日志文件中,我注意到一些我无法真正解释的事情。

Epoch: 1, Batch: 1, Batches total: 607
Epoch: 1, Batch: 2, Batches total: 607
Epoch: 1, Batch: 3, Batches total: 607
Epoch: 1, Batch: 4, Batches total: 607
Epoch: 1, Batch: 5, Batches total: 607
Epoch: 1, Batch: 6, Batches total: 607
Epoch: 1, Batch: 7, Batches total: 607 
[...]
Epoch: 1, Batch: 605, Batches total: 607
Epoch: 1, Batch: 606, Batches total: 607
Epoch: 1, Batch: 607, Batches total: 607
Epoch: 2, Batch: 1, Batches total: 607
Epoch: 1, Batch: 1, Batches total: 67
Epoch: 1, Batch: 2, Batches total: 67
Epoch: 1, Batch: 3, Batches total: 67
[...]
Epoch: 1, Batch: 66, Batches total: 67
Epoch: 1, Batch: 67, Batches total: 67
Epoch: 2, Batch: 1, Batches total: 67
Epoch: 2, Batch: 2, Batches total: 607
Epoch: 2, Batch: 3, Batches total: 607

所以它基本上按应有的方式加载了 607 个批次,但随后它加载了额外的批次,正如您可以通过以下输出看出的:

Epoch: 2, Batch: 1, Batches total: 607

就在进入 val 批次的生成器之前。 然后对于 Val 生成器,它是一样的,它工作得很好,它产生了 67 个批次,因为它应该,但然后它进入下一个循环,出于某种原因,我看到了这个:

Epoch: 2, Batch: 1, Batches total: 67

然后从这里开始 train_generator 中的第二个纪元:

Epoch: 2, Batch: 2, Batches total: 607

而不是:

Epoch: 2, Batch: 1, Batches total: 607

理应如此。

然后 Epoch 3 同样的事情:

Epoch: 3, Batch: 2, Batches total: 607

而不是:

Epoch: 3, Batch: 1, Batches total: 607

但是它为什么要这样做呢?正如我所说,steps_per_epoch 与通过index_list_in 循环生成的批次完全匹配。这是显而易见的,因为我使用 len(train_indices)/len(val_indices) 来确定批次数。但似乎每个时期还需要一批。为什么?

我想要的是,它每个时期仅加载全部 607 个批次,并且每个时期都应该从相同的批次开始。我必须改变什么?这是 Keras 的错误还是我做错了什么?

python tensorflow keras generator
1个回答
0
投票

其实我想已经明白了。

我需要在第一个纪元的训练生成器开始时添加第一批两次。 (所有其他批次仅steps_per_epoch批次)。

我需要在每个时期的 val 生成器的开头添加第一批两次。

因为对于这些批次,实际上没有计算准确性和损失(模型不会在这些批次上进行训练)。我认为模型只需要这些批次作为上下文。

每个纪元都需要 val_generator 中的上下文批处理,因为它实际上期望一个完整的数据集重复每个纪元,而对于 train_dataset,它希望在纪元步骤中遍历 data_set,因此它只需要上下文一次。

我在文档中没有找到任何关于此的内容,所以它要么是一个错误,要么很难找到。

© www.soinside.com 2019 - 2024. All rights reserved.