TensorFlow用interleave加载数据集报错:期望路径对象而非Tensor如何解决
问题解决方案
报错根因
interleave回调中拿到的filename是TensorFlow图模式下的字符串Tensor,属于延迟计算的占位对象,而tf.data.experimental.load是eager执行的Python API,仅接收实际的路径字符串/字节/os.PathLike对象,无法直接识别Tensor类型参数,因此抛出类型错误。
可行解法
方案1:固定路径列表场景(更简单,性能更好)
如果你的路径列表是提前确定的,不需要动态生成,可以直接提前加载所有数据集再做interleave,完全避开图模式参数问题:
import tensorflow as tf filenames = ["data4/0/31", "data4/0/32"] # 预先加载所有路径对应的数据集 datasets = [tf.data.experimental.load(path) for path in filenames] dataset = tf.data.Dataset.from_tensor_slices(datasets).interleave( lambda x: x, cycle_length=4, block_length=16 ) for item in dataset.as_numpy_iterator(): print(item)
方案2:路径需动态生成场景
如果路径是数据集运行过程中动态生成的,必须在图逻辑内处理,用tf.py_function包装加载逻辑,将Tensor转换为实际的字符串路径再调用加载接口:
import tensorflow as tf filenames = ["data4/0/31", "data4/0/32"] dataset = tf.data.Dataset.from_tensor_slices(filenames) def load_by_path(filename_tensor): # 将Tensor转为实际字符串路径 path = filename_tensor.numpy().decode('utf-8') return tf.data.experimental.load(path) def wrap_load_fn(filename): # 此处Tout请替换为你实际保存的数据集元素类型,多元素可传类型元组,比如(Tout=(tf.float32, tf.int32)) loaded_ds = tf.py_function(func=load_by_path, inp=[filename], Tout=tf.float32) # 可选:手动补全shape信息,避免后续运算丢失shape,按你实际的单元素shape填写即可 # loaded_ds = loaded_ds.map(lambda x: tf.ensure_shape(x, (128, 128, 3))) return loaded_ds dataset = dataset.interleave( lambda x: wrap_load_fn(x), cycle_length=4, block_length=16 ) for item in dataset.as_numpy_iterator(): print(item)
注意事项
使用tf.py_function时,Tout参数必须和你保存数据集时的元素类型完全匹配,否则会出现类型不匹配报错。
内容的提问来源于stack exchange,提问作者Dinesh Kuruba
相关产品推荐
相关产品推荐

