Проблема с тонкой настройкой inceptionv3 в тонких пакетах записей tensorflow и tf

Я пытаюсь настроить модель inceptionv3, используя тонкую библиотеку tensorflow. Я не могу понять некоторые вещи, когда пишу для него код. Я попытался прочитать исходный код (нет надлежащей документации) и понял несколько вещей, и я могу настроить его и сохранить контрольную точку. Вот шаги, которые я выполнил: 1. Я создал tf.record для своих обучающих данных, и это нормально, теперь я читаю данные, используя приведенный ниже код.

import tensorflow as tf
import tensorflow.contrib.slim.nets as nets
import tensorflow.contrib.slim as slim
import matplotlib.pyplot as plt
import numpy as np

# get the data and labels here

data_path = '/home/sfarkya/nvidia_challenge/datasets/detrac/train1.tfrecords'

# Training setting
num_epochs = 100
initial_learning_rate = 0.0002
learning_rate_decay_factor = 0.7
num_epochs_before_decay = 5
num_classes = 5980

# load the checkpoint
model_path = '/home/sfarkya/nvidia_challenge/datasets/detrac/inception_v3.ckpt'

# log directory
log_dir = '/home/sfarkya/nvidia_challenge/datasets/detrac/fine_tuned_model'

with tf.Session() as sess:
    feature = {'train/image': tf.FixedLenFeature([], tf.string),
               'train/label': tf.FixedLenFeature([], tf.int64)}

    # Create a list of filenames and pass it to a queue
    filename_queue = tf.train.string_input_producer([data_path], num_epochs=1)

    # Define a reader and read the next record
    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)

    # Decode the record read by the reader
    features = tf.parse_single_example(serialized_example, features=feature)

    # Convert the image data from string back to the numbers
    image = tf.decode_raw(features['train/image'], tf.float32)

    # Cast label data into int32
    label = tf.cast(features['train/label'], tf.int32)

    # Reshape image data into the original shape
    image = tf.reshape(image, [128, 128, 3])

    # Creates batches by randomly shuffling tensors
    images, labels = tf.train.shuffle_batch([image, label], batch_size=64, capacity=128, num_threads=2,
                                            min_after_dequeue=64)

Теперь я дорабатываю модель с помощью slim, и это код.

  init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
    sess.run(init_op)

    # Create a coordinator and run all QueueRunner objects
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)

    # load model

    # load the inception model from the slim library - we are using inception v3
    #inputL = tf.placeholder(tf.float32, (64, 128, 128, 3))

    img, lbl = sess.run([images, labels])
    one_hot_labels = slim.one_hot_encoding(lbl, num_classes)

    with slim.arg_scope(slim.nets.inception.inception_v3_arg_scope()):
        logits, inceptionv3 = nets.inception.inception_v3(inputs=img, num_classes=5980, is_training=True,
                                                          dropout_keep_prob=.6)

    # Restore convolutional layers:

    variables_to_restore = slim.get_variables_to_restore(exclude=['InceptionV3/Logits', 'InceptionV3/AuxLogits'])
    init_fn = slim.assign_from_checkpoint_fn(model_path, variables_to_restore)

    # loss function
    loss = tf.losses.softmax_cross_entropy(onehot_labels=one_hot_labels, logits = logits)
    total_loss = tf.losses.get_total_loss()

    # train operation
    train_op = slim.learning.create_train_op(total_loss + loss, optimizer= tf.train.AdamOptimizer(learning_rate=1e-4))

    print('Im here')
    # Start training.
    slim.learning.train(train_op, log_dir, init_fn=init_fn, save_interval_secs=20, number_of_steps= 10)

Теперь у меня есть несколько вопросов по коду, который я никак не могу понять. Как только код достигает slim.learning.train, я не вижу, чтобы что-то печаталось, это обучение, я вижу в журнале. Теперь 1. Как указать количество эпох в коде? Прямо сейчас он выполняется шаг за шагом, каждый шаг имеет размер_пакета = 64.
2. Как мне убедиться, что в коде tf.train.shuffle_batch я не повторяю свои изображения, а обучение по всему набору данных? 3. Как я могу распечатать значения потерь во время обучения?


person talos1904    schedule 29.03.2018    source источник


Ответы (1)


Вот ответы на ваши вопросы.

  1. Вы не можете указывать эпохи напрямую slim.learning.train. Вместо этого вы указываете количество пакетов в качестве аргумента. Он называется number_of_steps. Он используется для установки операции с именем should_stop_op на строка 709. Я предполагаю, что вы знаете, как преобразовать количество эпох в партии.

  2. Я не думаю, что функция shuffle_batch будет повторять изображения, потому что внутри она использует RandomShuffleQueue. Согласно этому ответу, RandomShuffleQueue ставит в очередь элементы, используя фоновый поток, как:

    • While size(queue) < capacity:
      • Add an element to the queue

Он удаляет элементы из очереди как:

  • While the number of elements dequeued < batch_size:
    • Wait until the size(queue) >= min_after_dequeue + 1 elements.
    • Случайным образом выберите элемент из очереди, удалите его из очереди и добавьте в выходной пакет.

Так что, на мой взгляд, очень мало шансов, что элементы будут повторяться, потому что в операции dequeuing выбранный элемент удаляется из очереди. Так что это выборка без замены.

Будет ли создаваться новая очередь для каждой эпохи?

В tf.train.shuffle_batch вводятся тензоры image и label, которые в конечном итоге исходят из filename_queue. Если эта очередь бесконечно создает имена файлов TFRecord, то я не думаю, что новая очередь будет создана shuffle_batch. Вы также можете создать игрушечный код, например этот, чтобы понять, как работает shuffle_batch.

Переходя к следующему пункту, как тренироваться на всем наборе данных? В вашем коде следующая строка получает список имен файлов TFRecord.

filename_queue = tf.train.string_input_producer([data_path], num_epochs=1)

Если filename_queue охватывает все имеющиеся у вас TFRecords, то вы наверняка тренируетесь на всем наборе данных. Теперь, как перетасовать весь набор данных, это другой вопрос. Как упоминалось здесь @mrry, нет поддержки (пока, насколько мне известно) для перетасовки нехватка памяти для наборов данных. Поэтому лучший способ — подготовить множество осколков вашего набора данных, чтобы каждый осколок содержал около 1024 примеров. Перемешайте список имен файлов TFRecord следующим образом:

filename_queue = tf.train.string_input_producer([data_path], shuffle=True, capacity=1000)

Обратите внимание, что я удалил аргумент num_epochs = 1 и установил shuffle=True. Таким образом, он будет бесконечно создавать перетасованный список имен файлов TFRecord. Теперь в каждом файле, если вы используете tf.train.shuffle_batch, вы получите почти равномерную перетасовку. По сути, по мере того, как количество примеров в каждом сегменте стремится к 1, ваша перетасовка будет становиться все более и более равномерной. Мне нравится не устанавливать num_epochs, а вместо этого завершать обучение, используя аргумент number_of_steps, упомянутый ранее.

  1. Чтобы распечатать значения потерь, вы, вероятно, могли бы просто отредактировать ссылку ="nofollow noreferrer">training.py и введите logging.info('total loss = %f', total_loss). Я не знаю, есть ли более простой способ. Другой способ без изменения кода — просмотреть сводки в Tensorboard.

Есть очень полезные статьи о том, как просматривать сводки в Tensorboard, включая ссылку в конце этого ответа. Как правило, вам нужно сделать следующие вещи.

  1. Создайте объект summary.
  2. Запишите интересующие вас переменные в summary.
  3. Объединить все отдельные сводки.
  4. Создайте summary op.
  5. Создайте средство записи сводного файла.
  6. Пишите резюме на протяжении всего обучения с желаемой периодичностью.

Теперь шаги 5 и 6 уже выполняются автоматически, если вы используете slim.learning.train.

Для первых 4 шагов вы можете проверить файл train_image_classifier.py< /а>. В строке 472 показано, как создать объект summaries. Строки 490, 512 и 536 записывают соответствующие переменные в summaries. Строка 549 ​​объединяет все сводки, а строка 553 создает операцию. Вы можете передать эту операцию slim.learning.train, а также указать, как часто вы хотите писать сводки. На мой взгляд, ничего кроме потерь, тотальных потерь, точности и скорости обучения в аннотации не пишите, если только не хотите заниматься конкретной отладкой. Если писать гистограммы, то для таких сетей, как ResNet-50, файл тензорной доски мог загружаться десятки часов (мой файл тензорной доски когда-то был 28 ГБ, на загрузку которого ушло 12 часов прогресса за 6 дней!). Кстати, вы можете использовать файл train_image_classifier.py для тонкой настройки, и вы пропустите большинство шагов, описанных выше. Тем не менее, я предпочитаю это, поскольку вы узнаете много вещей.

См. раздел запуск tensorboard, чтобы узнать, как просмотреть ход выполнения в браузере.

Дополнительные замечания:

  • Вместо минимизации total_loss + loss вы можете сделать следующее:

    loss = tf.losses.softmax_cross_entropy(onehot_labels=one_hot_labels, logits = logits)
    tf.losses.add_loss(loss)
    total_loss = tf.losses.get_total_loss()
    train_op = slim.learning.create_train_op(total_loss, optimizer=tf.train.AdamOptimizer(learning_rate=1e-4))
    
  • Я обнаружил, что этот пост очень полезен, когда я изучал Tensorflow.

person Autonomous    schedule 29.03.2018
comment
Спасибо за такой подробный ответ, я могу решить большинство своих сомнений. У меня есть еще один вопрос. Предположим, я вычисляю шаги, соответствующие 2 эпохам. Теперь он автоматически создаст новую очередь для всего набора данных для второй эпохи? как в первую эпоху весь набор данных удаляется из очереди? - person talos1904; 30.03.2018
comment
Кроме того, чтобы увидеть на тензорной доске, что нужно делать? Я не создаю сводку переменных, как я буду использовать тензорную доску для просмотра потерь? - person talos1904; 30.03.2018