4

データセット内のクラスごとに 1 つのシリアル化されたファイルがあります。キューを使用してこれらの各ファイルをロードし、それらを RandomShuffleQueue に配置して、各クラスからサンプルをランダムに組み合わせて取得したいと考えています。このコードはうまくいくと思いました。

この例では、各ファイルに 10 個の例があります。

filenames = ["a", "b", ...]

with self.test_session() as sess:
  # for each file open a queue and get that
  # queue's results. 
  strings = []
  rq = tf.RandomShuffleQueue(1000, 10, [tf.string], shapes=())
  for filename in filenames:
    q = tf.FIFOQueue(99, [tf.string], shapes=())
    q.enqueue([filename]).run()
    q.close().run()
    # read_string just pulls a string from the file
    key, out_string = input_data.read_string(q, IMAGE_SIZE, CHANNELS, LABEL_BYTES)
    strings.append(out_string)

    rq.enqueue([out_string]).run()

  rq.close().run()
  qs = rq.dequeue()
  label, image = input_data.string_to_data(qs, IMAGE_SIZE, CHANNELS, LABEL_BYTES)
  for i in range(11):
    l, im = sess.run([label, image])
    print("L: {}".format(l)

これは 10 回の呼び出しでは正常に機能しますが、11 回目にはキューが空であると表示されます。

これは、これらのキューが動作する対象についての私の誤解によるものだと思います。に 10 個の変数を追加しますがRandomShuffleQueue、これらの各変数はそれ自体がキューからプルされるため、各ファイル キューが空になるまでキューが空にならないと想定しました。

ここで何が間違っていますか?

4

1 に答える 1

3

この質問に対する正しい答えは、ファイルの数、サイズ、サイズの分散方法によって異なります。

あなたの例の差し迫った問題は、rq各 に対して 1 つの要素しか取得しないためfilename in filenames、キューが閉じられることです。を呼び出すたびに の 1 つの要素を消費するfilenamesため、10 個あると推測しています。キューが閉じられているため、これ以上要素を追加できず、操作の 11 番目のアクティブ化は失敗します。rq.dequeue()rqsess.run([label, image])rq.dequeue()

rq.enqueue([out_string])一般的な解決策は、ループで実行し続けるために追加のスレッドを作成する必要があることです。TensorFlow には、QueueRunnerこれを簡素化するために設計されたクラスと、一般的なケースを処理するその他の関数が含まれています。スレッド化とキューのドキュメントでは、それらがどのように使用されるかが説明されています。また、キューを使用してファイルから読み取ることに関する適切な情報もあります。

特定の問題に関しては、これを処理する方法の 1 つは、 (ファイルNごとに) リーダーを作成することです。N次に、要素 (各リーダーから 1 つ) をバッチに入れ、 を使用して一度にバッチを十分な容量のに追加し、クラス間で十分な混合が行われるようにします。を呼び出すと、各ファイルから同じ確率でサンプリングされた要素のバッチが得られます。tf.pack() Nenqueue_manytf.RandomShuffleQueuemin_after_dequeuedequeue_many(k)RandomShuffleQueuek

于 2015-11-19T07:14:17.753 に答える