这些函数之间有什么区别?

特遣部队。variable_op_scope(values, name, default_name, initializer=None) 返回用于定义创建变量的操作的上下文管理器。 这个上下文管理器验证给定的值是否来自同一个图,确保该图是默认图,并推入名称作用域和变量作用域。


特遣部队。op_scope(values, name, default_name=None) 返回定义Python操作时使用的上下文管理器。 这个上下文管理器验证给定的值是否来自同一个图,确保该图是默认图,并推入名称作用域。


tf.name_scope(名字) 使用默认图形的graph. name_scope()的包装器。 有关详细信息,请参阅Graph.name_scope()。


特遣部队。variable_scope(name_or_scope, reuse=None, initializer=None) 返回变量scope的上下文。 变量作用域允许创建新变量并共享已创建的变量,同时提供检查,以防止意外创建或共享。有关详细信息,请参见变量作用域如何,在这里我们只提供几个基本示例。


当前回答

让我们先简短地介绍一下变量共享。它是TensorFlow中的一种机制,允许共享在代码的不同部分访问的变量,而无需传递对变量的引用。

方法tf。Get_variable可以与变量名一起作为参数使用,以创建具有此名称的新变量或检索之前创建的变量。这与使用tf不同。变量构造函数,每次调用它都会创建一个新变量(如果已经存在这样的变量名,则可能会在变量名后面添加一个后缀)。

正是为了实现变量共享机制,引入了一种单独类型的作用域(变量作用域)。

结果,我们得到了两种不同类型的作用域:

名称作用域,使用tf.name_scope创建 变量作用域,使用tf.variable_scope创建

这两个作用域对所有操作以及使用tf创建的变量具有相同的效果。变量,即作用域将作为操作或变量名的前缀添加。

但是,名称作用域被tf.get_variable忽略。我们可以在下面的例子中看到:

with tf.name_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

放置使用tf访问的变量的唯一方法。作用域中的Get_variable是使用变量作用域,如下例所示:

with tf.variable_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # my_scope/var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

这允许我们轻松地在程序的不同部分共享变量,甚至在不同的名称范围内:

with tf.name_scope("foo"):
    with tf.variable_scope("var_scope"):
        v = tf.get_variable("var", [1])
with tf.name_scope("bar"):
    with tf.variable_scope("var_scope", reuse=True):
        v1 = tf.get_variable("var", [1])
assert v1 == v
print(v.name)   # var_scope/var:0
print(v1.name)  # var_scope/var:0

更新

从r0.11版本开始,op_scope和variable_op_scope都已弃用,并被name_scope和variable_scope所取代。

其他回答

命名空间是一种以分层方式组织变量和操作符名称的方法。“scopeA / scopeB / scopeC op1”)

Tf.name_scope为默认图中的操作符创建命名空间。 特遣部队。Variable_scope为默认图中的变量和操作符创建命名空间。 特遣部队。Op_scope与tf.name_scope相同,但用于创建指定变量的图。 特遣部队。Variable_op_scope与tf相同。Variable_scope,但用于在其中创建指定变量的图。

指向上述来源的链接有助于消除这个文档问题的歧义。

这个例子显示了所有类型的作用域都为变量和操作符定义了名称空间,区别如下:

tf定义的作用域。Variable_op_scope或tf。Variable_scope与tf兼容。Get_variable(它忽略了另外两个作用域) 特遣部队。Op_scope和tf。Variable_op_scope只是从指定变量列表中选择一个图来创建范围。除了它们的行为等于tf。name_scope和tf。variable_scope相应 特遣部队。Variable_scope和variable_op_scope添加指定的或默认的初始化式。

您可以将它们看作两组:variable_op_scope和op_scope以一组变量作为输入,用于创建操作。区别在于它们如何影响tf.get_variable变量的创建:

def mysum(a,b,name=None):
    with tf.op_scope([a,b],name,"mysum") as scope:
        v = tf.get_variable("v", 1)
        v2 = tf.Variable([0], name="v2")
        assert v.name == "v:0", v.name
        assert v2.name == "mysum/v2:0", v2.name
        return tf.add(a,b)

def mysum2(a,b,name=None):
    with tf.variable_op_scope([a,b],name,"mysum2") as scope:
        v = tf.get_variable("v", 1)
        v2 = tf.Variable([0], name="v2")
        assert v.name == "mysum2/v:0", v.name
        assert v2.name == "mysum2/v2:0", v2.name
        return tf.add(a,b)

with tf.Graph().as_default():
    op = mysum(tf.Variable(1), tf.Variable(2))
    op2 = mysum2(tf.Variable(1), tf.Variable(2))
    assert op.name == 'mysum/Add:0', op.name
    assert op2.name == 'mysum2/Add:0', op2.name

注意这两个例子中变量v的名称。

tf.name_scope和tf.variable_scope也一样:

with tf.Graph().as_default():
    with tf.name_scope("name_scope") as scope:
        v = tf.get_variable("v", [1])
        op = tf.add(v, v)
        v2 = tf.Variable([0], name="v2")
        assert v.name == "v:0", v.name
        assert op.name == "name_scope/Add:0", op.name
        assert v2.name == "name_scope/v2:0", v2.name

with tf.Graph().as_default():
    with tf.variable_scope("name_scope") as scope:
        v = tf.get_variable("v", [1])
        op = tf.add(v, v)
        v2 = tf.Variable([0], name="v2")
        assert v.name == "name_scope/v:0", v.name
        assert op.name == "name_scope/Add:0", op.name
        assert v2.name == "name_scope/v2:0", v2.name

您可以在本教程中阅读更多关于变量作用域的内容。 之前在Stack Overflow上也有类似的问题。

让我们先简短地介绍一下变量共享。它是TensorFlow中的一种机制,允许共享在代码的不同部分访问的变量,而无需传递对变量的引用。

方法tf。Get_variable可以与变量名一起作为参数使用,以创建具有此名称的新变量或检索之前创建的变量。这与使用tf不同。变量构造函数,每次调用它都会创建一个新变量(如果已经存在这样的变量名,则可能会在变量名后面添加一个后缀)。

正是为了实现变量共享机制,引入了一种单独类型的作用域(变量作用域)。

结果,我们得到了两种不同类型的作用域:

名称作用域,使用tf.name_scope创建 变量作用域,使用tf.variable_scope创建

这两个作用域对所有操作以及使用tf创建的变量具有相同的效果。变量,即作用域将作为操作或变量名的前缀添加。

但是,名称作用域被tf.get_variable忽略。我们可以在下面的例子中看到:

with tf.name_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

放置使用tf访问的变量的唯一方法。作用域中的Get_variable是使用变量作用域,如下例所示:

with tf.variable_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # my_scope/var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

这允许我们轻松地在程序的不同部分共享变量,甚至在不同的名称范围内:

with tf.name_scope("foo"):
    with tf.variable_scope("var_scope"):
        v = tf.get_variable("var", [1])
with tf.name_scope("bar"):
    with tf.variable_scope("var_scope", reuse=True):
        v1 = tf.get_variable("var", [1])
assert v1 == v
print(v.name)   # var_scope/var:0
print(v1.name)  # var_scope/var:0

更新

从r0.11版本开始,op_scope和variable_op_scope都已弃用,并被name_scope和variable_scope所取代。

对于API r0.11, op_scope和variable_op_scope都已弃用。 Name_scope和variable_scope可以嵌套:

with tf.name_scope('ns'):
    with tf.variable_scope('vs'): #scope creation
        v1 = tf.get_variable("v1",[1.0])   #v1.name = 'vs/v1:0'
        v2 = tf.Variable([2.0],name = 'v2')  #v2.name= 'ns/vs/v2:0'
        v3 = v1 + v2       #v3.name = 'ns/vs/add:0'

Tensorflow 2.0兼容答案:Andrzej Pronobis和Salvador Dali的解释非常详细地介绍了与范围相关的函数。

在上面讨论的范围函数中,截至目前(2020年2月17日)活跃的是variable_scope和name_scope。

为我们上面讨论过的那些函数指定2.0兼容调用,以造福社区。

1.x中的函数:

tf.variable_scope

tf.name_scope

2.x中的各自函数:

tf.compat.v1.variable_scope

Tf.name_scope (tf.compat.v2.name_scope如果从1迁移过来)。X至2.x)

有关从1迁移的更多信息。X到2。x,请参考本迁移指南。