The image data generator image.py fails when I tried to train a single input and multiple output model with data augmentation by saying 'the shape of X and y must be the same.
But, for multiple output model, I supply a list of ndarrays and since the input is a single input, I supplied just X as is ndarray. I locally fixed it by checking to see if y is a list and bypass the exception and it works just fine.
I have met the same problem before. And I solved it by modifying some source code.
In
Below code is the modification to solve the problem of ImageDataGenerator for multiple output.
Problematic code in NumpyArrayIterator class
batch_y = self.y[index_array]
This code is not appropriate for multiple output indexing.
I modified the class like the below. This is a temporal solution. I hope this solution works fine with you. And I think the bug: ImageDataGenerator for multiple output and multiple output should be fixed in keras source officially.
`
class NumpyArrayIterator(Iterator):
def __init__(self, X, y, image_data_generator,
batch_size=32, shuffle=False, seed=None,
dim_ordering='default',
save_to_dir=None, save_prefix='', save_format='jpeg'):
if y is not None and len(X) != len(y):
raise Exception('X (images tensor) and y (labels) '
'should have the same length. '
'Found: X.shape = %s, y.shape = %s' % (np.asarray(X).shape, np.asarray(y).shape))
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.X = X
self.y = y
self.image_data_generator = image_data_generator
self.dim_ordering = dim_ordering
self.save_to_dir = save_to_dir
self.save_prefix = save_prefix
self.save_format = save_format
super(NumpyArrayIterator, self).__init__(X.shape[0], batch_size, shuffle, seed)
def next(self):
# for python 2.x.
# Keeps under lock only the mechanism which advances
# the indexing of each batch
# see http://anandology.com/blog/using-iterators-and-generators/
with self.lock:
index_array, current_index, current_batch_size = next(self.index_generator)
# The transformation of images is not under thread lock so it can be done in parallel
batch_x = np.zeros(tuple([current_batch_size] + list(self.X.shape)[1:]))
for i, j in enumerate(index_array):
x = self.X[j]
x = self.image_data_generator.random_transform(x.astype('float32'))
x = self.image_data_generator.standardize(x)
batch_x[i] = x
if self.save_to_dir:
for i in range(current_batch_size):
img = array_to_img(batch_x[i], self.dim_ordering, scale=True)
fname = '{prefix}_{index}_{hash}.{format}'.format(prefix=self.save_prefix,
index=current_index + i,
hash=np.random.randint(1e4),
format=self.save_format)
img.save(os.path.join(self.save_to_dir, fname))
if self.y is None:
return batch_x
'''
batch_y = self.y[index_array]
'''
batch_y = {}
for i in range(len(self.y)):
name = list(self.y.keys())[i]
batch_y[name] = self.y[name][index_array]
return batch_x, batch_y
`
This maybe closed due to stale state, but I believe the bug is still there.
I am still running into this problem in April 2019.
I am stuck at the same problem. I opened a issue here: https://github.com/keras-team/keras/issues/12639
Most helpful comment
This maybe closed due to stale state, but I believe the bug is still there.