1. ホーム

tf.variable_scope パラメータ

2022-02-16 23:12:45

最近、TensorFlowの変数管理を見ていて、多くのコードに含まれるtf.variable_scope()パラメータの数や意味がよくわからないことがわかったので、ここに記録しておくことにします。

  def __init__(self,
               name_or_scope,
               default_name=None,
               values=None,
               initializer=None,
               regularizer=None,
               caching_device=None,
               partitioner=None,
               custom_getter=None,
               reuse=None,
               dtype=None,
               use_resource=None,
               constraint=None,
               auxiliary_name_scope=True):
    """Initialize the context manager.

    Args:
      name_or_scope: `string` or `VariableScope`: the scope to open.
      default_name: The default name to use if the `name_or_scope` argument is
        If name_or_scope is provided it
        If name_or_scope is provided it won't be used and therefore it is not required and can be None.
      values: The list of `Tensor` arguments that are passed to the op function.
      initializer: default initializer for variables within this scope.
      regularizer: default regularizer for variables within this scope.
      caching_device: default caching device for variables within this scope.
      partitioner: default partitioner for variables within this scope.
      custom_getter: default custom getter for variables within this scope.
      reuse: `True`, None, or tf.AUTO_REUSE; if `True`, we go into reuse mode
        AUTO_REUSE; if `True`, we go into reuse mode for this scope as well as all sub-scopes; if tf.
        AUTO_REUSE, we create variables if they do not exist, and return them otherwise; if None, we
        AUTO_REUSE, we create variables if they do not exist, and return them otherwise; if None, we inherit the parent scope's reuse flag,
        When eager execution is enabled, this argument is always forced to be tf.AUTO_REUSE.
      dtype: type of variables created in this scope (defaults to the type
        in the passed scope, or inherited from parent scope).
      use_resource: If False, all variables will be regular Variables. if True,
        If True, experimental ResourceVariables with well-defined semantics will be used
        Defaults to False (will later change to True). When eager
        execution is enabled this argument is always forced to be True.
      constraint: An optional projection function to be applied to the variable
        constraint: An optional projection function to be applied to the variable after being updated by an `Optimizer` (e.g. used to implement norm
        constraints or value constraints for layer weights). The function must
        take as input the unprojected Tensor representing the value of the
        variable and return the Tensor for the projected value
        (which must have the same shape). Constraints are not safe to
        use when doing asynchronous distributed training.
      auxiliary_name_scope: If `True`, we create an auxiliary name scope with
        If `False`, we don't touch name scope.

    Returns:
      A scope that can be captured and reused.

    Raises:
      ValueError: when trying to reuse within a create scope, or create within
        a reuse scope.
      TypeError: when the types of some arguments are not appropriate.
    """

上記のコードは、tf.variable関数の定義であり、ここで
 name_or_scope: `string` or `VariableScope`: the scope to open. is the name of the variable space
 default_name: It can be ignored when name_or_scope is used and is basically useless
 values: The tensor parameters passed into the scope      
initializer=None: the default parameter initialization function
regularizer: d default regularizer function
caching_device: default caching device for variables within this scope.
partitioner: default partitioner for variables within this scope.
custom_getter: default custom getter for variables within this scope.
reuse: `True`, None, or tf.AUTO_REUSE; if `True`, we go into reuse mode
        for this scope as well as all sub-scopes; if tf.AUTO_REUSE, we create
        AUTO_REUSE, we create variables if they do not exist, and return them otherwise; if None, we
        AUTO_REUSE, we create variables if they do not exist, and return them otherwise; if None, we inherit the parent scope's reuse flag,
        When eager execution is enabled, this argument is always forced to be tf.AUTO_REUSE

with tf.variable_scope("foo"):
    v = tf.get_variable("v", [1], initializer=tf.constant_initializer(1.0))
                        
# with tf.variable_scope("foo"):
   # v = tf.get_variable("v", [1])
    
with tf.variable_scope("foo", reuse=True):
    v1 = tf.get_variable("v", [1])
print(v == v1)

# with tf.variable_scope("bar", reuse=True):
   # v = tf.get_variable("v", [1])

with tf.variable_scope("root"): # reuse is false by default or consistent with the previous level
    print(tf.get_variable_scope().reuse)
    
    with tf.variable_scope("foo", reuse=True):
        print(tf.get_variable_scope().reuse)
        
        with tf.variable_scope("bar"):
            print(tf.get_variable_scope().reuse)
            
    print(tf.get_variable_scope().reuse)





a1 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a1')


reuseには3つの値があり、デフォルトはNoneである。

True: パラメータ空間は再利用モードを使用します。つまり、その空間内のすべての tf.get_variable() 関数は作成された変数を直接取得し、パラメータが存在しない場合は tf.get_variable() 関数がエラーを報告することになります。

AUTO_REUSE:パラメータが存在しない場合はパラメータスペースに作成し、既に存在する場合は直接取得します。

None or False ここでは、作成関数 tf.get_variable() 関数は新しい変数のみを作成でき、同じ名前の変数がすでに存在する場合は、エラーを報告します。

以下はその例です。

import tensorflow as tf

with tf.variable_scope('f2'):
    #a1 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))
    a1 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a1')
    a2 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a1')
    a5 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))

with tf.variable_scope('f2', reuse=True):
    a3 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))

    a4 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a2')

print(a1.name)
print(a2.name)
print(a1==a2)
print(a5.name)
print(a3.name)
print(a4.name)

出力はTrue

with tf.variable_scope("root"): # reuse is false by default or consistent with the previous level
    print(tf.get_variable_scope().reuse)
    
    with tf.variable_scope("foo", reuse=True):
        print(tf.get_variable_scope().reuse)
        
        with tf.variable_scope("bar"):
            print(tf.get_variable_scope().reuse)
            
    print(tf.get_variable_scope().reuse)



tf.name_scopeとtf.variable_scopeの関係

tf.name_scope と tf.variable_scope は、主に変数の作成/呼び出し関数である tf.Variable() と tf.get_variable() で使用されるスコープであります。まず、tf.variable()とtf.get_variable()の違いについて。

    Variable() は呼び出されるたびに新しい変数を作成し、名前の衝突を自動的に検出して独自に処理し、変数名はオプションのパラメータで、例.

a1 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a1')


a2 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1)), name='a1')

print(a1.name)

print(a2.name)さん

プリント(a1==a2)

結果を実行します。

f1/a1:0
f1/a1_1:0

誤 # a2 は実際には a1_1 になり、a1 と同じ変数ではありません。

tf.get_variable()は、名前を変更した変数が作成され、変数名が共有変数に設定されていない場合にエラーを報告しますが(共有とは同じパラメータ空間で共有されていること、パラメータ空間名が異なる場合は共有ではない)、このパラメータに基づいて tf.get_variable() は変数の作成または取得を行ないます。

tf.name_scope()は主にグラフ内の様々なopを管理するために使われ、tf.variable_scope()は主にグラフ内の変数の名前を管理するために使われます。 tf.name_scopeの下では、tf.get_variable()で作成した変数名はname_scopeの影響を受けない(束縛されない)

import tensorflow as tf

with tf.variable_scope('f2'):
    #a1 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))
    a1 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a1')
    a2 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a1')
    a5 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))

with tf.variable_scope('f2', reuse=True):
    a3 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))

    a4 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a2')

print(a1.name)
print(a2.name)
print(a1==a2)
print(a5.name)
print(a3.name)
print(a4.name)

結果を実行します。

f2/a1:0
f2/a1_1:0

f2/a1_2:0
f2/a1_2:0
f2_1/a2:0