使用TensorFlow InceptionV3预处理函数时的错误问题
问题:TensorFlow数据集预处理报错TypeError: unsupported operand type(s) for /=: 'BatchDataset' and 'float'
代码实现参数及数据集加载逻辑
# Here my args, they are pretty much the same for all three functions: training_preprocessing_args = dict( labels='inferred', label_mode='int', class_names=classes, color_mode='rgb', image_size=hyper_parameter["image_size"], shuffle=True, seed=seed, validation_split=None, subset=None, interpolation='bilinear', follow_links=False, crop_to_aspect_ratio=False ) logging.info("Training Data:") train_dataset:tf.data.Dataset = tf.keras.utils.image_dataset_from_directory(directory=PATH_DATA_TRAINING, **training_preprocessing_args) logging.info("Testing Data:") test_dataset:tf.data.Dataset = tf.keras.utils.image_dataset_from_directory(directory=PATH_DATA_TESTING, **testing_preprocessing_args) logging.info("Validation Data:") validation_dataset:tf.data.Dataset = tf.keras.utils.image_dataset_from_directory(directory=PATH_DATA_VALIDATION, **validation_preprocessing_args) logging.info("Preprocessing:") train_dataset = tf.keras.applications.inception_v3.preprocess_input(tf.cast(train_dataset, tf.float32)) validation_dataset = tf.keras.applications.inception_v3.preprocess_input(tf.cast(validation_dataset, tf.float32)) test_dataset = tf.keras.applications.inception_v3.preprocess_input(tf.cast(test_dataset, tf.float32))
报错信息
15-12-2022 23:21:15 INFO Training Data: Found 6988 files belonging to 10 classes. 2022-12-15 23:21:16.075523: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX AVX2 To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. INFO:tensorflow:Converted call: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761FC0> args: (<tf.Tensor 'args_0:0' shape=() dtype=string>,) kwargs: {} 15-12-2022 23:21:16 INFO Converted call: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761FC0> args: (<tf.Tensor 'args_0:0' shape=() dtype=string>,) kwargs: {} INFO:tensorflow:Allowlisted: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761FC0>: DoNotConvert rule for keras 15-12-2022 23:21:16 INFO Allowlisted: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761FC0>: DoNotConvert rule for keras 15-12-2022 23:21:16 INFO Testing Data: Found 1699 files belonging to 10 classes. INFO:tensorflow:Converted call: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D763490> args: (<tf.Tensor 'args_0:0' shape=() dtype=string>,) kwargs: {} 15-12-2022 23:21:16 INFO Converted call: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D763490> args: (<tf.Tensor 'args_0:0' shape=() dtype=string>,) kwargs: {} INFO:tensorflow:Allowlisted: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D763490>: DoNotConvert rule for keras 15-12-2022 23:21:16 INFO Allowlisted: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D763490>: DoNotConvert rule for keras 15-12-2022 23:21:16 INFO Validation Data: Found 1700 files belonging to 10 classes. INFO:tensorflow:Converted call: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761BD0> args: (<tf.Tensor 'args_0:0' shape=() dtype=string>,) kwargs: {} 15-12-2022 23:21:16 INFO Converted call: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761BD0> args: (<tf.Tensor 'args_0:0' shape=() dtype=string>,) kwargs: {} INFO:tensorflow:Allowlisted: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761BD0>: DoNotConvert rule for keras 15-12-2022 23:21:16 INFO Allowlisted: <function paths_and_labels_to_dataset.<locals>.<lambda> at 0x000002063D761BD0>: DoNotConvert rule for keras 15-12-2022 23:21:16 INFO Preprocessing: Traceback (most recent call last): File "_CORE\main.py", line 27, in <module> main() File "_CORE\main.py", line 17, in main data:tuple = run_preprocessing() File "_CORE\preprocessing\run.py", line 10, in run_preprocessing data = create_datasets() File "_CORE\preprocessing\CreateDataset.py", line 23, in create_datasets train_dataset = tf.keras.applications.inception_v3.preprocess_input(train_dataset)#tf.cast(train_dataset, tf.float32)) File "_ENV\_ENV_1\lib\site-packages\keras\applications\inception_v3.py", line 448, in preprocess_input return imagenet_utils.preprocess_input( File "_ENV\_ENV_1\lib\site-packages\keras\applications\imagenet_utils.py", line 123, in preprocess_input return _preprocess_symbolic_input(x, data_format=data_format, mode=mode) File "_ENV\_ENV_1\lib\site-packages\keras\applications\imagenet_utils.py", line 271, in _preprocess_symbolic_input x /= 127.5 TypeError: unsupported operand type(s) for /=: 'BatchDataset' and 'float'
参考官方示例
i = tf.keras.layers.Input([None, None, 3], dtype = tf.uint8) x = tf.cast(i, tf.float32) x = tf.keras.applications.mobilenet.preprocess_input(x) core = tf.keras.applications.MobileNet() x = core(x) model = tf.keras.Model(inputs=[i], outputs=[x]) image = tf.image.decode_png(tf.io.read_file('file.png')) result = model(image)
问题分析与解决方法
错误原因
你直接将BatchDataset对象传给了preprocess_input函数,但该函数的处理对象是单个张量(Tensor),而非整个数据集。tf.keras.utils.image_dataset_from_directory返回的是包含(图像张量,标签张量)的批次数据集,无法直接作为预处理函数的参数。
解决方法
方法1:用map函数处理数据集
针对数据集中的每个元素(图像+标签)单独执行预处理:
def preprocess_fn(image, label): # 转换图像张量类型 image = tf.cast(image, tf.float32) # 应用InceptionV3的预处理逻辑 image = tf.keras.applications.inception_v3.preprocess_input(image) return image, label # 对三个数据集分别应用预处理 train_dataset = train_dataset.map(preprocess_fn) validation_dataset = validation_dataset.map(preprocess_fn) test_dataset = test_dataset.map(preprocess_fn)
方法2:将预处理整合到模型中(适配官方示例)
把预处理逻辑作为模型的输入层部分,数据传入模型时自动完成预处理:
# 假设你的输入尺寸是hyper_parameter["image_size"],例如(299,299) input_layer = tf.keras.layers.Input(shape=(*hyper_parameter["image_size"], 3), dtype=tf.uint8) x = tf.cast(input_layer, tf.float32) x = tf.keras.applications.inception_v3.preprocess_input(x) # 加载预训练的InceptionV3(根据需求设置参数) base_model = tf.keras.applications.InceptionV3(weights='imagenet', include_top=False, input_tensor=x) # 添加自定义分类层(示例) x = base_model.output x = tf.keras.layers.GlobalAveragePooling2D()(x) output_layer = tf.keras.layers.Dense(len(classes), activation='softmax')(x) model = tf.keras.Model(inputs=input_layer, outputs=output_layer)
这种方式下,你可以直接将image_dataset_from_directory返回的原始数据集传入模型训练,无需提前处理。
关于尺寸调整
你设置的image_size=hyper_parameter["image_size"]已经让image_dataset_from_directory自动将所有图像调整到指定尺寸,不需要额外处理。预处理函数仅负责像素值归一化、缩放等操作,不承担尺寸调整的工作。
内容的提问来源于stack exchange,提问作者JustSomeCoder
相关产品推荐
相关产品推荐

