tensorflow - 保存和恢复操作

时间:2017-10-08 21:32:07

标签: tensorflow save restore

我有一个简单的目标,即在tensorflow保存中训练模型并在以后恢复它,以便继续训练或使用某些功能/操作。

以下是模型的简单示例

import tensorflow as tf
import numpy as np

BATCH_SIZE = 3
VECTOR_SIZE = 1
LEARNING_RATE = 0.1

x = tf.placeholder(tf.float32, [BATCH_SIZE, VECTOR_SIZE],
                   name='input_placeholder')
y = tf.placeholder(tf.float32, [BATCH_SIZE, VECTOR_SIZE],
                   name='labels_placeholder')

W = tf.get_variable('W', [VECTOR_SIZE, BATCH_SIZE])
b = tf.get_variable('b', [VECTOR_SIZE], initializer=tf.constant_initializer(0.0))

y_hat = tf.matmul(W, x) + b
predict = tf.matmul(W, x) + b
total_loss = tf.reduce_mean(y-y_hat)
train_step = tf.train.AdagradOptimizer(LEARNING_RATE).minimize(total_loss)
X = np.ones([BATCH_SIZE, VECTOR_SIZE])
Y = np.ones([BATCH_SIZE, VECTOR_SIZE])
all_saver = tf.train.Saver() 

sess= tf.Session()
sess.run(tf.global_variables_initializer())
sess.run([train_step], feed_dict = {x: X, y:Y}))
save_path =  r'C:\some_path\save\\'
all_saver.save(sess,save_path)

现在我们在这里恢复它:

meta_path = r'C:\some_path\save\.meta'
new_all_saver = tf.train.import_meta_graph(meta_path)

graph = tf.get_default_graph()
all_ops = graph.get_operations()
for el in all_ops:
    print(el)

在恢复的操作中,您甚至无法从原始代码中找到predicttrain_step。我需要在保存之前命名此操作吗?如何让predict返回并运行类似

的内容
sess=tf.Session()
sess.run([predict], feed_dict = {x:X})

P.S。我在tensorflow中阅读了许多关于保存和恢复的教程,但仍然不太了解它是如何工作的。

1 个答案:

答案 0 :(得分:2)

1)您的操作存在于已恢复的模型中,但由于您尚未命名它们,因此将根据某些默认规则对它们进行命名。例如,因为你有:

predict = tf.matmul(W, x) + b

然后代表predict的操作可能如下所示:

name: "add"
op: "Add"
input: "MatMul"
input: "b/read"
attr {
  key: "T"
  value {
    type: DT_FLOAT
  }
}

在此示例中,当您执行for el in all_ops:并打印结果时打印,您会看到操作的名称是“add”,它是自动分配的;操作类型(“op”)是“Add”,它对应于代码行中执行的最后一个操作(即+);输入是“MatMul”和“b / read”,对应于你总结的内容。为了清楚起见,我不确定只是这个操作对应于给定的代码行,因为打印中存在具有相同类型输入的其他添加,但这是可能的。

所以总结到现在为止:你的操作在那里,你在打印时看到它们。但为什么你不看“预测”这个词?好吧,因为这不是Tensorflow图中张量或操作的名称,它只是代码中变量的名称。

前进,你怎么能访问这个“预测”?答案是通过它的名称,如图中所示。在上面的例子中,预测的名称可以是“添加”,如果我对我的猜测是正确的,那么让我们将其命名为“预测”,这样您就可以轻松控制哪个操作对应于它。

为了命名“预测”,我们在predict = tf.matmul(W, x) + b下方添加以下代码行:

predict_named = tf.identity(predict, "here_i_put_a_name")

这一行正在做的是创建一个新操作,它接收“predict”中定义的操作作为输入,并产生一个等于输入结果的输出。操作本身没有做太多 - 只是重复一个值 - 但通过这个操作,我可以为它添加一个名称。现在,如果您在印刷品中搜索,您将能够找到:

name: "add_1"
op: "Add"
input: "MatMul_1"
input: "b/read"
attr {
  key: "T"
  value {
    type: DT_FLOAT
  }
}

name: "here_i_put_a_name"
op: "Identity"
input: "add_1"
attr {
  key: "T"
  value {
    type: DT_FLOAT
  }
}

尼斯!现在你1)可以使用名称“here_i_put_a_name”访问你的“预测”,2)我们可以确认你的“预测”实际上是名为“add_1”的操作 - 只需检查操作的“输入”属性上方“here_i_put_a_name”。

完成后,让我们访问“here_i_put_a_name”操作并完成一些预测。首先,更改save_path和meta_path,最后放置一个可能的文件名,例如:

save_path =  r'C:\some_path\save\my_model_name'
meta_path = r'C:\some_path\save\my_model_name.meta'

然后,在还原代码的最后,添加:

with tf.Session(graph=graph) as sess:

    new_all_saver.restore(sess,save_path)
    my_prediction = sess.run(["here_i_put_a_name:0"], feed_dict={"input_placeholder:0": [[1],[2],[3]]})
    print(my_prediction)

使用此块,您将创建一个新的Tensorflow会话并使用存储在变量“graph”中的图形。在此上下文中,您正在将会话从save_path还原到当前会话。然后,您正在运行预测,或者更确切地说,您正在运行操作“here_i_put_a_name”并获取此操作的第一个输出(之后我们有“:0”)。 feed dict将值[[1],[2],[3]]赋给张量“input_placeholder:0”(同样,“:0”表示这是张量,而不是操作)。

随着所有的说法和(希望)回答的问题,我有一些意见:

1)根据我的经验,使用库tf.saved_model以保存和恢复模块会很不错。但这是我个人的建议。

2)我限制自己回答有关命名和调用操作的问题,因此我忽略了训练和预测例程。但是我认为在将变量X与BATCH_SIZE作为大小放置时,问题是错误的。

3)注意“blabla”和“blabla:0”之间的区别。第一个是操作,最后一个是张量。