Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从Tensor流中的文件队列访问文件名_Python_Tensorflow - Fatal编程技术网

Python 从Tensor流中的文件队列访问文件名

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”的文件,标签文件如下所示:

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查找文件的位置也需要时间

好的,太好了,这正是我需要的!我没有想到在python中只匹配这两个文件,然后预先将其洗牌——我只是尝试使用CIFAR教程中的代码加载文件,然后再洗牌。实际上我只是尝试了一下,我觉得我的文件名列表太大了。使用此代码时,它只是挂起,但在减少列表中的元素数时,它会起作用。顺便说一句,这里有87000个文件。有趣的是,它不应该挂起来,真的。您是否增加了randomshufflequeue max,使其足够大,以处理您放入其中的内容的数量?我要警告的是,我从未尝试过这么大的随机洗牌队列。:)如果您想节省内存,可以将文件重写为csv,使用连接到csv解码器的textlinereader,然后将其放入队列,并使用queuerunner保持其运行。不过,只有1MB的文件名需要大量的工作。哦,我没有意识到我需要的容量与文件数量一样大。我想它会等到足够多的人排队后再添加更多。这似乎是可行的,但我仍然有一个问题,那就是一旦RandomShuffleQueue吐出文件名,如何读取实际文件。似乎我需要另一个队列对象将结果排入队列,只将文件名排入队列以输入到一个完整的文件阅读器中,对吗?哦,天哪,这正是
tf.read\u file()
的目的。我怎么从来没见过这个!?这种读入标签的框架非常适合我的代码,我的代码也使用
tf.WholeFileReader
读入图像文件名,但是,用户必须记住运行
sess.run(标签排队)
在开始培训之前,否则程序将挂起并等待排队操作发生。我试图使用与您的代码相同的想法,但无法使标签与图像保持同步。