【发布时间】:2021-01-01 12:36:14
【问题描述】:
我的问题与post 中解决的问题完全相同:我不能在keras 的model.fit 的训练输入中使用生成器,所以我应该打开它。建议的解决方案:
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)
正是我正在寻找的。问题是它适用于初始question 的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:我在 osx 10.13.6 上使用 python 3.8。
更新: 根据@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。
【问题讨论】:
-
请将包含调用堆栈回溯的完整错误消息放入您的问题中。另外请更新您问题中的代码,使其成为minimal reproducible example - 任何人都应该能够将您的代码粘贴到文件中并且无需添加任何内容运行它以查看与您相同的问题。跨度>
-
错误正是它所说的。 batch_gen 不可下标。你没有在你的生成器类中实现
__getitem__,你没有理由应该这样做。您可以直接迭代项目而不是通过下标。izip(*(item for item in gen_tr))应该可以工作。