2017-02-11 2 views
2

Я знаю, как использовать входной трубопровод для чтения данных из файлов:Использование несколько входных трубопроводов в TensorFlow

input = ... # Read from file 
loss = network(input) # build a network 
train_op = ... # Using SGD or other algorithms to train the network. 

Но как я могу переключаться между несколькими входными трубопроводами? Скажем, если я хочу обучить сеть на 1000 партий на тренировочном наборе из учебного конвейера, то подтвердите его на основании проверки, установленном из другого конвейера, затем продолжите обучение, затем выполните проверку, затем тренировку ... и т. Д.

Это легко реализовать с помощью feed_dict. Я также знаю, как использовать контрольные точки для достижения этого, как в примере cifar-10. Но это довольно громоздко: мне нужно выгрузить модель на диск, а затем снова прочитать ее с диска.

Могу ли я просто переключаться между двумя входными конвейерами (один для данных обучения, один для данных проверки), чтобы достичь этого? Чтение 1000 партий из очереди данных обучения, затем несколько пакетов из очереди данных проверки и т. Д. Если это возможно, как это сделать?

ответ

2

Не уверен, что это именно то, что вы ищете, но я занимаюсь обучением и проверкой в ​​одном и том же коде в двух отдельных циклах. Мой код считывает числовые и строковые данные из файлов .CSV, а не изображений. Я читаю из двух отдельных файлов CSV, один для обучения и один для проверки. Я уверен, что вы можете обобщить его, чтобы читать из двух «наборов» файлов, а не только отдельных файлов, поскольку код есть.

Вот фрагменты кода на тот случай, если это поможет. Обратите внимание, что этот код сначала считывает все как строку, а затем преобразует необходимые ячейки в поплавки, только учитывая мои собственные требования. Если ваши данные чисто числовые, вы должны просто установить по умолчанию поплавки, и все должно быть проще. Кроме того, есть пара строк, которые отбрасывают Weights and Biases в CSV-файл и сериализуют их в файл контрольной точки TF, в зависимости от того, какой вы предпочитаете.

 #first define the defaults: 
     rDefaults = [['a'] for row in range((TD+TS+TL))] 

    # this function reads line-by-line from CSV and separates cells into chunks: 
     def read_from_csv(filename_queue): 
      reader = tf.TextLineReader(skip_header_lines=False) 
      _, csv_row = reader.read(filename_queue) 
      data = tf.decode_csv(csv_row, record_defaults=rDefaults) 
      dateLbl = tf.slice(data, [0], [TD]) 
      features = tf.string_to_number(tf.slice(data, [TD], [TS]), tf.float32) 
      label = tf.string_to_number(tf.slice(data, [TD+TS], [TL]), tf.float32) 
      return dateLbl, features, label 

    #this function loads the above lines and spits them out as batches of N: 
     def input_pipeline(fName, batch_size, num_epochs=None): 
      filename_queue = tf.train.string_input_producer(
       [fName], 
       num_epochs=num_epochs, 
       shuffle=True) 
      dateLbl, features, label = read_from_csv(filename_queue) 
      min_after_dequeue = 10000 
      capacity = min_after_dequeue + 3 * batch_size # max of how much to load into memory 
      dateLbl_batch, feature_batch, label_batch = tf.train.shuffle_batch(
       [dateLbl, features, label], 
       batch_size=batch_size, 
       capacity=capacity, 
       min_after_dequeue=min_after_dequeue) 
      return dateLbl_batch, feature_batch, label_batch 

    # These are the TRAINING features, labels, and meta-data to be loaded from the train file:  
     dateLbl, features, labels = input_pipeline(fileNameTrain, batch_size, try_epochs) 
    # These are the TESTING features, labels, and meta-data to be loaded from the test file: 
     dateLblTest, featuresTest, labelsTest = input_pipeline(fileNameTest, batch_size, 1) # 1 epoch here regardless of training 

    # then you define the model, start the session, blah blah  

    # fire up the queue:   
      coord = tf.train.Coordinator() 
      threads = tf.train.start_queue_runners(coord=coord) 

    #This is the TRAINING loop: 
try:    
       while not coord.should_stop(): 

        dateLbl_batch, feature_batch, label_batch = sess.run([dateLbl, features, labels])  

        _, acc, summary = sess.run([train_step, accuracyTrain, merged_summary_op], feed_dict={x: feature_batch, y_: label_batch, 
       keep_prob: dropout, 
       learning_rate: lRate}) 

      except tf.errors.OutOfRangeError: # (so done reading the file(s)) 

    # by the way, this dumps weights and biases into a CSV file, since you asked for that 
       np.savetxt(fPath + fIndex + '_weights.csv', sess.run(W), 
    # and this serializes weight and biases into the TF-formatted protobuf: 
     #  tf.train.Saver({'varW': W, 'varB': b}).save(sess, fileNameCheck) 

      finally: 
       coord.request_stop() 

    # now re-start the runners for the testing file: 
      coord = tf.train.Coordinator() 
      threads = tf.train.start_queue_runners(coord=coord) 

      try: 

       while not coord.should_stop(): 
    # so now this line reads features, labels, and meta-data, but this time from the training file:     
        dateLbl_batch, feature_batch, label_batch = sess.run([dateLblTest, featuresTest, labelsTest]) 

        guessY = tf.argmax(y, 1).eval({x: feature_batch, keep_prob: 1}) 
        trueY = tf.argmax(label_batch, 1).eval() 

        accuracy = round(tf.reduce_mean(tf.cast(tf.equal(guessY, trueY), tf.float32)).eval(), 2) 

      except tf.errors.OutOfRangeError: 
       acCumTest /= i 
      finally: 
       coord.request_stop() 


      coord.join(threads) 

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

Также я не уверен, что повторное начало очередей после тренировки - лучший способ пойти, но это работает для меня. Хотелось бы увидеть лучший пример, так как большинство примеров TF используют некоторые встроенные обертки вокруг набора данных MNIST, чтобы пройти обучение за один раз ...

+0

Спасибо! Это действительно полезно! – soloice

+0

Я не понял, что сначала могу оценить входной конвейер, чтобы получить мини-пакет, а затем использовать feed_dict для подачи мини-пакета в свою сеть. В моей предыдущей настройке я напрямую использовал очередь в качестве входных данных! Выбирая, какой входной конвейер оценивается, я могу подать правильную очередь в сеть с помощью feed_dict! Это хороший способ комбинировать feed_dict и входной конвейер! – soloice

+0

Да, я думаю, что это логика наличия заполнителей. Таким образом, вы можете вытащить что-то из очереди, выполнить некоторую работу над ним, а затем «передать» его в остальную часть рабочего процесса через «feed_dict». Помните, что вывод «оценки» - это просто массивный объект массива , поэтому вы можете делать много вещей с ним за пределами TF, например, сохранять файлы и т. д. Возможно, вам понадобится, чтобы выгрузить материал на диск, как вы упомянули в вопросе ... –

Смежные вопросы