2016-05-02 1 views
13

Я построил простой генератор, который дает tuple(inputs, targets) только с одним элементом в списках inputs и targets - в основном обход набора данных, по одному образцу за раз.В методе Keras model.fit_generator(), для чего используется управляемый параметром очереди генератор «max_q_size»?

я прохожу этот генератор в:

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

Это просто определяет максимальный размер внутренней тренировочной очереди, которая используется для «предварительной проверки» ваших образцов из генератора. Он используется в процессе генерации очередей

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? Никакой конкретной причины, как и большинство дефолтов, - это просто имеет смысл, но вы можете использовать и другие значения.

Конструкция, подобная этому, предполагает, что авторы думали о дорогих генераторах данных, которые могут потребовать времени для прослушивания. Например, рассмотрите возможность загрузки данных по сети в вызове генератора - тогда имеет смысл предусмотреть некоторые последующие партии и загрузить следующие параллельно, ради эффективности и быть надежными для сетевых ошибок и т. Д.

+2

А, я вижу, так что в идеале вы никогда не прекращаете тренировку, ожидая генератора, чтобы генерировать результаты - у вас есть поток, заполняющий очередь в фоновом режиме сзади, в то время как модель тренируется по ранее выбранным образцам. – Ray

+1

Да, это идеальный сценарий. Это, очевидно, зависит от размера очереди и общего дизайна системы. – lejlot