Ошибка модели нагрузки Tenorflow

Я пытаюсь загрузить предыдущую сохраненную модель TENSOFLOW (как график, так и переменные).

Вот как я экспортировал модель во время тренировки

tf.global_variables_initializer().run()
y = tf.matmul(x, W) + b

cross_entropy = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

for batch_index in range(batch_size):
    batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size)
    #print(batch_xs.shape)
    #print(batch_ys.shape)
    sess.run(train_step, feed_dict = {x: batch_xs, y_:batch_ys})

    if batch_index % 100 == 0:
        print("Batch "+str(batch_index))
        correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))
        print("Accuracy: "+str(sess.run(accuracy,
                                                  feed_dict = {x: batch_xs, y_: batch_ys})))
        #print("Predictions "+str(y))
        #print("Training accuracy: %.1f%%" %accuracy())
    if batch_index + 1 == batch_size:
        #Save the trained model
        print("Exporting trained model")
        builder = saved_model_builder.SavedModelBuilder(EXPORT_DIR)
        builder.add_meta_graph_and_variables(sess, ['simple-MNIST'])
        builder.save(as_text=True)

Пожалуйста, не обращайте внимания на определение модели (это просто игрушечный пример) и проверяйте только последние строки, в которых вызывается метод сохранения. Все прошло нормально и модель корректно сохраняется в ФС.

Когда я пытаюсь загрузить экспортированную модель, я всегда получаю следующую ошибку:

TypeError: невозможно преобразовать MetaGraphDef в тензор или операцию.

Вот как я загружаю модель:

with tf.Session() as sess:
  print(tf.saved_model.loader.maybe_saved_model_directory(export_dir))
  saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir)

  sess.run(saved_model)

Есть идеи, как это решить? Кажется, модель была экспортирована в неправильном формате, но я не могу понять, как его изменить.

Вот простой скрипт для загрузки модели и ее оценки.

with tf.device("/cpu:0"):
  x = tf.placeholder(tf.float32, shape =(batch_size, 784))
  W = tf.Variable(tf.truncated_normal(shape=(784, 10), stddev=0.1))
  b = tf.Variable(tf.zeros([10]))
  y_ = tf.placeholder(tf.float32, shape=(batch_size, 10))

with tf.Session() as sess:
  tf.global_variables_initializer().run()

  print(tf.saved_model.loader.maybe_saved_model_directory(export_dir))
  saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir)

  batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size)
  y = tf.matmul(x, W) + b
  correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
  accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))    

 print("Test Accuracy: "+ str(sess.run(accuracy, feed_dict = {x: batch_xs, y_: batch_ys})))

Запуск этого скрипта в совершенно новом контексте PYTHON будет оценивать модель с очень низкой точностью (похоже, что метод загрузки модели неправильно установил переменные графика)

Благодарю вас!


person luke035    schedule 04.04.2017    source источник


Ответы (1)


Я думаю, проблема в том, что вы не можете передать saved_model в sess.run. Из документации saved_model.loader.load:

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

Итак, что именно вы ожидаете от sess.run(saved_model), когда saved_model является MetaGraphDef? Если я правильно понял механику load, то график, а также связанные с ним переменные восстанавливаются в сеансе, который вы передаете load(..), и, следовательно, ваша модель готова к использованию после завершения load(..). Таким образом, вы должны иметь доступ к переменным, операциям и тензорам через график (по умолчанию), как обычно, и нет необходимости в дальнейшем иметь дело с возвращенным объектом MetaGraphDef.

Вот дополнительная информация о том, что такое MetaGraphDef: Что такое метафайл контрольной точки TensorFlow? . Из этого должно быть понятно, что использовать его с sess.run() не имеет смысла.

Изменить

После вашего редактирования: функция tf.saved_model.loader.load внутренне вызывает tf.import_meta_graph, а затем saver.restore, т. е. восстанавливает как график , так и значения переменных, представленных на графике. Таким образом, вам не нужно самостоятельно переопределять переменные в начале добавленного фрагмента кода. На самом деле это может привести к неопределенному поведению, поскольку тогда некоторые узлы могут существовать дважды в графе по умолчанию. Проверьте этот пост stackoverflow для получения дополнительной информации: Восстановление модели Tensorflow и переменной просмотра значение. Итак, я предполагаю, что здесь происходит следующее: на шаге вывода используется необученная переменная W, которую вы создали вручную, вместо предварительно обученной, которую вы загружаете через saved_model.loader, поэтому вы видите низкую точность.

Итак, я предполагаю, что если вы опустите определения x, W, b и y_ в начале и получите их из восстановленного графа, например. через вызов tf.get_default_graph().get_tensor_by_name('variable_name')) он должен работать нормально.

PS: Если вы восстанавливаете модель, нет необходимости запускать инициализатор (хотя я предполагаю, что это тоже не повредит).

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

person kafman    schedule 04.04.2017
comment
Спасибо за ваш ответ. Я думаю, что вы правы, но я все еще пытаюсь найти решение. Я попытался загрузить модель в отдельный блокнот, но переменные, похоже, неинициализированы (мне также пришлось их переопределить, чтобы сделать код функциональным). Если я загружаю модель в том же контексте (в данном случае блокнот), модель правильно оценивает новые записи, но не тогда, когда я пытаюсь загрузить ее в совершенно новый блокнот. - person luke035; 04.04.2017
comment
Что вы хотите сделать с моделью после ее загрузки (продолжить обучение, использовать ее для вывода, получить некоторые определенные переменные/тензоры...)? - person kafman; 04.04.2017
comment
Я хочу использовать его для вывода новых записей. Когда я сохраняю модель, я считаю ее завершенной. Еще раз спасибо! - person luke035; 04.04.2017
comment
Не могли бы вы отредактировать свой пост с воспроизводимым примером той ошибки, которую вы описываете? - person kafman; 04.04.2017
comment
Все становится понятнее! К сожалению, я до сих пор не могу загрузить тенора, указанные на графике. Когда я пытаюсь загрузить тензор W (tf.get_default_graph().get_tensor_by_name('W')) я получаю следующую ошибку: Имя 'W' выглядит как (недопустимое) имя операции, а не как тензор. Имена тензоров должны иметь форму ‹op_name›:‹output_index›. Я думаю, что мне нужно было сопоставить тензоры в графе перед сохранением, верно? - person luke035; 04.04.2017
comment
Давайте продолжим обсуждение в чате. - person kafman; 04.04.2017