大規模なデータセットで動作するように書き換えた次のコードがあります。 Pythonジェネレータを使用して、バッチごとに生成されたデータにモデルを適合させています。
def subtract_mean_gen(x_source,y_source,avg_image,batch):
batch_list_x=[]
batch_list_y=[]
for line,y in Zip(x_source,y_source):
x=line.astype('float32')
x=x-avg_image
batch_list_x.append(x)
batch_list_y.append(y)
if len(batch_list_x) == batch:
yield (np.array(batch_list_x),np.array(batch_list_y))
batch_list_x=[]
batch_list_y=[]
model = resnet.ResnetBuilder.build_resnet_18((img_channels, img_rows, img_cols), nb_classes)
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
val = subtract_mean_gen(X_test,Y_test,avg_image_test,batch_size)
model.fit_generator(subtract_mean_gen(X_train,Y_train,avg_image_train,batch_size), steps_per_Epoch=X_train.shape[0]//batch_size,epochs=nb_Epoch,validation_data = val,
validation_steps = X_test.shape[0]//batch_size)
次のエラーが表示されます。
239/249 [===========================>..] - ETA: 60s - loss: 1.3318 - acc: 0.8330Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/local/lib/python2.7/dist-packages/keras/utils/data_utils.py", line 560, in data_generator_task
generator_output = next(self._generator)
StopIteration
240/249 [===========================>..] - ETA: 54s - loss: 1.3283 - acc: 0.8337Traceback (most recent call last):
File "cifa10-copy.py", line 125, in <module>
validation_steps = X_test.shape[0]//batch_size)
File "/usr/local/lib/python2.7/dist-packages/keras/legacy/interfaces.py", line 87, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1809, in fit_generator
generator_output = next(output_generator)
StopIteration
私は投稿された同様の質問 here を調べましたが、StopIterationが発生するエラーを解決できません。
ケラのジェネレーターは無限でなければなりません:
def subtract_mean_gen(x_source,y_source,avg_image,batch):
while True:
batch_list_x=[]
batch_list_y=[]
for line,y in Zip(x_source,y_source):
x=line.astype('float32')
x=x-avg_image
batch_list_x.append(x)
batch_list_y.append(y)
if len(batch_list_x) == batch:
yield (np.array(batch_list_x),np.array(batch_list_y))
batch_list_x=[]
batch_list_y=[]
エラーは、kerasが新しいバッチを取得しようとするために発生しますが、ジェネレーターはすでにその終わりに達しています。 (正しい数のステップを定義した場合でも、kerasには、最後のステップにいる場合でもジェネレーターからより多くのバッチを取得しようとするキューがあります。)
どうやら、デフォルトのキューサイズは10です(例外は、キューが終了後にバッチを取得しようとしているため、終了前に10バッチ表示されます)。
あなたが提供したリンクされた質問が示すように、Keras Generatorsは無期限に繰り返す必要があるので、必要なだけトレーニングに要素を出力できます。 this Githubの問題に関する詳細情報。
そのためには、ジェネレーターに次のような変更を加える必要があります。
def subtract_mean_gen(x_source,y_source,avg_image,batch):
batch_list_x=[]
batch_list_y=[]
while 1: #run forever, so you can generate elements indefinitely
for line,y in Zip(x_source,y_source):
x=line.astype('float32')
x=x-avg_image
batch_list_x.append(x)
batch_list_y.append(y)
if len(batch_list_x) == batch:
yield (np.array(batch_list_x),np.array(batch_list_y))
batch_list_x=[]
batch_list_y=[]