Found a workaround by adding keras.applications.mobilenet_v2.preprocess_input() as a layer in between an input layer and the premade model, like so:
input = keras.layers.Input([224, 224, 3])
pre = keras.applications.mobilenet_v2.preprocess_input(input)
net = keras.applications.MobileNetV2(
input_tensor = pre,
alpha=1.0,
include_top=True,
weights=None,
classes=3,
classifier_activation="softmax",
name=None,
)
model = keras.Model(inputs=input, outputs=net.output)
Technically a different function than in the original question, but ultimately they both end up calling keras\src\applications\imagenet_utils.py and produce the same error when they do, so this should hopefully work for all preprocess_input functions that end up calling this.
Answer from Lentemern on Stack Overflowpython - '_PrefetchDataset' object has no attribute 'shape' when calling resnet_v2.preprocess_input() - Stack Overflow
keras - Tensorflow v1 Dataset API AttributeError with ndim - Data Science Stack Exchange
Dataset object has no attribute `to_tf_dataset`
TypeError: 'PrefetchDataset' object is not subscriptable - General Discussion - Google AI Developers Forum
Greetings,
I have serialized and stored some data as TFRecords, and created datasets from these records using TFRecordDataset. I was under the impression that this can be passed directly to a Keras model for fitting, but I am receiving an error. If I attempt to batch the dataset, the error I get upon attempting to fit is AttributeError: 'BatchDataset' objecthas no attribute 'ndim.' If I attempt to shuffle the training dataset before fitting, I get AttributeError: 'ShuffleDataset' object has no attribute 'ndim.' If I do neither of these and just pass the dataset as-is, I get AttributeError: 'TFRecordDatasetV2' objecthas no attribute 'ndim.'
Seems like Keras is still expecting an array, which I don't quite understand. Am I missing something? In the TF documentation, they have an example where they pass a Dataset created from tensor slices, but not one created from TFRecords.
You can convert it to a list with list(ds) and then recompile it as a normal Dataset with tf.data.Dataset.from_tensor_slices(list(ds)). From there your nightmare begins again but at least it's a nightmare that other people have had before.
Note that for more complex datasets (e.g. nested dictionaries) you will need more preprocessing after calling list(ds), but this should work for the example you asked about.
This is far from a satisfying answer but unfortunately the class is entirely undocumented and none of the standard Dataset tricks work.
You can turn use map to select either the input or label from every (input, label) pair, and turn this into a list:
import tensorflow as tf
import numpy as np
inputs = np.random.rand(100, 99)
targets = np.random.rand(100)
ds = tf.data.Dataset.from_tensor_slices((inputs, targets))
X_train = list(map(lambda x: x[0], ds))
y_train = list(map(lambda x: x[1], ds))