Python 从Tensor流中的文件队列访问文件名
我有一个图像目录,还有一个单独的文件,将图像文件名与标签匹配。因此,图像目录包含类似“train/001.jpg”的文件,标签文件如下所示:Python 从Tensor流中的文件队列访问文件名,python,tensorflow,Python,Tensorflow,我有一个图像目录,还有一个单独的文件,将图像文件名与标签匹配。因此,图像目录包含类似“train/001.jpg”的文件,标签文件如下所示: train/001.jpg 1 train/002.jpg 2 ... 通过从文件名创建文件队列,我可以轻松地从Tensor Flow中的图像目录加载图像: filequeue = tf.train.string_input_producer(filenames) reader = tf.WholeFileReader() img = reader.re
train/001.jpg 1
train/002.jpg 2
...
通过从文件名创建文件队列,我可以轻松地从Tensor Flow中的图像目录加载图像:
filequeue = tf.train.string_input_producer(filenames)
reader = tf.WholeFileReader()
img = reader.read(filequeue)
但是我不知道如何将这些文件与标签文件中的标签进行耦合。似乎我在每一步都需要访问队列中的文件名。有办法得到它们吗?此外,一旦我有了文件名,我需要能够查找由文件名键入的标签。标准Python字典似乎不起作用,因为这些计算需要在图形的每一步进行。鉴于您的数据不太大,无法将文件名列表作为Python数组提供,我建议您只使用Python进行预处理。创建文件名和标签的两个列表(相同顺序),并将它们插入RandomShuffeQueue或队列,然后从中退出队列。如果您想要字符串输入生成器的“无限循环”行为,可以在每个历元开始时重新运行“排队” 一个非常有趣的例子:
import tensorflow as tf
f = ["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8"]
l = ["l1", "l2", "l3", "l4", "l5", "l6", "l7", "l8"]
fv = tf.constant(f)
lv = tf.constant(l)
rsq = tf.RandomShuffleQueue(10, 0, [tf.string, tf.string], shapes=[[],[]])
do_enqueues = rsq.enqueue_many([fv, lv])
gotf, gotl = rsq.dequeue()
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
tf.train.start_queue_runners(sess=sess)
sess.run(do_enqueues)
for i in xrange(2):
one_f, one_l = sess.run([gotf, gotl])
print "F: ", one_f, "L: ", one_l
关键是,当您执行
排队
时,您有效地将文件名/标签对排队,这些对由出列
返回
我首先洗牌了文件名,并用Python将标签与之匹配:
np.random.shuffle(filenames)
labels = [label_dict[f] for f in filenames]
然后,为文件名创建一个字符串\u输入\u生产者,并使用shuffle off,为标签创建一个FIFO:
lv = tf.constant(labels)
label_fifo = tf.FIFOQueue(len(filenames),tf.int32, shapes=[[]])
file_fifo = tf.train.string_input_producer(filenames, shuffle=False, capacity=len(filenames))
label_enqueue = label_fifo.enqueue_many([lv])
然后,为了读取图像,我可以使用全文件阅读器,为了获得标签,我可以将fifo排在队列中:
reader = tf.WholeFileReader()
image = tf.image.decode_jpeg(value, channels=3)
image.set_shape([128,128,3])
result.uint8image = image
result.label = label_fifo.dequeue()
并按如下方式生成批次:
min_fraction_of_examples_in_queue = 0.4
min_queue_examples = int(num_examples_per_epoch *
min_fraction_of_examples_in_queue)
num_preprocess_threads = 16
images, label_batch = tf.train.shuffle_batch(
[result.uint8image, result.label],
batch_size=FLAGS.batch_size,
num_threads=num_preprocess_threads,
capacity=min_queue_examples + 3 * FLAGS.batch_size,
min_after_dequeue=min_queue_examples)
您可以利用tf.py_func()
实现从文件路径到标签的映射
files = gfile.Glob(data_pattern)
filename_queue = tf.train.string_input_producer(
files, num_epochs=num_epochs, shuffle=True) # list of files to read
def extract_label(s):
# path to label logic for cat&dog dataset
return 0 if os.path.basename(str(s)).startswith('cat') else 1
def read(filename_queue):
key, value = reader.read(filename_queue)
image = tf.image.decode_jpeg(value, channels=3)
image = tf.cast(image, tf.float32)
image = tf.image.resize_image_with_crop_or_pad(image, width, height)
label = tf.cast(tf.py_func(extract_label, [key], tf.int64), tf.int32)
label = tf.reshape(label, [])
training_data = [read(filename_queue) for _ in range(num_readers)]
...
tf.train.shuffle_batch_join(training_data, ...)
我用了这个:
filename = filename.strip().decode('ascii')
另一个建议是以格式保存数据。在这种情况下,您可以将所有图像和所有标签保存在同一个文件中。对于大量文件,它提供了许多优势:
- 可以在同一位置存储数据和标签
- 数据分配在一个位置(无需记住各种目录)
- 如果有许多文件(图像),打开/关闭文件会很耗时。从ssd/hdd查找文件的位置也需要时间
tf.read\u file()
的目的。我怎么从来没见过这个!?这种读入标签的框架非常适合我的代码,我的代码也使用tf.WholeFileReader
读入图像文件名,但是,用户必须记住运行sess.run(标签排队)
在开始培训之前,否则程序将挂起并等待排队操作发生。我试图使用与您的代码相同的想法,但无法使标签与图像保持同步。