Подтвердить что ты не робот

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: сохранение и восстановление сеанса, но окончательного решения четкого разрешения нет, и пример довольно сложный.

В идеале я бы хотел, чтобы простой пример, начинающийся с нуля, останавливался, а затем снова поднимался. У меня есть что-то, что работает (ниже), но также интересно, не хватает ли я чего-то. Неужели я не единственный, кто это делает?

4b9b3361

Ответ 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