I am converting python code from keras namespace to tf.keras. It trains Resnet50. New Model.fit() method can't find adapter for my simple generator and validation_data does not even support generators anymore. So I am trying to convert it to Dataset using tensorflow.data.Dataset.from_generator method.
Images are grayscale and stored in raw bytes - one byte for one pixel. Generator has such rows
def __next__( self ):
return self.next()
def __call__( self ):
return self.next()
def next( self ):
#reading files
...
resultLabels = numpy.zeros( ( count, len( classes ) ), "float32" )
resultImages = numpy.zeros( ( count, patchSize, patchSize, 3 ), "float32" )
#filling result with images and labels
...
fileBytes = numpy.reshape( numpy.fromfile( self.ImageLabelsAndPaths[i][1], "uint8" ), (patchSize, patchSize), "F" ).astype( "float32" )
imageWithChannels = numpy.zeros( ( patchSize, patchSize, 3 ), "float32" )
# Because Resnet50 requires RGB images and we have grayscale
imageWithChannels[:,:,0] = fileBytes
imageWithChannels[:,:,1] = fileBytes
imageWithChannels[:,:,2] = fileBytes
resultImages[i - cursor] = imageWithChannels
return ( resultImages, resultLabels )
So resultImages is an array with length of batch_size=16, that contains arrays of image pixels. Numpy.shape is (16, 256, 256, 3) and resultLabels shape is (16, 3) - 3 classes for now.
Next I am converting it to Dataset
trainGenerator = FileIterator( "train" )
trainDataset = tf.data.Dataset.from_generator( trainGenerator, (tf.float32, tf.float32), (tf.TensorShape([batchSize, patchSize, patchSize, 3]), tf.TensorShape([batchSize, len(classes)]) ) )
validationGenerator = FileIterator( "validate" )
validationDataset = tf.data.Dataset.from_generator( validationGenerator, (tf.float32, tf.float32), (tf.TensorShape([batchSize, patchSize, patchSize, 3]), tf.TensorShape([batchSize, len(classes)]) ) )
but I am getting error
TypeError: `generator` yielded an element that did not match the expected structure. The expected structure was (tf.float32, tf.float32), but the yielded element was [[[[185. 185. 185.]
[158. 158. 158.]
[145. 145. 145.]
...
And code example for Dataset.from_generator has an array as a second item in tuple and similar output_types=(tf.int64, tf.int64). And I guess it works there.
Attempt to add arrays to type results in another error
TypeError: unhashable type: 'list'
What should I change to make it work?