了解Tensorflow控制依赖项

时间:2019-03-11 03:42:05

标签: python tensorflow machine-learning controls

我试图更深入地了解TensorFlow。我遇到了控件依赖项的概念。我了解我们指定的操作顺序在执行期间与Tensorflow并没有真正的关系。为了优化执行速度,TensorFlow决定了自己的计算节点顺序。 但是我们可以使用tf.control_dependencies自定义执行顺序。 我无法理解该功能的用例。任何人都可以将我带到某些资源(文档除外)或解释此功能的工作吗? 一个例子:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="time" name="inputJammulai" id="inputJammulai" class="form-control" required="required">
<input type="time" name="inputJamselesai" id="inputJamselesai" onchange="javascript: hitungjam();" class="form-control" required="required">
<label>Difference (hours):<label>
<input type="text" id="inputSelisih">

代码的输出为8。因此,我推断由于z = x + y,所以尚未评估分配节点(对吗?)。但这不是意味着张量流的结果可能是错误的吗?这意味着我们需要在每次操作期间创建新节点,以强制TensorFlow计算导致结果的所有节点。但是,如果说用10000个步骤训练神经网络,如果每个步骤都创建了一组新的1000个权重/参数集,那么空间复杂性不会爆炸吗?

1 个答案:

答案 0 :(得分:2)

在您发布的摘录中,tf.control_dependencies没有任何作用。该函数会创建一个上下文,在该上下文中将创建新操作并具有对给定操作的控件依赖性,但是在您的代码中,上下文中没有新操作,仅是对先前现有操作的评估。

在大多数情况下,TensorFlow中的控制流是“显而易见的”,从某种意义上说,只有一种方法可以正确地进行计算。但是,当涉及有状态对象(即变量)时,有些情况可能会模棱两可。考虑以下示例:

import tensorflow as tf

v1 = tf.Variable(0)
v2 = tf.Variable(0)
upd1 = tf.assign(v1, v2 + 1)
upd2 = tf.assign(v2, v1 + 1)
init = tf.global_variables_initializer()

v1v2都被初始化为0,然后被更新。但是,每个更新都使用另一个变量的值。在常规的Python程序中,事物将按顺序运行,因此upd1将首先运行(因此v1将是1),之后是upd2(因此v2将是{ {1}},因为2v1)。但是TensorFlow不会记录操作的创建顺序,而只记录其依赖关系。因此也可能发生1upd2之前运行(因此upd1将是v1,而2将是v2),或者两者都更新值(1v2 + 1)是在分配之前计算的(因此v1 + 1v1都将最终为v2)。确实,如果我运行几次:

1

我并非总是会得到相同的结果(个人上我会得到for i in range(10): with tf.Session() as sess: sess.run(init) sess.run([upd1, upd2]) print(*sess.run([v1, v2])) 1 1,尽管从技术上讲2 1也是可能的)。例如,如果您想在1 2更新后为v2计算新值,则可以执行以下操作:

v1

这里,新值import tensorflow as tf v1 = tf.Variable(0) v2 = tf.Variable(0) upd1 = tf.assign(v1, v2 + 1) upd2 = tf.assign(v2, upd1 + 1) init = tf.global_variables_initializer() 是使用v2计算的,它保证是更新后变量的值。因此,upd1在这里将对该分配具有隐式依赖性,因此一切都会按预期进行。

但是,如果您想始终使用未更新的变量值来计算upd2v1的新值(也就是说,始终以v2和{{ 1}}是v1)?在这种情况下,您可以使用tf.control_dependencies

v2

在这里,只有在计算出1import tensorflow as tf v1 = tf.Variable(0) v2 = tf.Variable(0) new_v1 = v2 + 1 new_v2 = v1 + 1 with tf.control_dependencies([new_v1, new_v2]): upd1 = tf.assign(v1, new_v1) upd2 = tf.assign(v2, new_v2) init = tf.global_variables_initializer() 的新值之后,赋值操作才能发生,因此在两种情况下它们的最终值始终为v1