1. ホーム
  2. tensorflow

tf.variable, tf.get_variable, tf.variable_scope, tf.name_scope の類似点と相違点を理解する。

2022-02-16 22:13:50
<パス

以前、tf.variable_scopeとtf.name_scopeについての記事を転載しましたが、今日は、あまり、要領がよくないというか、やっぱり、英語とかかなり面倒そうですね。変数、tf.get_variable、tf.variable_scope、tf.name_scope、この4つの違いと繋がりについて。

1. tf.variableとtf.get_variable

tensorflowは、変数をその名前で生成したり取得したりする機構を提供する。この機構により、変数は引数として渡す代わりに、異なる関数内でその名前によって直接使用することができる。
TensorFlowで変数を変数名で取得する仕組みは、主にtf.get_variableとtf.variable_scopeによって実装されています。
もちろん、変数はtf.varivaleで作成することも可能です。 変数作成にtf.get_variableを使用した場合、基本的にtf.get_variableと同等になります。 .

# The following two definitions are equivalent
v = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v = tf.Variable(tf.constant(1.0, shape=[1], name='v')

tf.get_varialbeとtf.Variableの最大の違いは、以下の点です。 Variableの変数名はname='v'で与えられるオプションのものである。しかし、tf.get_variableは変数名を指定する必要があります。 .

2. tf.get_variableとtf.variable_scopeについて

前述の通り、TensorFlowにおいて変数名で変数を取得する仕組みは、主にtf.get_variableとtf.variable_scopeによって実装されています。 ここで、みんなが大嫌いな再利用問題について説明します。 .
ひとつだけ覚えておいてほしいのは、reuseがFalseまたはNone(これもデフォルト)の場合、同じtf.variable_scopeにある変数は同じ名前を持つことができません。reuseがTrueの場合、tf.variable_scopeはすでに作られた変数だけを取得できます。
これをコードで見てみましょう。

The case where an error is reported when #reuse=False.
with tf.variable_scope('foo'):
    v = tf.get_variable('v',[1],initializer=tf.constant_initializer(1.0))

with tf.variable_scope('foo'):
    v1 = tf.get_variable('v',[1])

この場合、エラーが報告されます。Varscopeでreuse=Trueを設定したのでしょうか?
その理由は、同じ変数が名前空間fooに作成されたからです。もし、fooの下にname='v'の変数v1を作りたい場合は、reuseをTureに設定すればOKです。上のコードの2番目の部分を次のように修正します。

with tf.variable_scope('foo', reuse=True):
    v1 = tf.get_variable('v',[1])
    print(v1.name) # results in foo/v

reuse が True に設定されている場合、tf.variable_scope は既に作成された変数のみをフェッチできます。このとき、名前空間 bar に name='v' で変数 v3 を作成すると、エラーになります。Variable bar/v dose not exist, diallowed. VarScope?

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

一言で言えば reuse=Falseのとき、tf.variable_scopeは変数を作成し、reuse=Trueのとき、tf.variable_scopeは変数を取得します。 .

3. tf.variable_scopeとtf.name_scopeの併用

tf.variable_scopeに加えて、tf.name_scope関数も名前空間管理機能を提供します。この2つの関数はほとんどの場合同等で、唯一の違いはtf.get_variable関数を使用する場合です。
tf.get_variable 関数は、tf.name_scope の影響を受けません。 .
この文の意味を正確に理解するために、コードを見てみましょう。
まず、tf.variable_scopeです。

with tf.variable_scope('foo'):
    a = tf.get_variable('bar',[1])
    print(a.name)# results in foo/bar:0

tf.name_scopeをもう一度見てみる。

with tf.name_scope('a'):
    a=tf.Variable([1])
    print(a.name)# results in a/Variable:0

    b=tf.get_variable('b',[1])
    print(b.name)#result is b:0

この結果から、はっきりとわかるのは tf.get_variable は a/b:0 ではなく b:0 となる変数を作成します。これは、tf.get_variableがtf.name_scope関数の下に束縛されていないことを意味します。 .