使用image_dataset_from_directory加载数据集时能否获取对应图片文件名?
实现方案
该需求完全可以实现。默认调用image_dataset_from_directory仅返回(图像, 标签)二元组,没有包含文件路径信息,只需修改数据集加载逻辑,同步返回对应图像的文件路径即可,具体操作如下:
步骤1:修改数据集加载参数
TF 2.4及以上版本的image_dataset_from_directory提供了return_paths参数,设置为True后会返回(图像, 标签, 文件路径)三元组,路径和对应图像、标签始终一一绑定,即使开启shuffle也不会错位。
修改后的加载代码:
VALIDATION_DATASET = image_dataset_from_directory( VALIDATION_DIR, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_SIZE, return_paths=True # 新增参数,开启文件路径返回 )
原有数据集拆分、prefetch优化逻辑无需修改。
步骤2:修改测试阶段代码,同步收集路径、标签、预测结果
无需手动拆分多个batch单独预测,直接遍历测试数据集统一收集所有数据即可,示例代码如下:
import numpy as np import tensorflow as tf from sklearn.metrics import classification_report import pandas as pd # 加载模型 model_name = r"C:\model\location\pre_trained_model.h5" model = tf.keras.models.load_model(model_name) # 初始化列表存储全量数据 all_file_paths = [] all_true_labels = [] all_pred_labels = [] # 遍历测试集批量处理 for image_batch, label_batch, path_batch in test_dataset: # 收集当前批次的文件路径和真实标签 all_file_paths.extend(path_batch.numpy().astype(str)) all_true_labels.extend(label_batch.numpy()) # 生成预测结果 pred = tf.where(tf.nn.sigmoid(model.predict_on_batch(image_batch).flatten()) < 0.5, 0, 1) all_pred_labels.extend(pred.numpy()) # 输出分类报告 classificationRPRT = classification_report(all_true_labels, all_pred_labels, target_names=CLASSES_NAMES) print(classificationRPRT) # 导出比对表到CSV,方便后续和人工标注结果核对 result_df = pd.DataFrame({ "文件路径": all_file_paths, "真实分类": [CLASSES_NAMES[i] for i in all_true_labels], "模型预测分类": [CLASSES_NAMES[i] for i in all_pred_labels] }) result_df.to_csv("图像分类结果比对表.csv", index=False, encoding="utf-8-sig")
低版本TF兼容方案
如果使用的TF版本低于2.4,没有return_paths参数,可以手动构造数据集实现相同效果:
import pathlib # 读取所有图像路径和对应标签 val_root = pathlib.Path(VALIDATION_DIR) all_image_paths = [str(p) for p in val_root.glob("*/*")] CLASSES_NAMES = sorted([item.name for item in val_root.glob("*/") if item.is_dir()]) label_map = {name: idx for idx, name in enumerate(CLASSES_NAMES)} all_labels = [label_map[pathlib.Path(p).parent.name] for p in all_image_paths] # 定义图像预处理函数,同步返回路径 def preprocess(path, label): img = tf.io.read_file(path) img = tf.image.decode_jpeg(img, channels=3) img = tf.image.resize(img, IMG_SIZE) return img, label, path # 构造数据集 VALIDATION_DATASET = tf.data.Dataset.from_tensor_slices((all_image_paths, all_labels)) VALIDATION_DATASET = VALIDATION_DATASET.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE) VALIDATION_DATASET = VALIDATION_DATASET.shuffle(len(all_image_paths)).batch(BATCH_SIZE)
后续拆分数据集、测试逻辑和上面的高版本方案完全一致。
内容的提问来源于stack exchange,提问作者Thulfiqar
相关产品推荐
相关产品推荐

