Generator Keras拟合_发生器投掷值错误

Generator Keras拟合_发生器投掷值错误,generator,keras,Generator,Keras,因此,我试图创建一个生成器来迭代数据集,以便使用Keras的fit_生成器进行培训。以下是生成器的定义、模型以及对fit_generator的调用: import numpy as np from queue import Queue, deque from keras.models import Sequential from keras.layers import Dense num_features = 40 len_data = 100 data = np.random.rand(le

因此,我试图创建一个生成器来迭代数据集,以便使用Keras的fit_生成器进行培训。以下是生成器的定义、模型以及对fit_generator的调用:

import numpy as np
from queue import Queue, deque
from keras.models import Sequential
from keras.layers import Dense

num_features = 40
len_data = 100
data = np.random.rand(len_data, num_features)

def train_generator(train_idxs):
    while True:
        i = train_idxs.get(block=False)
        training_example = data[i,:]
        training_example.shape = (1, len(training_example))

        yield (training_example, training_example)


layer0_size = num_features
layer1_size = layer0_size / 2
layer2_size = layer1_size / 2

layers = []
layers.append(
    Dense(input_dim=layer0_size, output_dim=layer1_size, activation='relu'))
layers.append(
    Dense(input_dim=layer1_size, output_dim=layer2_size, activation='relu'))
layers.append(
    Dense(input_dim=layer2_size, output_dim=layer1_size, activation='relu'))
layers.append(
    Dense(input_dim=layer1_size, output_dim=layer0_size, activation='sigmoid'))

model = Sequential()
for layer in layers:
    model.add(layer)

model.compile(optimizer='adam', loss='binary_crossentropy')

train_idxs = Queue()
train_idxs.queue = deque(range(len_data))
train_gen = train_generator(train_idxs)
max_q_size = 2
model.fit_generator(train_gen, samples_per_epoch=len(data), max_q_size=max_q_size, nb_epoch=1)
Keras随后将成功训练98/100个训练示例,并抛出此错误

 98/100 [============================>.] - ETA: 0s - loss: 0.6930Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 429, in data_generator_task
    generator_output = next(self._generator)
  File "scrap.py", line 12, in train_generator
    i = train_idxs.get(block=False)
  File "/usr/lib/python3.5/queue.py", line 161, in get
    raise Empty
queue.Empty

Traceback (most recent call last):
  File "scrap.py", line 43, in <module>
    model.fit_generator(train_gen, samples_per_epoch=len(data), max_q_size=max_q_size, nb_epoch=1)
  File "/usr/local/lib/python3.5/dist-packages/keras/models.py", line 935, in fit_generator
    initial_epoch=initial_epoch)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 1528, in fit_generator
    str(generator_output))
ValueError: output of generator should be a tuple (x, y, sample_weight) or (x, y). Found: None
98/100[=========================>]-预计到达时间:0s-丢失:0.6930线程中的异常-1:
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python3.5/threading.py”,第914行,在内部引导中
self.run()
文件“/usr/lib/python3.5/threading.py”,第862行,正在运行
自我目标(*自我参数,**自我参数)
文件“/usr/local/lib/python3.5/dist-packages/keras/engine/training.py”,第429行,在数据生成器任务中
发电机输出=下一个(自发电机)
第12行“scrap.py”文件在列_生成器中
i=列车idxs.get(block=False)
get中的文件“/usr/lib/python3.5/queue.py”,第161行
空举
排队,空的
回溯(最近一次呼叫最后一次):
文件“scrap.py”,第43行,在
模型拟合发生器(序列生成,每个历元的样本数=长度(数据),最大历元大小=最大历元大小,nb历元=1)
文件“/usr/local/lib/python3.5/dist-packages/keras/models.py”,第935行,在fit_生成器中
初始_历元=初始_历元)
文件“/usr/local/lib/python3.5/dist-packages/keras/engine/training.py”,第1528行,在fit_生成器中
str(发电机输出)
ValueError:生成器的输出应该是元组(x,y,sample_weight)或(x,y)。发现:无

似乎现在发生的事情是,它弹出了所有的training_IDX,并且它仍在尝试获取更多,直到Keras耗尽其内部队列中的训练示例。有没有办法让它停止尝试从生成器获取更多的培训示例?

为什么要以如此繁琐的方式使用此生成器?这样的用法背后有什么原因吗?基本上-不可能阻止生成器获取下一个示例并将其放入队列。但也许有一种不同的方法来解决你的问题。@MarcinMożejko我不确定你认为哪一部分很麻烦。这是我实际用例的一个简化示例。实际上,数据不是一个numpy数组。它是一个对象,用于连接到一个文件,根据需要从中提取数据。我使用队列以便将数据收集分散到多个工作线程。我不认为你不能阻止fit_generator获得新的示例是真的。它应该在每个历元检索到num_samples_后停止。您是否会以不同的方式编写此代码?如果您阅读
fit_generator
文档,其中提到发电机应该无限期地生成数据。@MarcinMożejko我明白了!谢谢。我可以推荐使用Sequence类-它允许您创建一个生成器“类”,而不必产生不确定的结果。为什么您会以如此麻烦的方式使用此生成器?这样的用法背后有什么原因吗?基本上-不可能阻止生成器获取下一个示例并将其放入队列。但也许有一种不同的方法来解决你的问题。@MarcinMożejko我不确定你认为哪一部分很麻烦。这是我实际用例的一个简化示例。实际上,数据不是一个numpy数组。它是一个对象,用于连接到一个文件,根据需要从中提取数据。我使用队列以便将数据收集分散到多个工作线程。我不认为你不能阻止fit_generator获得新的示例是真的。它应该在每个历元检索到num_samples_后停止。您是否会以不同的方式编写此代码?如果您阅读
fit_generator
文档,其中提到发电机应该无限期地生成数据。@MarcinMożejko我明白了!谢谢。我可以推荐使用Sequence类——它允许您创建一个生成器“类”,而不必无限期地产生结果