web-dev-qa-db-ja.com

「model.fit_generator」で使用されるパラメーター「max_q_size」は何ですか?

inputsリストとtargetsリストに単一の項目のみを含むTuple(inputs, targets)を生成する単純なジェネレーターを作成しました。基本的に、一度に1つのサンプルアイテムのデータセットをクロールします。

このジェネレーターを以下に渡します。

  model.fit_generator(my_generator(),
                      nb_Epoch=10,
                      samples_per_Epoch=1,
                      max_q_size=1  # defaults to 10
                      )

私はそれを得る:

  • nb_Epochは、トレーニングバッチが実行される回数です。
  • samples_per_Epochは、エポックごとにトレーニングされたサンプルの数です。

しかし、max_q_sizeのために、そしてなぜそれがデフォルトで10になるのでしょうか?ジェネレーターを使用する目的は、データセットを適切なチャンクにバッチ処理することだと思ったのに、なぜ追加のキューが必要なのでしょうか?

23
Ray

これは、ジェネレーターからサンプルを「プリキャッシュ」するために使用される内部トレーニングキューの最大サイズを定義するだけです。キューの生成中に使用されます

def generator_queue(generator, max_q_size=10,
                    wait_time=0.05, nb_worker=1):
    '''Builds a threading queue out of a data generator.
    Used in `fit_generator`, `evaluate_generator`, `predict_generator`.
    '''
    q = queue.Queue()
    _stop = threading.Event()

    def data_generator_task():
        while not _stop.is_set():
            try:
                if q.qsize() < max_q_size:
                    try:
                        generator_output = next(generator)
                    except ValueError:
                        continue
                    q.put(generator_output)
                else:
                    time.sleep(wait_time)
            except Exception:
                _stop.set()
                raise

    generator_threads = [threading.Thread(target=data_generator_task)
                         for _ in range(nb_worker)]

    for thread in generator_threads:
        thread.daemon = True
        thread.start()

    return q, _stop

言い換えれば、あなたはジェネレーターから直接与えられた最大容量までキューを埋めるスレッドを持っている一方で、(例えば)トレーニングルーチンはその要素を消費します(そして時々完了を待ちます)

 while samples_seen < samples_per_Epoch:
     generator_output = None
     while not _stop.is_set():
         if not data_gen_queue.empty():
             generator_output = data_gen_queue.get()
             break
         else:
             time.sleep(wait_time)

そして、なぜデフォルトの10ですか?ほとんどのデフォルトのような特別な理由はありません-それは理にかなっていますが、異なる値を使用することもできます。

このような構造は、作成者が実行に時間がかかる可能性のある高価なデータジェネレーターについて考えたことを示唆しています。たとえば、ジェネレーターコールでネットワーク経由でデータをダウンロードすることを検討してください。次に、効率のために、またネットワークエラーなどに強いように、いくつかの次のバッチをプリキャッシュし、次のバッチを並行してダウンロードするのが理にかなっています。

31
lejlot