我试图更深入地了解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个权重/参数集,那么空间复杂性不会爆炸吗?
答案 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()
v1
和v2
都被初始化为0
,然后被更新。但是,每个更新都使用另一个变量的值。在常规的Python程序中,事物将按顺序运行,因此upd1
将首先运行(因此v1
将是1
),之后是upd2
(因此v2
将是{ {1}},因为2
是v1
)。但是TensorFlow不会记录操作的创建顺序,而只记录其依赖关系。因此也可能发生1
在upd2
之前运行(因此upd1
将是v1
,而2
将是v2
),或者两者都更新值(1
和v2 + 1
)是在分配之前计算的(因此v1 + 1
和v1
都将最终为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
在这里将对该分配具有隐式依赖性,因此一切都会按预期进行。
但是,如果您想始终使用未更新的变量值来计算upd2
和v1
的新值(也就是说,始终以v2
和{{ 1}}是v1
)?在这种情况下,您可以使用tf.control_dependencies
:
v2
在这里,只有在计算出1
和import 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
。