无法在 TensorFlow 中共享/重命名变量



我正在尝试实现一个深度神经网络,我想在其中尝试隐藏层的数量。为了避免容易出错的代码重复,我将层的创建放在一个 for 循环中,如下所示:

def neural_network_model(data, layer_sizes):
    num_layers = len(layer_sizes) - 1 # hidden and output layers
    layers = [] # hidden and output layers
    # initialise the weights
    for i in range(num_layers):
        layers.append({
            'weights': tf.get_variable("W" + str(i+1),
                       [layer_sizes[i], layer_sizes[i+1]], 
                       initializer = tf.contrib.layers.xavier_initializer()),
             'biases': tf.get_variable("b" + str(i+1), [layer_sizes[i+1]], 
                       initializer = tf.zeros_initializer())
        })
        ...

作为输入给出的列表layer_sizes如下所示:

layer_sizes = [num_inputs, num_hl_1, num_hl_2, ..., num_hl_n, num_outputs]

当我第一次运行此代码时,我没有问题。但是,当我将layer_sizes更改为具有不同数量的图层时,出现错误:

ValueError: Variable W1 already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope

我知道这是因为层的命名(我什至不关心(。如何解决此问题并在重新运行时允许重命名?我已经做了一些谷歌搜索,解决方案似乎在于使用with tf.variable_scope(),但我无法弄清楚具体如何。

编辑 - 需要明确的是:我不想重复使用任何名称或变量。我只想在每次调用neural_network_model时(重新(初始化权重和偏差。

创建多个不同的模型时,需要确保它们都收到唯一的变量名称。我能在这里看到的最直接的方式是这样的:

def neural_network_model(data, layer_sizes, name):
    num_layers = len(layer_sizes) - 1 # hidden and output layers
    layers = [] # hidden and output layers
    # initialise the weights
    for i in range(num_layers):
        with tf.variable_scope(name):
            layers.append({
                'weights': tf.get_variable("W" + str(i+1),
                           [layer_sizes[i], layer_sizes[i+1]], 
                           initializer = tf.contrib.layers.xavier_initializer()),
                'biases': tf.get_variable("b" + str(i+1), [layer_sizes[i+1]], 
                      initializer = tf.zeros_initializer())
            })
    ...

请注意,如何有一个额外的name参数来命名模型。然后你可以创建多个,如

model1 = neural_network_model(data, some_layers, "model1")
model2 = neural_network_model(data, other_layers, "model2")

等。模型将具有变量名称,例如"model1/W0"。请注意,您还可以使用 variable_scope 来命名不同图层的参数。即,您可以使用tf.variable_scope("layer" + str(i)) get_variable而不是使用诸如"W" + str(i)之类的名称。这将为您提供诸如"model1/layer0/W"之类的名称。作用域可以任意嵌套。

您可能需要阅读有关变量的 TF 程序员指南。

如果您不希望重用变量,则不应使用 tf.get_variable 。一个简单的tf.Variable应该有效,而不是你所看到的冲突。

您可以在 tensorflow 文档中查看此页面以获取更多信息:他们的第一个示例解释了当再次调用示例函数时将创建一组全新的变量。然后他们解释了如何避免这种情况,但在这种情况下,这似乎正是您想要的。

我认为找到了最简单的解决方案。事实证明,我遇到了这个问题,因为我使用了Jupyter笔记本,只要我不重新启动内核,所有变量都会保持活动状态。

我的解决方案是在调用任何变量之前简单地重新初始化所有变量:

tf.reset_default_graph()

最新更新