张量流中的变量内部

Ale*_*der 4 tensorflow

我将探讨如何在图中表示变量.我创建一个变量,初始化它并在每个动作后创建图形快照:

import tensorflow as tf

def dump_graph(g, filename):
    with open(filename, 'w') as f:
        print(g.as_graph_def(), file=f)

g = tf.get_default_graph()
var = tf.Variable(2)
dump_graph(g, 'data/after_var_creation.graph')

init = tf.global_variables_initializer()
dump_graph(g, 'data/after_initializer_creation.graph')

with tf.Session() as sess:
    sess.run(init)
    dump_graph(g, 'data/after_initializer_run.graph')
Run Code Online (Sandbox Code Playgroud)

变量创建后的图形看起来像

node {
  name: "Variable/initial_value"
  op: "Const"
  attr {
    key: "dtype"
    value {
      type: DT_INT32
    }
  }
  attr {
    key: "value"
    value {
      tensor {
        dtype: DT_INT32
        tensor_shape {
        }
        int_val: 2
      }
    }
  }
}
node {
  name: "Variable"
  op: "VariableV2"
  attr {
    key: "container"
    value {
      s: ""
    }
  }
  attr {
    key: "dtype"
    value {
      type: DT_INT32
    }
  }
  attr {
    key: "shape"
    value {
      shape {
      }
    }
  }
  attr {
    key: "shared_name"
    value {
      s: ""
    }
  }
}
node {
  name: "Variable/Assign"
  op: "Assign"
  input: "Variable"
  input: "Variable/initial_value"
  attr {
    key: "T"
    value {
      type: DT_INT32
    }
  }
  attr {
    key: "_class"
    value {
      list {
        s: "loc:@Variable"
      }
    }
  }
  attr {
    key: "use_locking"
    value {
      b: true
    }
  }
  attr {
    key: "validate_shape"
    value {
      b: true
    }
  }
}
node {
  name: "Variable/read"
  op: "Identity"
  input: "Variable"
  attr {
    key: "T"
    value {
      type: DT_INT32
    }
  }
  attr {
    key: "_class"
    value {
      list {
        s: "loc:@Variable"
      }
    }
  }
}
versions {
  producer: 21
}
Run Code Online (Sandbox Code Playgroud)

有几个节点:Variable/initial_value,Variable, Variable/Assign,Variable/read.

运行init操作后,添加另一个节点:

node {
  name: "init"
  op: "NoOp"
  input: "^Variable/Assign"
}
Run Code Online (Sandbox Code Playgroud)

我没有紧紧抓住这里发生的事情.

  1. 任何人都可以解释这些节点的确切含义是什么?
  2. tensorflow Python API中隐式变量初始化的目的是什么?为什么我们不能在创建变量对象后自动初始化变量,或者在Session.run()中初始化未初始化的变量?
  3. Variable/read节点和 ^Variable/Assign内部init节点内"loc:@"语法的含义是什么?
  4. 如何检索变量值有效?我想这个值存储在一个会话中,并且session.run()代替了这个值的某个地方,但是不知道血淋淋的细节.

mrr*_*rry 9

tf.Variable可以在此处的源存储库中找到TensorFlow 类的实现.Python包装器类负责在数据流图中创建多个节点,并提供方便的访问器来使用它们.我会使用你的例子中的名字来说清楚:

  • Variable类型的节点VariableV2是拥有变量内存的有状态TensorFlow操作.每次运行该操作时,它都会发出缓冲区(作为"ref tensor"),以便其他操作可以读取或写入它.

  • 节点Variable/initial_value(类型Const)是您提供的张量作为构造函数的initial_value参数tf.Variable.这可以是任何类型的张量,尽管通常它是tf.random_*()用于随机权重初始化的操作.后缀initial_value意味着它可能是通过传递一个隐式转换为张量的非张量来创建的.

  • Variable/Assign类型的节点Assign初始化操作,它将初始值写入变量的内存中.当您sess.run(tf.global_variables_initializer())在程序中稍后执行时,它通常运行一次.

  • Variable/read类型节点Identity是"取消引用" Variableop的"ref tensor"输出的操作.这主要是一个实现细节,但是当跨越进程边界多次读取变量时,它提供了理想的行为:特别是,该值仅被复制一次,因为此op的输出不是"ref tensor".(相反,如果"ref"边缘在进程之间进行分区,TensorFlow会多次复制该变量.这有时很有用(如果你想在同一步骤中看到写入对不同设备的影响),但它非常适合.

TensorFlow中的变量初始化是显式的,这可能会引起麻烦(例如,如果您忘记为所有变量运行初始值设定项).但是,我们不隐式执行此操作的原因是有很多方法可以初始化变量:从张量,检查点或其他进程(在图复制之间进行).TensorFlow无法猜测您打算使用哪一个,因此它会使流程显式化.

"loc:@Variable"语法用于在同一设备上共存节点.特别是,任何具有此_classattr 值的op都将与Variable操作放在同一设备上.

检索变量的值非常简单:变量op输出一个tensorflow::Tensor值,该值可以通过tensorflow::Session::Run()API 复制回来.然后,Python绑定将此值复制到NumPy数组中.