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

问题描述 投票:2回答:3

我正在尝试实现一个深度神经网络,我想在那里试验隐藏层的数量。为了避免容易出错的代码重复,我将层的创建放在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时初始化权重和偏差。

python variables tensorflow scope
3个回答
1
投票

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

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命名不同图层的参数。即而不是使用像"W" + str(i)这样的名字,你可以在tf.variable_scope("layer" + str(i))周围包裹一个get_variable。这会给你一些名字,比如“model1 / layer0 / W”。范围可以任意嵌套。

你可能想读the TF Programmer's Guide on variables


1
投票

如果您不希望重用变量,那么您不应该使用tf.get_variable。一个简单的tf.Variable应该工作,而不是你看到的冲突。

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


1
投票

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

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

tf.reset_default_graph()
© www.soinside.com 2019 - 2024. All rights reserved.