TensorFlow初学者求助:如何向图中添加numpy数组与预处理数组
最简单的TensorFlow流水线添加自定义预处理数组方案
嘿,作为TensorFlow初学者能搭出基于tf.train.string_input_producer的图像流水线已经很厉害了!针对你要把[image, preprocess_array1, preprocess_array2]一起传入图中的需求,这里有几个适配你现有工作流的简单方案,你可以按需选择:
方案1:将预处理数组与图像文件名绑定存储,读取时同步加载
如果你的preprocess_array1和preprocess_array2是提前计算好的,可以把每个图像对应的数组存成和图像同名的.npy文件(比如img_001.jpg对应img_001_array1.npy和img_001_array2.npy)。然后在你的图像读取流程里,同步加载这些数组:
import tensorflow as tf import numpy as np def load_image_and_arrays(filename): # 读取图像 img_string = tf.read_file(filename) img = tf.image.decode_jpeg(img_string, channels=3) # 生成对应的数组文件名 array1_filename = tf.strings.regex_replace(filename, r'\.jpg$', '_array1.npy') array2_filename = tf.strings.regex_replace(filename, r'\.jpg$', '_array2.npy') # 用tf.py_func加载npy数组(适配TensorFlow 1.x写法) def load_npy(file_path): return np.load(file_path.decode('utf-8')) array1 = tf.py_func(load_npy, [array1_filename], tf.float32) array2 = tf.py_func(load_npy, [array2_filename], tf.float32) # 确保数组形状固定(根据你的实际数据维度调整) array1.set_shape((height, width, 1)) array2.set_shape((height, width, 1)) return img, array1, array2 # 你的现有文件名列表 filenames = ['img_001.jpg', 'img_002.jpg', ...] filename_queue = tf.train.string_input_producer(filenames) reader = tf.WholeFileReader() _, filename = reader.read(filename_queue) img, array1, array2 = load_image_and_arrays(filename) # 后续的batch处理 batch_img, batch_array1, batch_array2 = tf.train.batch([img, array1, array2], batch_size=32)
这个方案的好处是不需要改动太多现有代码,直接在读取环节同步加载对应数组,逻辑清晰易维护。
方案2:在图中直接计算预处理数组(如果数组可从图像/文件名推导)
如果preprocess_array1和preprocess_array2是可以通过图像本身或者文件名信息计算出来的(比如深度数组是图像的某个通道,或者从文件名里的编号推导),那完全可以在TensorFlow图里直接计算,省去存储数组的麻烦:
def load_image_and_generate_arrays(filename): # 读取图像 img_string = tf.read_file(filename) img = tf.image.decode_jpeg(img_string, channels=4) # 假设深度信息是第4通道 # 提取深度数组作为preprocess_array1 array1 = tf.expand_dims(img[:, :, 3], axis=-1) # 从文件名提取信息生成array2(比如文件名是img_depth_5.jpg,提取5作为基础值生成数组) depth_value = tf.strings.to_number(tf.strings.split(filename, '_')[2], out_type=tf.float32) array2 = tf.fill(tf.shape(img)[:2] + (1,), depth_value) return img[:, :, :3], array1, array2 # 后续的队列和batch处理和你现有代码一致 filename_queue = tf.train.string_input_producer(filenames) _, filename = reader.read(filename_queue) img, array1, array2 = load_image_and_generate_arrays(filename)
这种方案更高效,避免了额外的IO操作,适合数组可动态计算的场景。
方案3:用tf.train.slice_input_producer批量传入文件名和数组列表
如果你的预处理数组已经全部加载到内存里了(比如存在两个大列表array1_list和array2_list,顺序和filenames完全对应),那可以直接用slice_input_producer把三者打包后一起出队:
# 假设你已经有: # filenames = [img1.jpg, img2.jpg, ...] # array1_list = [array1_1, array1_2, ...] # 每个元素是numpy数组 # array2_list = [array2_1, array2_2, ...] # 将列表转成TensorFlow张量 array1_tensor = tf.convert_to_tensor(array1_list, dtype=tf.float32) array2_tensor = tf.convert_to_tensor(array2_list, dtype=tf.float32) filename_tensor = tf.convert_to_tensor(filenames, dtype=tf.string) # 打包后生成队列 input_tensors = [filename_tensor, array1_tensor, array2_tensor] slice_queue = tf.train.slice_input_producer(input_tensors, shuffle=True) # 读取图像并关联对应的数组 filename = slice_queue[0] array1 = slice_queue[1] array2 = slice_queue[2] img_string = tf.read_file(filename) img = tf.image.decode_jpeg(img_string, channels=3) # 生成batch batch_img, batch_array1, batch_array2 = tf.train.batch([img, array1, array2], batch_size=32)
这个方案适合内存足够容纳所有数组的情况,省去了文件IO,速度最快。
内容的提问来源于stack exchange,提问作者Elena Zherdeva
相关产品推荐
相关产品推荐

