Search code examples
pythontensorflowtensorflow-datasetstf.data.dataset

Tensorflow dataset with multiple inputs and target


I am trying to implement a model with the ArcFace Layer: https://github.com/4uiiurz1/keras-arcface

to this extend I created a tf.data.dataset like so:

images= tf.data.Dataset.from_tensor_slices(train.A_image.to_numpy())
target = tf.keras.utils.to_categorical(
    train.Label.to_numpy(), num_classes=n_class, dtype='float32'
)
target = tf.data.Dataset.from_tensor_slices(target)

images= images.map(transform_img)

dataset = tf.data.Dataset.zip((images, target, target))

when I call model.fit(dataset)

I get the following error:

ValueError: Layer model expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=<unknown> dtype=float32>]

But this should work according:

tf.data with multiple inputs / outputs in Keras

Can someone point out my folly?

Thanks!

Edit: this solves some problems:

#reads in filepaths to images from dataframe train
images = tf.data.Dataset.from_tensor_slices(train.image.to_numpy())
#converts labels to one hot encoding vector
target = tf.keras.utils.to_categorical(train.Label.to_numpy(), num_classes=n_class, dtype='float32')
#reads in the image and resizes it
images= images.map(transform_img)
input_1 = tf.data.Dataset.zip((anchors, target))
dataset = tf.data.Dataset.zip((input_1, target))

And I think it's what we are trying. But I get a shape error for targets, it's (n_class, 1) instead of just (n_class,)

I.e. the fit methods throws this error

ValueError: Shapes (n_class, 1) and (n_class, n_class) are incompatible

and this warning

input expected is (None, n_class) but received an input of (n_class, 1)

Solution

  • I've made changes to the solution based on the arcface, you've wanted here is the code, i've managed to train it

    The first one is from tensor slices as the original input and i used mnist to test it out

    def map_data(inputs, outputs):
        image = tf.cast(inputs['image_input'], tf.float32)
        image = image / 255.
        image = tf.expand_dims(image, axis=2)
        
        labels = tf.one_hot(outputs, 10)
        
        return {'image_input': image, 'label_input': labels}, labels
    
    dataset = tf.data.Dataset.from_tensor_slices(({
        'image_input': x_train, 'label_input': y_train
    }, y_train))
    dataset = dataset.map(map_data)
    dataset = dataset.batch(2)
    

    Here is the second type i have tried using a normal from tensor slices then i converted it to a multiple input, since both the normal labels are used for both the input and output

    def map_data(images, annot_labels):
        image = tf.cast(images, tf.float32)
        image = image / 255.
        image = tf.expand_dims(image, axis=2) # convert to 0 - 1 range
        
        labels = tf.one_hot(annot_labels, 10)
        
        return {'image_input': image, 'label_input': labels}, labels
    
    dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    dataset = dataset.map(map_data)
    dataset = dataset.batch(2)