如何使用TensorFlow从9.9万张图像中提取1万张构建数据集
问题分析与解决
错误原因
你遇到的类型错误根源在于:
- 初始创建的是空字符串类型数据集,但后续拼接的是处理后的图像张量(形状
(256,256,3)),两者类型、形状完全不兼容。 - 循环逐个拼接数据集的方式既低效,也不符合TensorFlow数据集的设计逻辑。
load_and_preprocess_image里直接调用filename.numpy(),后续切换到图模式(比如训练阶段)会直接报错,因为numpy()仅支持Eager模式,正确做法是全程用TensorFlow API处理路径。
两种可行实现方案
方案一:Python层面先随机筛选1万张,再构建数据集
这种方式简单直观,适合数据量不是特别庞大的场景(9.9万完全适用):
import tensorflow as tf import os import random data_dir = '/home/clau/Escritorio/cropped/' # 1. 获取所有图像文件名,过滤非图片文件 all_filenames = [os.path.join(data_dir, f) for f in os.listdir(data_dir) if f.lower().endswith(('.jpg', '.jpeg'))] # 2. 随机打乱列表并取前1万张 random.shuffle(all_filenames) selected_filenames = all_filenames[:10000] # 3. 定义图像加载预处理函数(全程用TF API,避免numpy切换) def load_and_preprocess_image(file_path): img = tf.io.read_file(file_path) img = tf.image.decode_jpeg(img, channels=3) # convert_image_dtype自动完成像素值归一化到[0,1] img = tf.image.convert_image_dtype(img, tf.float32) img = tf.image.resize(img, [256, 256]) return img # 4. 构建数据集并优化 dataset = tf.data.Dataset.from_tensor_slices(selected_filenames) # 并行处理图像加载,提升效率 dataset = dataset.map(load_and_preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) # 可选:添加批处理和预取优化 dataset = dataset.batch(32).prefetch(tf.data.AUTOTUNE)
方案二:用tf.data原生API随机采样(无需提前加载所有文件名到内存)
适合超大规模数据集,全程在TensorFlow图内操作,性能更优:
import tensorflow as tf import os data_dir = '/home/clau/Escritorio/cropped/' # 1. 构建包含所有图片文件的数据集 dataset = tf.data.Dataset.list_files(os.path.join(data_dir, '*.jpg')) # 可根据实际后缀调整 # 2. 全局打乱(buffer_size设为总文件数确保完全打乱),取前1万张 total_files = 99000 dataset = dataset.shuffle(buffer_size=total_files, seed=42).take(10000) # 3. 加载预处理图像(同方案一的函数) def load_and_preprocess_image(file_path): img = tf.io.read_file(file_path) img = tf.image.decode_jpeg(img, channels=3) img = tf.image.convert_image_dtype(img, tf.float32) img = tf.image.resize(img, [256, 256]) return img dataset = dataset.map(load_and_preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) # 可选优化 dataset = dataset.batch(32).prefetch(tf.data.AUTOTUNE)
关键注意点
- 务必过滤非图像文件,避免加载无效文件导致解码错误。
num_parallel_calls=tf.data.AUTOTUNE让TensorFlow自动分配并行资源,大幅提升图像加载速度。tf.image.convert_image_dtype已自动完成像素值归一化,无需额外执行img = img / 255.0。
内容的提问来源于stack exchange,提问作者Claudia P
相关产品推荐
相关产品推荐

