В Tensorflow 2 API обнаружения объектов разделил обучение и проверку на два разных процесса. Более того, они должны работать одновременно, отслеживая тот же каталог, где сохранены контрольные точки. В этой статье объясняется прием, позволяющий пользователям запускать проверку как истинный постпроцесс, который, насколько мне известно, недоступен в текущей реализации API обнаружения объектов.
Оглавление
1). By default, how is Training and Validation supposed to intertwine? 2). The Pros & Cons of the aforementioned approach 3). Make Validation a true Post-process 4). Verify 5). Conclusion
Как по умолчанию обучение и валидация должны переплетаться?
Предполагая, что все настроено правильно, от подготовки данных в виде TFRecord до загрузки моделей репозитория Git, компиляции прототипов, установки setup.py
API Tensorflow Object Detection и настройки pipeline.config
, затем выполняется процесс обучения, с помощью команды:
python model_main_tf2.py \ --pipeline_config_path="some_path/pipeline.config" \ --model_dir="some_path" \ --checkpoint_every_n=100 \ --num_train_steps=1000 \ --alsologtostderr
В то же время запускается проверка следующим образом:
python model_main_tf2.py \ --pipeline_config_path="some_path/pipeline.config" \ --model_dir="some_path" \ --checkpoint_dir="some_path" \ --eval_timeout=60
Всякий раз, когда обучение сохраняет файл контрольной точки, например, ckpt-1
(ckpt-1.data-00000-of-00001
и ckpt-1.index
), проверка обнаруживает, принимает файл, начинает проверку и сохраняет результат, например, как events.out.tfevents.1645005144.6403b50c5b59.912.0.v2
. Эти процессы продолжаются до тех пор, пока обучение не будет завершено, а затем истечет время проверки (нет новой контрольной точки).
Плюсы и минусы вышеупомянутого подхода
Читатель может иметь другую схему настройки ресурсов для обучения и проверки. Например, у них может быть один или два мощных ПК с большим количеством CPU/GPU. Но в моем случае используется Google Colab. К сожалению, блокнот CoLab выполняет ячейки одну за другой; в одной ячейке, одна команда за другой, например. !python model_main_tf2.py…
. При выполнении проверки после обучения проверка будет учитывать только последнюю контрольную точку, как показано ниже:
# 1). module "model_main_tf2.py", line 81. if FLAGS.checkpoint_dir: # if checkpoint_dir argument is used. model_lib_v2.eval_continuously(... # 2). module "model_lib_v2.py", function eval_continuously(), line 1136: for latest_checkpoint in tf.train.checkpoints_iterator( checkpoint_dir, timeout=timeout, min_interval_secs=wait_interval): # 3). module "checkpoint_utils.py", function checkpoints_iterator(), line 194: while True: new_checkpoint_path = wait_for_new_checkpoint( checkpoint_dir, checkpoint_path, timeout=timeout) # 4). same module, function wait_for_new_checkpoint(), line 139: while True: checkpoint_path = checkpoint_management.latest_checkpoint(checkpoint_dir)
Может быть несколько трюков для одновременной работы нескольких ячеек, таких как ipyparallel
(но я не разбираюсь в этом методе и не уверен, что он вообще может работать с CoLab).
Насколько мне известно, плюсы и минусы обучения и проверки параллельного выполнения):
- Плюсы:
- Нет необходимости хранить все контрольные точки (в моем случае одна контрольная точка стоит 42,5 МБ). Действительно, Training поддерживает только последние 7 контрольных точек. Эта конфигурация не может быть изменена извне.
- В сочетании с Tensorboard в режиме реального времени можно остановить обучение раньше, если, например.loss
уже существенно не уменьшается. - Минусы:
— ресурсы должны быть разделены между обучением и проверкой, что может замедлить обучение. Проверка может также использовать GPU (Рисунок [1]).
- В процессе проверки учитывается только последняя контрольная точка. В некоторых случаях, например. большой набор проверок и более детальныйcheckpoint_every_n
, проверка может пропустить некоторые контрольные точки, что приведет к менее детализированной визуализации для данных проверки.
- Сложность: в CoLab непросто запустить несколько ячеек параллельно (т. Обучение, одна ячейка для проверки).
Следовательно, может возникнуть необходимость в проведении процесса валидации после процесса обучения. Это было бы особенно удобно в случае использования CoLab.
Сделайте валидацию настоящим постпроцессом
Код для проверки, а именно: прием контрольной точки, восстановление модели, проверка ее на соответствие набору проверки, должен быть разбросан по нескольким местам в моделях репозитория Git. Сборка всех частей может занять много времени, а также может привести к возникновению новых тонких проблем.
Безопасный и быстрый подход должен состоять в том, чтобы сохранить текущий способ выполнения, т. е. вызвать model_main_tf2.py
с аргументом checkpoint_dir
, но изменить несколько мест в коде, где вместо постоянного наблюдения за каталогом в поисках нового Checkpoint, он будет просто перечислять все контрольные точки в каталоге и обрабатывать каждую из них как если бы каждая из них была единственной последней контрольной точкой. Благодаря этому сохраняется правильность всего процесса проверки. Каждый созданный артефакт должен быть затем хорошо отформатирован и доступен, например. Тензорборд.
Во-первых, в тренировке сохраняются только последние 7 контрольных точек:
# 1). module "model_main_tf2.py", line 105: with strategy.scope(): model_lib_v2.train_loop( pipeline_config_path=FLAGS.pipeline_config_path, model_dir=FLAGS.model_dir, train_steps=FLAGS.num_train_steps, use_tpu=FLAGS.use_tpu, checkpoint_every_n=FLAGS.checkpoint_every_n, record_summaries=FLAGS.record_summaries) # 2). module "model_lib_v2.py", function train_loop(), line 443: def train_loop( pipeline_config_path, model_dir, config_override=None, train_steps=None, use_tpu=False, save_final_config=False, checkpoint_every_n=1000, checkpoint_max_to_keep=7, record_summaries=True, performance_summary_exporter=None, num_steps_per_iteration=NUM_STEPS_PER_ITERATION, **kwargs):
К сожалению, этот аргумент нельзя изменить извне. Лучше всего добавить checkpoint_max_to_keep=some_big_number
к вызову train_loop()
в модуле model_main_tf2.py
(модуль, используемый для обучения и проверки).
Далее в модуле model_lib_v2.py
, функция eval_continuously()
, строка 1136:
for latest_checkpoint in tf.train.checkpoints_iterator( checkpoint_dir, timeout=timeout, min_interval_secs=wait_interval): ... ckpt.restore(latest_checkpoint).expect_partial()
Учитывая переменную latest_checkpoint
, это строка, описывающая полный путь к последнему файлу контрольной точки, например absolute_path/ckpt-33
. После определения пути он переходит к проверке, т. е. восстанавливает модель с контрольной точкой, сохраненной на пути, а затем начинает проверку.
Если мы заменим использование tf.train.checkpoints_iterator()
каким-нибудь кодом, который перечисляет все контрольные точки, и передаст каждую в тело цикла for, все должно происходить как обычно! Правильность будет сохранена. Вот что я сделал: заменил итератор кодом, выделенным жирным шрифтом. (кроме того, нужны дополнительные библиотеки (regex
, glob
) и служебная функция (natural_sort
))
import regex as re import glob def natural_sort(l): convert = lambda text: int(text) if text.isdigit() else text.lower() alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] return sorted(l, key = alphanum_key) for latest_checkpoint in natural_sort(list(set(map(lambda n: n[:n.index(".")], glob.glob(f"{checkpoint_dir}/ckpt-*.*"))))):
И последнее, но не менее важное: все вышеперечисленные изменения должны иметь место после клонирования моделей Github Repo и до выполнения !cp object_detection/packages/tf2/setup.py .
и !pip install .
.
Проверять
Я думаю, что аргумент checkpoint_every_n
должен делиться на 100, то есть NUM_STEPS_PER_ITERATION
. Причину можно увидеть здесь: после одной итерации Обучение пытается сохранить контрольную точку только в том случае, если только накопленных шагов больше checkpoint_every_n
. Делая его делящимся на 100, мы можем легко оценить, сколько контрольных точек будет сгенерировано, учитывая num_train_steps
.
Обучение теперь начинается первым. После завершения следует проверка. Все последовательно. В конце, внутри checkpoint_dir
, будут папки eval
и train
, содержащие данные для визуализации с помощью Tensorboard:
tensorboard --logdir=checkpoint_dir
Заключение
Мы узнали, как сделать валидацию настоящим постпроцессом для Tensorflow Object-Detection API. Этот трюк, по крайней мере, полезен в моем случае: простая настройка в CoLab для обучения и проверки выполняется последовательно.
P.s. Если эта статья окажется полезной, рассмотрите возможность подписки на мой Medium. 😋