Using tfrec files in Keras - tensorflow

I feel like this should be simple but cannot for the life of me work it out.
I have this melanoma dataset(https://www.kaggle.com/datasets/cdeotte/melanoma-512x512/code) (in tfrec format) downloaded to my local machine.
import os
import cv2
import numpy as np
import pandas as pd
import albumentations
import tensorflow as tf
from tensorflow import keras
features = {'image': tf.io.FixedLenFeature([], tf.string),
'image_name': tf.io.FixedLenFeature([], tf.string),
'patient_id': tf.io.FixedLenFeature([], tf.int64),
'sex': tf.io.FixedLenFeature([], tf.int64),
'age_approx': tf.io.FixedLenFeature([], tf.int64),
'anatom_site_general_challenge': tf.io.FixedLenFeature([], tf.int64),
'diagnosis': tf.io.FixedLenFeature([], tf.int64),
'target': tf.io.FixedLenFeature([], tf.int64),
'width': tf.io.FixedLenFeature([], tf.int64),
'height': tf.io.FixedLenFeature([], tf.int64)}
train_filepaths=tf.io.gfile.glob(path+'/train*.tfrec')
train_filepaths
this lists all the files:
['\Users\adban\Dissertation\Moles\512\train00-2182.tfrec',
'\Users\adban\Dissertation\Moles\512\train01-2185.tfrec',
'\Users\adban\Dissertation\Moles\512\train02-2193.tfrec', ...]
But I cannot seem to decode them. (Tried 'tf.io.parse_single_example' and 'tf.data.TFRecordDataset' but either get a parse error or an empty array returned.)

I figured it out.
This will add all images to a list as 3d array.
def _parse_image_function(example_proto):
return tf.io.parse_single_example(example_proto, features)
def preprocess_image(image):
image = tf.io.decode_image(image, channels=3)
return image
path = '/Users/adban/Dissertation/Moles/512'
tfimage_set = []
for filename in os.listdir(path):
#change for
train_image_dataset = tf.data.TFRecordDataset(path+'/'+filename)
train_images = train_image_dataset.map(_parse_image_function)
for image_feature in train_images:
image_raw = preprocess_image(image_feature['image'])
image_raw_np = image_raw.numpy()
tfimage_set.append(image_raw_np)

Related

How to parse an in-house TFRecords dataset when loading it using ImportExampleGen

Following the official tutorial, this is how I should load a TFRecord dataset:
raw_image_dataset = tf.data.TFRecordDataset('images.tfrecords')
# Create a dictionary describing the features.
image_feature_description = {
'height': tf.io.FixedLenFeature([], tf.int64),
'width': tf.io.FixedLenFeature([], tf.int64),
'depth': tf.io.FixedLenFeature([], tf.int64),
'label': tf.io.FixedLenFeature([], tf.int64),
'image_raw': tf.io.FixedLenFeature([], tf.string),
}
def _parse_image_function(example_proto):
# Parse the input tf.train.Example proto using the dictionary above.
return tf.io.parse_single_example(example_proto, image_feature_description)
parsed_image_dataset = raw_image_dataset.map(_parse_image_function)
parsed_image_dataset
The _parse_image_function is where I get the chance to set the type and shape of my loaded tensors.
But then, when I'm loading the same file using ImportExampleGen, I don't see how I can inject my parse function into the mix!
context = InteractiveContext()
example_gen = tfx.components.ImportExampleGen(input_base=_dataset_folder)
context.run(example_gen, enable_cache=True)
Does anyone know what's going to happen to my parse logic when I'm using the ImportExampleGen class instead of loading my dataset directly using TFRecordDataset class?

How to parse a tfds.features.Sequence object ? It is not compatible with tf.io.FixedLenSequenceFeature

Recently I was trying to train a model on the Wider-Face Dataset. I found it is prebuilt into tfds (https://www.tensorflow.org/datasets/catalog/wider_face). However I am having difficulty parsing it. It's feature map is of the following form -
FeaturesDict({
'faces': Sequence({
'bbox': BBoxFeature(shape=(4,), dtype=tf.float32),
'blur': tf.uint8,
'expression': tf.bool,
'illumination': tf.bool,
'invalid': tf.bool,
'occlusion': tf.uint8,
'pose': tf.bool,
}),
'image': Image(shape=(None, None, 3), dtype=tf.uint8),
'image/filename': Text(shape=(), dtype=tf.string),})
So I passed the following nested dictionary to tf.io.parse_single_example
feature_description = {'faces': {
'bbox': tf.io.FixedLenFeature([], dtype=tf.float32),
'blur': tf.io.FixedLenFeature([], dtype=tf.uint8),
'expression': tf.io.FixedLenFeature([], dtype=tf.bool),
'illumination': tf.io.FixedLenFeature([], dtype=tf.bool),
'invalid': tf.io.FixedLenFeature([], dtype=tf.bool),
'occlusion': tf.io.FixedLenFeature([], dtype=tf.uint8),
'pose': tf.io.FixedLenFeature([], dtype=tf.bool),
},
'image': tf.io.FixedLenFeature([], dtype=tf.uint8),
'image/filename': tf.io.FixedLenFeature([], dtype=tf.string),}
But it gives me a value error of ValueError: Unsupported dict. Later I also learnt that Sequence does not support features which are of type tf.io.FixedLenSequenceFeature.
Please let me know how can I parse this type of TFRecords. I didn't find much documentation of how to use the object detection datasets that are build into Tensorflow, so providing some links with examples will also be helpful.
Thanks

How to read a datapoint with multiple lables from a tfrecord file

I am writing data with multiple labels for each image, in this case bounding box and classification labels and am using the following function to write the data to a tfrecord :
def tfr_write_sr(data_split_name,save_dir, label_array, data_array):
filename = os.path.join(save_dir, data_split_name + '.tfrecords')
writer = tf.python_io.TFRecordWriter(filename)
for index in range(data_array.shape[0]):
image = data_array[index].tostring()
example = tf.train.Example(features=tf.train.Features(
feature={
'height': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[data_array.shape[1]])),
'width': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[data_array.shape[2]])),
'depth': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[data_array.shape[3]])),
'shape_type': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[int(label_array[index][3])])),
'bbtl_x': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[int(label_array[index][1][0])])),
'bbtl_y': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[int(label_array[index][1][1])])),
'bbbr_x': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[int(label_array[index][0][0])])),
'bbbr_y': tf.train.Feature(
int64_list=tf.train.Int64List(
value=[int(label_array[index][0][1])])),
'image_raw': tf.train.Feature(
bytes_list=tf.train.BytesList(
value=[image]))}))
writer.write(example.SerializeToString())
writer.close()
I have verified that the record is being written correctly but all the examples I have seen before only read one label per image, how do I read multiple labels ?
First we read in our tfrecord and get its features :
reader = tf.TFRecordReader()
_ , serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example,
features={
'image_raw': tf.FixedLenFeature([],tf.string),
'shape_type' : tf.FixedLenFeature([], tf.int64),
'bbtl_x' : tf.FixedLenFeature([], tf.int64),
'bbtl_y' : tf.FixedLenFeature([], tf.int64),
'bbbr_x' : tf.FixedLenFeature([], tf.int64),
'bbbr_y' : tf.FixedLenFeature([], tf.int64)
})
Now we have our features we can use tf.stack() to build a tensor for our multilables and add it to our graph :
label = tf.stack([features['shape_type'],
features['bbtl_x'],
features['bbtl_y'],
features['bbbr_x'],
features['bbbr_y'] ], axis=0 )
image = tf.decode_raw(features['image_raw'], tf.uint8)
images_batch, labels_batch = tf.train.shuffle_batch([image,label],
batch_size=128,
capacity=2000,
min_after_dequeue=1000)

Decoding Training Examples

I am using a ddsm dataset to make a CNN, and the owner of the dataset gave some code to decode the training examples, but I can't figure out what first part of the code is actually doing. Still learning.
For reference: https://www.kaggle.com/skooch/ddsm-mammography/home
The code: features = tf.parse_single_example(
serialized_example,
features={
'label': tf.FixedLenFeature([], tf.int64),
'label_normal': tf.FixedLenFeature([], tf.int64),
'image': tf.FixedLenFeature([], tf.string)
})

TensorFlow - Decoding images in a given shape from TF records

I am trying to read images from TFrecords file. The images vary in shapes. After reading, I want to preserve their shape which is why I pass the height, width and depth parameters appropriately. But the code just doesn't print anything after the set_shape command. I initialized the session in the main function. Is there a way to get the values of height,w,d tensors so that I can pass it to set_shape? How do I fix this? Any suggestions are welcome. Thanks in advance.
def read_and_decode(sess,filename_queue):
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(
serialized_example,
# Defaults are not specified since both keys are required.
features={
'height': tf.FixedLenFeature([], tf.int64),
'width': tf.FixedLenFeature([], tf.int64),
'depth': tf.FixedLenFeature([], tf.int64),
'image_raw': tf.FixedLenFeature([], tf.string),
'label': tf.FixedLenFeature([], tf.int64),
})
# Convert from a scalar string tensor (whose single string has
# length mnist.IMAGE_PIXELS) to a uint8 tensor with shape
# [mnist.IMAGE_PIXELS].
image = tf.decode_raw(features['image_raw'], tf.uint8)
image.set_shape([sess.run(features['height']),sess.run(features['width']),sess.run(features['depth'])])
Here's my main function:
def main(argv=None):
with tf.Graph().as_default():
sess=tf.Session()
pdb.set_trace()
load_inputs(sess,FLAGS.batch_size)
and load_input() function which calls the read_and_decode().
def load_inputs(sess,batch_size):
filenames='/home/dp1248/ICR_TF/original_iam_test_words.tfrecords'
# Create a queue that produces the filenames to read.
filename_queue = tf.train.string_input_producer([filenames],num_epochs=1)
# Even when reading in multiple threads, share the filename
# queue.
image, label = read_and_decode(sess,filename_queue)