TensorFlow TFRecord Image Encoding & Decoding

Viewed 15

I'm trying to decode images that I have encoded (tf.io.serialize_tensor(object).numpy()) as ByteFeatures within a TFRecord. I've narrowed down the error to the decoding of the image and mask fields but am unable to find a solution.

Troubleshooting steps:

  • Perform encoding and decoding outside of the functions. This performed as intended.
  • Attempted to reshape the images (seen commented out below). Failed
  • Attempted tf.ensure_shape. Failed due to the shape not conforming.

Observations:

  • When printing the shape of the tf.io.parse_tensor within the function, the shape returns unknown
  • Error message shows the shape as [640, 3] instead of [640,640,3]
  • I'm surprised my desk isn't broken

Any guidance?

def decode_tfrecord(record):
    features = tf.io.parse_single_example(
        record,
        {
            'age': tf.io.FixedLenFeature([], tf.float32),
            'image': tf.io.FixedLenFeature([], tf.string),
            'mask': tf.io.FixedLenFeature([], tf.string),
            'organ': tf.io.FixedLenFeature([], tf.string),
            'sex': tf.io.FixedLenFeature([], tf.string)
        }
    )

    image = tf.ensure_shape(tf.io.parse_tensor(features['image'], out_type=tf.float32), (640,640,3))
    # image = tf.reshape(image, [640,640,3])

    mask = tf.io.parse_tensor(features['mask'], out_type=tf.float32)
    # print(mask.shape)
    # mask = tf.reshape(mask, [640, 640, 1])
    # mask = tf.cast(mask, tf.uint8)

    organ = features['organ']
    age = features['age']
    sex = features['sex']
    
    return image, mask, organ, age, sex

def get_train_ds(ds):
    FNAMES_TRAIN_TFRECORDS = tf.io.gfile.glob('tfrecords/*.tfrecords')

    train_ds = tf.data.TFRecordDataset(
        FNAMES_TRAIN_TFRECORDS,
        num_parallel_reads=1
    )

    train_ds = train_ds.map(
        decode_tfrecord, 
        num_parallel_calls=multiprocessing.cpu_count()
    )

    train_ds = train_ds.batch(ds)

    return train_ds

def show_batch(ds, rows=10, cols=3):
    images, masks, organs, age, sex = next(iter(ds))

    fig, ax = plt.subplots(nrows=rows, ncols=cols, figsize=(cols*6, rows*6))
    for r in range(rows):
        ax[r, 0].imshow(images[r])
        organ = organs[r].numpy().decode('UTF-8')
        ax[r, 0].set_title(f'Image {r} - Organ: {organ}')
        ax[r, 0].axis('off')

        ax[r, 1].imshow(masks[r])
        ax[r, 1].set_ have a strong desktitle(f'Mask {r}')
        ax[r, 1].axis('off')

        ax[r, 2].imshow(images[r])
        ax[r, 2].imshow(masks[r], alpha=0.5)   
        ax[r, 2].set_title(f'Image {r} + Mask {r}')
        ax[r, 2].axis('off')

When ran I get the following error code:

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
/home/kyle/Desktop/kaggle/eda.ipynb Cell 31 in <cell line: 2>()
      1 train_ds = get_train_ds(10)
----> 2 show_batch(train_ds)

/home/kyle/Desktop/kaggle/eda.ipynb Cell 31 in show_batch(ds, rows, cols)
     44 def show_batch(ds, rows=10, cols=3):
---> 45     images, masks, organs, age, sex = next(iter(ds))
     47     fig, ax = plt.subplots(nrows=rows, ncols=cols, figsize=(cols*6, rows*6))
     48     for r in range(rows):

File ~/anaconda3/envs/tensorflow/lib/python3.9/site-packages/tensorflow/python/data/ops/iterator_ops.py:766, in OwnedIterator.__next__(self)
    764 def __next__(self):
    765   try:
--> 766     return self._next_internal()
    767   except errors.OutOfRangeError:
    768     raise StopIteration

File ~/anaconda3/envs/tensorflow/lib/python3.9/site-packages/tensorflow/python/data/ops/iterator_ops.py:749, in OwnedIterator._next_internal(self)
    746 # TODO(b/77291417): This runs in sync mode as iterators use an error status
    747 # to communicate that there is no more data to iterate over.
    748 with context.execution_mode(context.SYNC):
--> 749   ret = gen_dataset_ops.iterator_get_next(
    750       self._iterator_resource,
...
   7163   e.message += (" name: " + name if name is not None else "")
-> 7164   raise core._status_to_exception(e) from None

InvalidArgumentError: Shape of tensor ParseTensor [640,3] is not compatible with expected shape [640,640,3].
     [[{{node EnsureShape}}]] [Op:IteratorGetNext]
0 Answers
Related