0

I am trying to do image colorization. I have 5000 images (256x256x3) and would like not to load all data in my program (for memory reason). I have found that it is possible to use ImageDataGenerator.flow_from_directory() but I use LAB images and I would like to feed my model with a numpy array of the L component (256, 256, 1). My targets are A and B components (256, 256, 2). To have my image I then merge the input and output to have a LAB image (256, 256, 3). The problem i that ImageDataGenerator.flow_from_directory() only works with image type files (so a 256x256x3 image) and I would like to know if there is a way to do the same thing with numpy arrays.

I tried using tf.data.Dataset.list_files(), I had all my files but I did not found how to load my numpy array to feed my model. I guess I need to use some sort of generator but I do not really understand how to use it. This is what I have for now :

HEIGHT = 256
WIDTH = HEIGHT
Batch_size = 50

dir_X_train = 'data/X_train_np/train_black_resized/*.npy'
dir_X_test = 'data/X_test/test_black_resized/*.npy'
dir_y_train = 'data/y_train_np/train_color_resized/*.npy'
dir_y_test = 'data/y_test/test_color_resized/*.npy'

X_train_dataset = tf.data.Dataset.list_files(dir_X_train, shuffle=False).batch(Batch_size)
y_train_dataset = tf.data.Dataset.list_files(dir_y_train, shuffle=False).batch(Batch_size)

def process_path(file_path):
  return tf.io.read_file(file_path[0])

X_train_dataset = X_train_dataset.map(process_path)
y_train_dataset = y_train_dataset.map(process_path)

train_dataset = tf.data.Dataset.zip((X_train_dataset, y_train_dataset))

for image_black, image_color in train_dataset.take(1):
   print(image_black.numpy()[:100])
   print(type(image_black))
   print(image_color.numpy()[:100])
   print(type(image_color))

Output :

b"\x93NUMPY\x01\x00v\x00{'descr': '<f4', 'fortran_order': False, 'shape': (256, 256), }                           "
<class 'tensorflow.python.framework.ops.EagerTensor'>
b"\x93NUMPY\x01\x00v\x00{'descr': '<f4', 'fortran_order': False, 'shape': (256, 256, 2), }                        "
<class 'tensorflow.python.framework.ops.EagerTensor'>

The shape seems to be correct but I don't know how to have the numpy.array

Evermus
  • 1
  • 1
  • check - https://stackoverflow.com/questions/45427637/numpy-to-tfrecords-is-there-a-more-simple-way-to-handle-batch-inputs-from-tfrec – Vijay Mariappan Nov 18 '22 at 16:55
  • Does this answer your question? [Is there a simpler way to handle batch inputs from tfrecords?](https://stackoverflow.com/questions/45427637/is-there-a-simpler-way-to-handle-batch-inputs-from-tfrecords) – desertnaut Nov 18 '22 at 17:56
  • @V.M wouldn't that still load everything into memory? If so, OP might as well just use numpy arrays as input directly. (even though they said they'd like to not load all in their program) – Djinn Nov 18 '22 at 19:46
  • It doesnt. The above creates tfrecords. And you can set `buffer_size`, to how much data can be loaded. – Vijay Mariappan Nov 19 '22 at 01:07
  • Does this solve your problem? https://stackoverflow.com/a/74388725/7746219 – Mohammad Ahmed Nov 19 '22 at 05:40
  • @MohammadAhmed I tried your methode but my `model.fit` wont work : `ValueError: as_list() is not defined on an unknown TensorShape.` – Evermus Nov 19 '22 at 11:51
  • Hi @Evermus, you can use `np.load()` and `tf.data.Dataset.from_tensor_slices` to load numpy array to a Tensorflow dataset. Kindly refer to this [gist](https://colab.research.google.com/gist/synandi/7c67e3c31c597ee8238672d63b9a9b0a/74492503.ipynb#scrollTo=gOeufSgms2IX). Thank you! –  Nov 30 '22 at 14:17
  • @Tfer3 I tried using that but I can not fit my model, it consider my input as a Tuple and I get the following error : `AttributeError: 'tuple' object has no attribute 'shape'` – Evermus Nov 30 '22 at 23:43
  • @Evermus, please try casting the dataset using `np.array(list(dataset))`. Thank you! –  Dec 14 '22 at 09:29

0 Answers0