每次调用returns一批数据的函数

A function that returns a batch of data every time it's called

我正在尝试创建一个函数,每次调用它时 returns 一批数据(列表)。

它应该能够重复任意数量的训练步骤,并在遍历整个数据集(每个时期之后)后从头开始重新开始。

def generate_batch(X, batch_size):
    for i in range(0, len(X), batch_size):
        batch = X[i:i+batch_size]
        yield batch

X = [
[1, 2],
[4, 0],
[5, 1], 
[9, 99],
[9, 1],
[1, 1]]

for step in range(num_training_steps):
    x_batch = generate_batch(X, batch_size=2)
    print(list(x_batch))

当我打印函数的输出时,我发现它获取的是整个数据 (X) 而不是一批数据:

[[[1, 2], [4, 0]], [[5, 1], [9, 99]], [[9, 1], [1, 1]]]
[[[1, 2], [4, 0]], [[5, 1], [9, 99]], [[9, 1], [1, 1]]]
[[[1, 2], [4, 0]], [[5, 1], [9, 99]], [[9, 1], [1, 1]]]

问题是什么?这是使用 yield 的正确方法吗?

首先,如果你想在数据结束后从头开始,你需要将生成器函数体包裹在一个无限循环中,像这样:

def generate_batch(X, batch_size):
    while 1:
        for i in range(0, len(X), batch_size):
            batch = X[i:i+batch_size]
            yield batch

然后,当你这样做时:

x_batch = generate_batch(X, batch_size=2)

现在x_batch是一个发电机。您将需要对其进行迭代或对其调用 next() 以一次获取一批数据。如果你只是做 list(x_batch) 它会迭代并将所有批次收集到一个列表中。这不是你想要的。

你想要的是:

gen = generate_batch(X, batch_size=2)

for step in range(num_training_steps):
    x_batch = next(gen)
    print(x_batch)

或者,如果您需要可调用函数:

gen = generate_batch(X, batch_size=2)
gen = gen.__next__

for step in range(num_training_steps):
    x_batch = gen()
    print(x_batch)

此外,您可能想为该函数指定一个不同的名称,例如create_batch_generator().

好吧,你可以使用 itertools.cycle。这将像 tf.data.RepeatDataset 那样继续重复列表

您的源代码中有一点调整

from itertools import cycle

def generate_batch(X, batch_size):
    dataset = cycle(X)
    
    while True:
        batch = list(zip(range(batch_size), dataset))
        yield list(map(lambda x: x[1], batch))

就是这样。现在您可以将其插入您的代码

X = [
[1, 2],
[4, 0],
[5, 1], 
[9, 99],
[9, 1],
[1, 1]]


for step in range(20):
    for batch in generate_batch(X, 2):
        print(batch)

会输出如下

[[1, 2], [4, 0]]
[[9, 99], [9, 1]]
[[1, 2], [4, 0]]
[[9, 99], [9, 1]]
[[1, 2], [4, 0]]
[[9, 99], [9, 1]]
... and so on