Python TensorFlow: как перезапустить обучение с помощью оптимизатора и import_meta_graph?
Я пытаюсь перезапустить модельную тренировку в TensorFlow, набрав место, где она остановилась. Я бы хотел использовать недавно добавленный (0.12+, я думаю) import_meta_graph()
, чтобы не восстановить график.
Я видел решения для этого, например. Tensorflow: как сохранить/восстановить модель?, но я столкнулся с проблемами с AdamOptimizer, в частности, я получаю ошибку ValueError: cannot add op with name <my weights variable name>/Adam as that name is already used
. Это можно исправить путем инициализации, но тогда мои значения модели очищаются!
Есть другие ответы и некоторые полные примеры, но они всегда кажутся старше и поэтому не включают новый подход import_meta_graph()
или не имеют оптимизатора без тензора. Самый близкий вопрос, который я мог найти, - tensorflow: сохранение и восстановление сеанса, но окончательного решения четкого разрешения нет, и пример довольно сложный.
В идеале я бы хотел, чтобы простой пример, начинающийся с нуля, останавливался, а затем снова поднимался. У меня есть что-то, что работает (ниже), но также интересно, не хватает ли я чего-то. Неужели я не единственный, кто это делает?
Ответы
Ответ 1
Вот что я получил от чтения документов, других подобных решений, а также проб и ошибок. Это простой автокодер на случайных данных. Если он побежал, то снова побежал, он продолжится с того места, где он остановился (т.е. Функция стоимости при первом запуске идет от ~ 0,5 → 0,3 секунды, начинается ~ 0.3). Если я ничего не пропустил, все сбережения, конструкторы, моделирование, add_to_collection необходимы и в точном порядке, но может быть и более простой способ.
И да, загрузка графика с помощью import_meta_graph
здесь действительно не нужна, поскольку код находится прямо вверху, но это то, что я хочу в своем фактическом приложении.
from __future__ import print_function
import tensorflow as tf
import os
import math
import numpy as np
output_dir = "/root/Data/temp"
model_checkpoint_file_base = os.path.join(output_dir, "model.ckpt")
input_length = 10
encoded_length = 3
learning_rate = 0.001
n_epochs = 10
n_batches = 10
if not os.path.exists(model_checkpoint_file_base + ".meta"):
print("Making new")
brand_new = True
x_in = tf.placeholder(tf.float32, [None, input_length], name="x_in")
W_enc = tf.Variable(tf.random_uniform([input_length, encoded_length],
-1.0 / math.sqrt(input_length),
1.0 / math.sqrt(input_length)), name="W_enc")
b_enc = tf.Variable(tf.zeros(encoded_length), name="b_enc")
encoded = tf.nn.tanh(tf.matmul(x_in, W_enc) + b_enc, name="encoded")
W_dec = tf.transpose(W_enc, name="W_dec")
b_dec = tf.Variable(tf.zeros(input_length), name="b_dec")
decoded = tf.nn.tanh(tf.matmul(encoded, W_dec) + b_dec, name="decoded")
cost = tf.sqrt(tf.reduce_mean(tf.square(decoded - x_in)), name="cost")
saver = tf.train.Saver()
else:
print("Reloading existing")
brand_new = False
saver = tf.train.import_meta_graph(model_checkpoint_file_base + ".meta")
g = tf.get_default_graph()
x_in = g.get_tensor_by_name("x_in:0")
cost = g.get_tensor_by_name("cost:0")
sess = tf.Session()
if brand_new:
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)
init = tf.global_variables_initializer()
sess.run(init)
tf.add_to_collection("optimizer", optimizer)
else:
saver.restore(sess, model_checkpoint_file_base)
optimizer = tf.get_collection("optimizer")[0]
for epoch_i in range(n_epochs):
for batch in range(n_batches):
batch = np.random.rand(50, input_length)
_, curr_cost = sess.run([optimizer, cost], feed_dict={x_in: batch})
print("batch_cost:", curr_cost)
save_path = tf.train.Saver().save(sess, model_checkpoint_file_base)
Ответ 2
У меня была такая же проблема, и я просто понял, что случилось, по крайней мере, в моем коде.
В конце я использовал неправильное имя файла в saver.restore()
. Эта функция должна иметь имя файла без расширения файла, как функция saver.save()
:
saver.restore(sess, 'model-1')
вместо
saver.restore(sess, 'model-1.data-00000-of-00001')
С этим я делаю именно то, что вы хотите сделать: начиная с нуля, останавливаясь, а затем снова поднимаясь. Мне не нужно инициализировать вторую заставку из метафайла с помощью функции tf.train.import_meta_graph()
, и мне не нужно явно указывать tf.initialize_all_variables()
после инициализации оптимизатора.
Мое полное восстановление модели выглядит следующим образом:
with tf.Session() as sess:
saver = tf.train.Saver()
sess.run(tf.global_variables_initializer())
saver.restore(sess, model-1)
Я думаю, что в протоколе V1 вам все равно нужно добавить .ckpt
к имени файла, а для import_meta_graph()
вам все равно нужно добавить .meta
, что может вызвать некоторую путаницу среди пользователей. Возможно, это должно быть указано более подробно в документации.
Ответ 3
Может возникнуть проблема при создании объекта-хранителя на восстановительном сеансе.
Я получил ту же ошибку, что и ваша, при использовании кодов ниже в восстановительном сеансе.
saver = tf.train.import_meta_graph('tmp/hsmodel.meta')
saver.restore(sess, tf.train.latest_checkpoint('tmp/'))
Но когда я изменился таким образом,
saver = tf.train.Saver()
saver.restore(sess, "tmp/hsmodel")
Ошибка исчезла.
"Tmp/hsmodel" - это путь, который я передаю saver.save(sess, "tmp/hsmodel" ) в сеансе сохранения.
Здесь приведены простые примеры по сохранению и восстановлению сеанса обучения сети MNIST (содержащей оптимизатор Адама). Это помогло мне сравнить с моим кодом и устранить проблему.
https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/4_Utils/save_restore_model.py