Reputation: 37
All welcome. Trying to understand how fit_generator works in keras.
I have dataset, in each file - 100 images and 100 labels.
I wrote this generator:
def GenerateData(self):
while True:
complete_x1 = np.zeros((500, 50, 50, 3))
complete_x2 = np.zeros((500, 50, 50, 3))
complete_y1 = np.zeros((500, 3))
complete_y2 = np.zeros((500, 2))
done = 0
while done < 500:
data = np.load("{}/data_resized_{}.npy".format(self._patch, self._LastID))
self.Log('\nLoad ALL data. ID: {} - Done: {}'.format(self._LastID, done))
for data_x1, data_x2, data_y1, data_y2 in data:
data_x1 = self.random_transform(data_x1)
data_x2 = self.random_transform(data_x2)
data_x1 = self.ImageProcessing(data_x1, 0)
data_x2 = self.ImageProcessing(data_x2, 1)
data_x1 = np.array(data_x1).astype('float32')
data_x1 /= 255
data_x2 = np.array(data_x2).astype('float32')
data_x2 /= 255
complete_x1[done] = data_x1
complete_x2[done] = data_x2
complete_y1[done] = data_y1
complete_y2[done] = data_y2
done += 1
self._LastID += 1
if self._LastID >= 1058:
self._LastID = 0
yield [np.array(complete_x1), np.array(complete_x2)], [np.array(complete_y1), np.array(complete_y2)]
I have 1058 files in total. It turns out 105800 images with labels.
Model training:
model.fit_generator(data.GenerateData(), samples_per_epoch=1058/500, nb_epoch=15, verbose=1, workers=1)
Everything seems to be good, but!
At the very beginning of training, GenerateData print the following:
Load ALL data. ID: 0 - Done: 0
Load ALL data. ID: 1 - Done: 100
Load ALL data. ID: 2 - Done: 200
Load ALL data. ID: 3 - Done: 300
Load ALL data. ID: 4 - Done: 400
Load ALL data. ID: 5 - Done: 0
Load ALL data. ID: 6 - Done: 100
Load ALL data. ID: 7 - Done: 200
Load ALL data. ID: 8 - Done: 300
Load ALL data. ID: 9 - Done: 400
Load ALL data. ID: 10 - Done: 0
And this happens before the file with ID 59. It turns out ... Does it skip everything that goes up to the 59 file? 5900 images?
It simply loads 500 images, after which it passes yield and starts again, with the ID of the file on which he finished, but the train does not work.
Here is what comes after the 59th file:
Load ALL data. ID: 59 - Done: 400 1/2 [=============>................] - ETA: 4s - loss: 2.8177 - dense_18_loss: 2.0145 - dense_21_loss: 0.8032 - dense_18_acc: 0.2140 - dense_21_acc: 0.5780 Load ALL data. ID: 60 - Done: 0
Load ALL data. ID: 61 - Done: 100
Load ALL data. ID: 62 - Done: 200
Load ALL data. ID: 63 - Done: 300
Load ALL data. ID: 64 - Done: 400 2/2 [===========================>..] - ETA: 0s - loss: 2.7260 - dense_18_loss: 1.7077 - dense_21_loss: 1.0183 - dense_18_acc: 0.2720 - dense_21_acc: 0.5890 Load ALL data. ID: 65 - Done: 0
Load ALL data. ID: 66 - Done: 100
Why is this happening?
Upvotes: 1
Views: 54
Reputation: 5412
You are getting this behavior because you set workers
to 1, and the data generating task and training task are running on separate threads. The training task runs on the main thread, while the data generating task runs on separate thread(s), where the number of threads depend on the workers
argument.
If the workers
argument had been 0, the data-generator would run on the main thread and the result would have been what you are expecting.
Upvotes: 1