2016-03-01 2 views
11

я следующая ситуация:TensorFlow: Восстановление переменных из из нескольких контрольных точек

  • у меня есть 2 модель написана в 2 отдельных сценариях:

  • Модели А состоит из переменных a1, a2 и a3 , и записывается в A.py

  • Модель B состоит из переменных b1, b2, и b3, и написано в B.py

В каждом из A.py и B.py, у меня есть tf.train.Saver, сохраняющий блокпост всех локальных переменных, и давайте называть файлы контрольных точек ckptA и ckptB соответственно ,

Теперь я хочу сделать модель C, которая использует a1 и b1. Я могу сделать так, чтобы точно такое же имя переменной для a1 использовалось как в A, так и в C с помощью var_scope (и то же самое для b1).

Вопрос заключается в том, как я мог бы загрузить a1 и b1 из ckptA и ckptB в модели C? Например, будет ли следующая работа?

saver.restore(session, ckptA_location) 
saver.restore(session, ckptB_location) 

Возможно, возникнет ошибка, если вы попытаетесь восстановить один и тот же сеанс дважды? Хотелось бы пожаловаться на то, что для дополнительных переменных нет выделенных «слотов» (b2, b3, , , a3), или это просто восстановит переменные, которые он может, и только жалуется, есть ли какие-то другие переменные в C, которые неинициализированы?

Я пытаюсь написать некоторый код, чтобы проверить это сейчас, но я хотел бы увидеть канонический подход к этой проблеме, потому что это часто встречается при попытке повторно использовать некоторые предварительно подготовленные веса.

Спасибо!

ответ

16

Вы должны получить tf.errors.NotFoundError, если вы попытались использовать заставку (по умолчанию представляющую все шесть переменных) для восстановления с контрольной точки, которая не содержит всех переменных, которые представляет заставка. (Обратите внимание, однако, что вы можете называть Saver.restore() несколько раз в том же сеансе для любого подмножества переменных, если все необходимые переменные присутствуют в соответствующем файле.)

Канонический подход заключается в определении два отдельных tf.train.Saver экземпляров, охватывающих каждое подмножество переменных, которое полностью содержится в одной контрольной точке. Например:

saver_a = tf.train.Saver([a1]) 
saver_b = tf.train.Saver([b1]) 

saver_a.restore(session, ckptA_location) 
saver_b.restore(session, ckptB_location) 

В зависимости от того, как построен ваш код, если у вас есть указатели на объекты, называемые tf.Variablea1 и b1 в локальной области видимости, вы можете перестать читать здесь.

С другой стороны, если переменные a1 и b1 определены в отдельных файлах, вам может потребоваться сделать что-то творческое для получения указателей на эти переменные. Несмотря на то, что это не идеал, то, что люди обычно делают, чтобы использовать общий префикс, например, следующим образом (при условии, что имена переменных "a1:0" и "b1:0" соответственно):

saver_a = tf.train.Saver([v for v in tf.all_variables() if v.name == "a1:0"]) 
saver_b = tf.train.Saver([v for v in tf.all_variables() if v.name == "b1:0"]) 

Одно последнее замечание: вы не должны делать героические усилия по обеспечению того, чтобы переменные имели одинаковые имена в A и C. Вы можете передать словарь name-to-Variable в качестве первого аргумента в конструктор tf.train.Saver и тем самым переназначить имена в файле контрольной точки на Variable объектов в вашем коде. Это помогает, если A.py и B.py имеют аналогично названные переменные, или если в C.py вы хотите упорядочить код модели из этих файлов в tf.name_scope().

+0

первые фрагменты кода относятся к материалам, которые должны быть написаны на C.py правильно? и он написан в конце определения графа, где a1 a2 a3 и b1 b2 b3 определены в C.py? Мой первоначальный вопрос был в том, что если только a1 и b1 определены в C и ничего больше? –

+0

Извинения - обновленный ответ, чтобы покрыть этот случай. Если вы переопределите переменные на C.py, тогда все будет намного проще! – mrry

+0

Еще одно продолжение: когда мы выполняем это утверждение «saver_a.restore (session, ckptA_location)» saver_a создается с помощью единственной переменной [a1] и ничего больше, но ckptA содержит значения для всех a1, a2, a3. Вы говорите, что это не проблема, так как заставка будет искать только a1 в ckpt и восстанавливать a1 до модели C, игнорируя a2 и a3? И последний вопрос: a1 в C будет идентифицироваться как a1 в ckptA, если оба a1 создаются (в C и A) с тем же именем? –

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