У меня точно такая же проблема, как и в этом посте: я не могу использовать генератор в обучающем входе model.fit в keras, поэтому я должен развернуть его. Предлагаемое решение:

from platform import python_version_tuple

if python_version_tuple()[0] == '3':
    xrange = range
    izip = zip
    imap = map
else:
    from itertools import izip, imap

import numpy as np

# ..
# other code as in question
# ..

x, y = izip(*(validation_seq[i] for i in xrange(len(validation_seq))))
x_val, y_val = np.vstack(x), np.vstack(y)

это именно то, что я ищу. Проблема в том, что он работает для ImageDataGenerator() исходного вопроса, но не работает для моего генератора, который выглядит следующим образом:

def generator(data, L, D, i_min, i_max, shuffle=False, batch_size=16, step=1):
  if i_max is None:
     i_max = len(data) - D - 1
  i = i_min + L
  while 1:
     if shuffle:
        rows = np.random.randint(i_min + L, i_max, size=batch_size)
     else:
        if i + batch_size >= i_max:
           i = i_min + L
        rows = np.arange(i, min(i + batch_size, i_max))
        i += len(rows)
     samples = np.zeros((len(rows), L // step, data.shape[-1]))
     targets = np.zeros((len(rows),))
     for j, row in enumerate(rows):
        indices = range(rows[j] - L, rows[j], step)
        samples[j] = data[indices]
        targets[j] = data[rows[j] + D][3]  # where is Q in your data
     yield samples, targets


data = np.random.standard_normal([256,4])
generator = generator(data=data, L=8, D=1, i_min=0, i_max=255, shuffle=False, batch_size=16, step=1)

Когда я выполняю izip(*(generator[i] for i in xrange(len(generator)))), я получаю эту ошибку: object of type 'generator' has no len().

Я уже пытался заменить xrange(len(generator)) на len(list(generator)), enumerate(generator), и ни один из них не работает. Как я могу решить эту проблему? Спасибо.

PS: Я использую python 3.8 на osx 10.13.6.

UPDATE: на основании ответа @couka я попытался сделать генератор классов, но он все еще не работает.

class batch_gen:
  def __init__(self, data, L, D, min_index, max_index, shuffle, batch_size, step):
     self.data = data
     self.L = L
     self.D = D
     self.min_index = min_index
     self.max_index = max_index
     self.shuffle = shuffle
     self.batch_size = batch_size
     self.step = step
 
  def __iter__(self):
     if self.max_index is None:
        self.max_index = len(self.data) - self.D - 1
     i = self.min_index + self.L
     while 1:
        if self.shuffle:
           rows = np.random.randint(self.min_index + self.L, self.max_index, size=self.batch_size)
        else:
           if i + self.batch_size >= self.max_index:
              i = self.min_index + self.L
           rows = np.arange(i, min(i + self.batch_size, self.max_index))
           i += len(rows)
        samples = np.zeros((len(rows), self.L // self.step, self.data.shape[-1]))
        targets = np.zeros((len(rows),))
        for j, row in enumerate(rows):
           indices = range(rows[j] - self.L, rows[j], self.step)
           samples[j] = self.data[indices]
           targets[j] = self.data[rows[j] + self.D][3]  # where is Q in your data
        yield samples, targets
 
  def __len__(self):
     return int(math.floor(len(self.data) / float(self.batch_size)))

когда я использую:

gen_tr = batch_gen(data=data, L=L, D=D,
                  min_index=min(ind_tr), max_index=max(ind_tr),
                  shuffle=True, step=step, batch_size=batch_size)

и я получил эту ошибку: TypeError: 'batch_gen' object is not subscriptable.

Basilique

Ответов: 1

Ответы (1)

Во-первых, generator должен быть классом, а не методом.

Тогда, object of type 'generator' has no len() означает, что ваш класс generator не имеет метода __len__(self). Поэтому вам нужно его добавить. На самом деле этот метод должен возвращать количество партий в наборе данных.

Это может выглядеть примерно так:

def __len__(self):
    return int(math.floor(len(self.data) / float(self.batch_size)))

2022 WebDevInsider