Узлы Tensorflow графа обмениваются - PullRequest
6 голосов
/ 05 апреля 2020

Я тренировал модель с тонкой настройкой предварительно обученной модели ssd_mobilenet_v2_coco_2018. Здесь я использовал точно такой же файл pipe.config для обучения, который находится внутри предварительно подготовленной папки ssd_mobilenet_v2_coco_2018. Я только убрал флаг batch_norm_trainable: true и изменил количество классов (4). После обучения модели с помощью моих пользовательских наборов данных с 4 классами я обнаружил, что узлы concat и concat_1 обмениваются друг с другом. Предварительно обученная модель имеет | concat | 1x1917x1x4 |, после обучения она становится | concat | 1x1917x5 | Я прикрепил оба изображения визуализации графика тензорной доски. Первое изображение предварительно обученного графика ssd_mobilenet_v2_coco_2018. enter image description here enter image description here

Обмен узлами можно увидеть в крайнем правом углу изображения. Как и в предварительно обученном графике, Postprocess layer соединяется с concat_1 и Squeeeze соединяется с concat. Но после тренировки график показывает полностью обратное. Как Prosprocess layer соединиться с concat и Squeeeze соединиться с concat_1. Кроме того, я также обнаружил на графике предварительно обученной модели, что Preprocessor принимает входные данные ToFloat, в то время как после обучения на графике в качестве входных данных отображается Preprocessor. Я ввел вход для модели как tfrecords.

1 Ответ

1 голос
/ 14 апреля 2020

Скорее всего, разница не в графике, а просто в именах узлов, то есть узлы concat и concat_1 слева - это те же узлы, что и соотв. concat_1 и concat справа.

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

Возьмите этот пример:

import tensorflow as tf

x = tf.placeholder(tf.float32, (1,), name='x')
y = tf.placeholder(tf.float32, (1,), name='y')
z = tf.placeholder(tf.float32, (1,), name='z')

xy = tf.concat([x, y], axis=0)  # named 'concat'
xz = tf.concat([x, z], axis=0)  # named 'concat_1'

График выглядит так:

enter image description here

Теперь, если мы построим тот же тот же график , но на этот раз создадим xz до xy, мы получим следующий график:

enter image description here

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

Тот факт, что имена изменились для узлов без сохранения состояния, таких как concat, не важен, потому что при загрузке не будут перенаправлены веса сохраненная модель, например. Тем не менее, если стабильность именования важна для вас, вы можете либо дать явные имена своим операциям, либо поместить их в разные области:

xy = tf.concat([x, y], axis=0, name='xy')
xz = tf.concat([x, z], axis=0, name='xz')

enter image description here

Гораздо сложнее c, если переменные имя переключателя. Это одна из причин, по которой tf.get_variable - который заставляет переменные иметь имя и вызывает ошибку при возникновении конфликта имен - был предпочтительным способом работы с переменными в эпоху, предшествующую TF2.

...