不确定这是否需要解释,但以防万一(以及其他潜在观众)。
每当您在 TensorFlow 中创建操作时,都会向图中添加一个新节点。图中没有两个节点可以具有相同的名称。您可以定义您创建的任何节点的名称,但如果您不提供名称,TensorFlow 会以一种确定性的方式为您选择一个(即,不是随机的,而是始终以相同的顺序)。如果您将两个数字相加,则可能是Add
,但如果您再进行一次相加,由于没有两个节点可以具有相同的名称,它可能类似于Add_2
。一旦在图中创建了节点,它的名称就不能更改。许多函数依次创建多个子节点;例如,tf.layers.batch_normalization
创建一些内部变量beta
和gamma
.
保存和恢复工作方式如下:
- 您创建一个表示您想要的模型的图形。此图包含将由保护程序保存的变量。
- 您可以对该图进行初始化、训练或做任何您想做的事情,并且模型中的变量会被分配一些值。
- 您调用
save
保护程序将变量的值保存到文件中。
- 现在您在不同的图形中重新创建模型(它可以是完全不同的 Python 会话,也可以只是与第一个图形共存的另一个图形)。该模型必须以与第一个模型完全相同的方式创建。
- 您调用
restore
保护程序来检索变量的值。
为了使它起作用,第一张和第二张图中的变量名称必须完全相同。
在您的示例中,TensorFlow 抱怨变量batch_normalization_585/beta
. 看起来你tf.layers.batch_normalization
在同一张图中调用了近 600 次,所以你有那么多beta
变量。我怀疑你真的需要那么多,所以我猜你只是在试验 API 并最终得到了那么多副本。
这是应该起作用的草稿:
import tensorflow as tf
def make_model():
input = tf.placeholder(...)
phase = tf.placeholder(...)
input_norm = tf.layers.batch_normalization(input, training=phase))
# Do some operations with input_norm
output = ...
saver = tf.train.Saver()
return input, output, phase, saver
# We work with one graph first
g1 = tf.Graph()
with g1.as_default():
input, output, phase, saver = make_model()
with tf.Session() as sess:
# Do your training or whatever...
saver.save(sess, savedir + "ckpt")
# We work with a second different graph now
g2 = tf.Graph()
with g2.as_default():
input, output, phase, saver = make_model()
with tf.Session() as sess:
saver.restore(sess, savedir + "ckpt")
# Continue using your model...
同样,典型的情况不是并排有两个图,而是有一个图,然后稍后在另一个 Python 会话中重新创建它,但最终两者都是相同的。重要的部分是模型在两种情况下都是以相同的方式创建的(因此具有相同的节点名称)。