tensorflow:tf.Graph

Class Graph

- A TensorFlow computation, represented as a dataflow graph.

一个Graph 包含很多tf.Operation 对象( represent units of computation;)和tf.Tensor 对象 (represent the units of data that flow between operations)

- 获取默认的图tf.get_default_graph

定义一个Operation就会添加新的操作到默认图:

c = tf.constant(4.0)
assert c.graph is tf.get_default_graph()

tf.Graph.as_default 创立新的默认图:
- 注:这个类对于计算图来说不是线程安全的。

g = tf.Graph()
with g.as_default():
  # Define operations and tensors in `g`.
  c = tf.constant(30.0)
  assert c.graph is g

一个Graph 实例可以包括任意的”collections”。比如 tf.Variable 在创建一个图的时候放在这个 collection ( tf.GraphKeys.GLOBAL_VARIABLES) ,其他collection可以通过声明别的名字。collections相当对图中的类似的计算单元做了打包

该类下的方法

name_scope

name_scope(name)

作用:Returns a context manager that creates hierarchical names for operations.

#操作单元在流程图上的操作名称
with tf.Graph().as_default() as g:
  c = tf.constant(5.0, name="c")
  assert c.op.name == "c"
  c_1 = tf.constant(6.0, name="c")
  assert c_1.op.name == "c_1"

#nested被声明为图g的默认scope
  # Creates a scope called "nested"
  with g.name_scope("nested") as scope:
    nested_c = tf.constant(10.0, name="c")
    assert nested_c.op.name == "nested/c"

    #图g创建scope "inner",被放在默认的scope“nested”内
    with g.name_scope("inner"):
      nested_inner_c = tf.constant(20.0, name="c")
      assert nested_inner_c.op.name == "nested/inner/c"

    # 名称为inner的scope已经存在,自动起别名 "inner_1",同样放在“nested”内
    with g.name_scope("inner"):
      nested_inner_1_c = tf.constant(30.0, name="c")
      assert nested_inner_1_c.op.name == "nested/inner_1/c"

      # `scope` 代表默认的scope,即转到"nested/" scope.
      with g.name_scope(scope):
        nested_d = tf.constant(40.0, name="d")
        assert nested_d.op.name == "nested/d"

        with g.name_scope(""):
          e = tf.constant(50.0, name="e")
          assert e.op.name == "e"

在命名空间中创立变量:

inputs = tf.constant(...)
with g.name_scope('my_layer') as scope:
  weights = tf.Variable(..., name="weights")
  biases = tf.Variable(..., name="biases")
  affine = tf.matmul(inputs, weights) + biases
  output = tf.nn.relu(affine, name=scope)

例子2: 使用tf.get_variable()定义的变量不会被tf.name_scope()当中的名字所影响.

import tensorflow as tf

with tf.name_scope("a_name_scope"):
    initializer = tf.constant_initializer(value=1)
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    var21 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)
    var22 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)


with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print(var1.name)        # var1:0
    print(sess.run(var1))   # [ 1.]
    print(var2.name)        # a_name_scope/var2:0
    print(sess.run(var2))   # [ 2.]
    print(var21.name)       # a_name_scope/var2_1:0
    print(sess.run(var21))  # [ 2.0999999]
    print(var22.name)       # a_name_scope/var2_2:0
    print(sess.run(var22))  # [ 2.20000005]

可以看出来var1没有前缀命名空间。这里tf.variable_scopetf.name_scope 细微的差别,那就是 name_scope 只能管住操作 Ops 的名字,而管不住变量 Variables 的名字,看下例:

with tf.variable_scope("foo"):
    with tf.name_scope("bar"):
        v = tf.get_variable("v", [1])
        x = 1.0 + v
assert v.name == "foo/v:0"
assert x.op.name == "foo/bar/add"

tf.variable_scope():达到重复利用变量的效果, 我们就要使用 tf.variable_scope(), 并搭配 tf.get_variable() 这种方式产生和提取变量.

with tf.variable_scope("a_variable_scope") as scope:
    initializer = tf.constant_initializer(value=3)
    var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer)
    scope.reuse_variables()
    var3_reuse = tf.get_variable(name='var3',)
    var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    var4_reuse = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var3.name)            # a_variable_scope/var3:0
    print(sess.run(var3))       # [ 3.]
    print(var3_reuse.name)      # a_variable_scope/var3:0
    print(sess.run(var3_reuse)) # [ 3.]
    print(var4.name)            # a_variable_scope/var4:0
    print(sess.run(var4))       # [ 4.]
    print(var4_reuse.name)      # a_variable_scope/var4_1:0
    print(sess.run(var4_reuse)) # [ 4.]

tf.get_variable遇到了同样名字的变量时, 它会单纯的提取这个同样名字的变量(避免产生新变量). 而在重复使用的时候, 一定要在代码中强调 scope.reuse_variables()

get_all_collection_keys

  • Returns a list of collections used in this graph.

get_collection

get_collection(
    name,
    scope=None
)
  • Returns a list of values in the collection with the given name.
  • 注意:This is different from get_collection_ref() which always returns the actual collection list if it exists in that it returns a new list each time it is called.

例子:

X = tf.placeholder(tf.float32,shape=[None,n_inputs])


he_init = tf.contrib.layers.variance_scaling_initializer()# He initialization
#等价于
#he_init = lambda shape, dtype=tf.float32: tf.truncated_normal(shape, 0., stddev=np.sqrt(2/shape[0]))
l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
my_dense_layer = partial(tf.layers.dense,
                        activation=tf.nn.elu,
                        kernel_initializer=he_init,
                        kernel_regularizer=l2_regularizer)

hidden1 = my_dense_layer(X, n_hidden1)
hidden2 = my_dense_layer(hidden1, n_hidden2)
hidden3 = my_dense_layer(hidden2, n_hidden3)
outputs = my_dense_layer(hidden3, n_outputs,activation=None)

reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))
#拿出损失命名空间中的损失
reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)

参考:官网API
https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-12-scope/
http://www.cnblogs.com/Charles-Wan/p/6200446.html

猜你喜欢

转载自blog.csdn.net/nockinonheavensdoor/article/details/80557128