评估TensorFlow模型遇TypeError错误,求测试数据评估方案
解决TensorFlow评估时的TypeError: unhashable type: 'numpy.ndarray'
这个错误我之前在处理TensorFlow数据读取流程时也碰到过,本质是你把numpy数组传入了需要哈希的TensorFlow操作中——numpy数组是不可哈希的,而像tf.read_file这类API需要处理的是TensorFlow张量,不是原生numpy数组。结合你给出的场景,我整理了几个排查和解决的方向:
1. 确认queue的类型是否正确
你提到的readSample(queue)函数,这里的queue如果是直接从测试文件读取的numpy数组(比如用np.loadtxt读取后直接传入),就会触发这个错误。因为tf.read_file需要接收的是TensorFlow的字符串张量,而不是numpy数组。
错误示例(触发问题的常见写法)
import numpy as np # 读取测试数据 test_data = np.loadtxt("test.txt", dtype=str, delimiter=' ') image_paths = test_data[:, 0] labels = test_data[:, 1] # 直接把numpy数组传入readSample,导致错误 image, label = readSample([image_paths, labels])
2. 修正方案:用TensorFlow张量替代numpy数组作为输入
推荐使用tf.data.Dataset(TensorFlow 1.x/2.x都支持,新版更推荐)来构建测试数据流水线,或者用旧版的队列API将numpy数组转换为张量后入队。
方案一:使用tf.data.Dataset(推荐)
这是目前最简洁且兼容新版TensorFlow的方式,直接将numpy数组转换为数据集,再映射你的预处理逻辑:
import tensorflow as tf import numpy as np # 读取测试数据文件 test_data = np.loadtxt("test.txt", dtype=str, delimiter=' ') image_paths = test_data[:, 0] labels = test_data[:, 1] # 定义预处理函数(替代你的readSample) def preprocess_sample(image_path, label): # 读取图片 file_contents = tf.read_file(image_path) image = tf.image.decode_jpeg(file_contents, channels=3) # 这里可以添加你的其他预处理逻辑(resize、归一化等) # 确保标签转换为TensorFlow张量(根据你的标签类型调整dtype) label = tf.convert_to_tensor(label, dtype=tf.int32) return image, label # 构建数据集 test_dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels)) test_dataset = test_dataset.map(preprocess_sample) # 设置批量大小 test_dataset = test_dataset.batch(batch_size=32) # 获取测试batch # TensorFlow 2.x 直接迭代即可 for imageBatch_test, labelBatch_test in test_dataset: # 在这里执行模型评估逻辑 pass # 如果是TensorFlow 1.x,需要用迭代器 # iterator = test_dataset.make_one_shot_iterator() # imageBatch_test, labelBatch_test = iterator.get_next()
方案二:使用旧版队列API
如果你坚持使用原有的队列方式,需要先将numpy数组转换为TensorFlow张量,再通过slice_input_producer入队:
import tensorflow as tf import numpy as np # 读取测试数据 test_data = np.loadtxt("test.txt", dtype=str, delimiter=' ') image_paths = test_data[:, 0] labels = test_data[:, 1] # 将numpy数组转换为TensorFlow张量 image_tensor = tf.convert_to_tensor(image_paths, dtype=tf.string) label_tensor = tf.convert_to_tensor(labels, dtype=tf.int32) # 根据标签类型调整 # 创建切片队列 queue = tf.train.slice_input_producer([image_tensor, label_tensor], shuffle=False) # 调用你的readSample函数 imageBatch_test, labelBatch_test = tf.train.batch(readSample(queue), batch_size=32)
3. 额外检查:readSample函数内部的张量转换
如果你的readSample函数内部直接处理queue[1](标签)时,没有将其转换为TensorFlow张量,也可能导致后续操作出错。可以修改函数确保标签是张量类型:
def readSample(queue): # 将标签转换为TensorFlow张量(根据你的标签类型调整dtype) label = tf.convert_to_tensor(queue[1], dtype=tf.int32) file_contents = tf.read_file(queue[0]) example = tf.image.decode_jpeg(file_contents, channels=3) # 其他预处理逻辑... return example, label
内容的提问来源于stack exchange,提问作者user2743
相关产品推荐
相关产品推荐

