- 创建计算图而不是直接执行计算的主要好处是什么?主要缺点是什么?
-
主要好处:
TensorFlow可以自动计算梯度(使用逆模式自动编排)。
TensorFlow可以在不同的线程中并行运行操作。它使在不同设备上运行相同模型变得更加容易。
它简化了内省 - 例如,在TensorBoard中查看模型。 主要缺点:
它使学习曲线更加陡峭。
它使逐步调试变得更加困难。
语句
a_val = a.eval(session = sess)
是否等同于a_val = sess.run(a)
?
是的语句
a_val,b_val = a.eval(session = sess),b.eval(session = sess)
是否等价于a_val,b_val = sess.run([a,b])
?
不等价
实际上,第一个语句运行图形两次(一次计算a,一次计算b),而第二个语句只运行图形一次。如果这些操作中的任何一个(或它们所依赖的操作)具有副作用(例如,变量被修改,项目被插入队列中,或者读取器读取文件),那么效果将是不同的。如果它们没有副作用,则两个语句将返回相同的结果,但第二个语句将比第一个语句更快。你能在同一个会话中运行两个图吗?
不可以,你不能在同一会话中运行两个图表。你必须首先将图形合并为单个图形。如果创建包含变量w的图形 g,然后启动两个线程并在每个线程中打开一个会话,两个都使用相同的图g,每个会话都有自己的变量w副本还是会被共享?
在本地TensorFlow中,会话管理变量值,因此如果你创建图g包含变量w,然后启动两个线程并在每个线程中打开一个本地会话线程,都使用相同的图 g,然后每个会话将有自己的副本变量w。
但是,在分布式TensorFlow中,变量值存储在由集群管理的容器中,因此如果两个会话连接到同一个集群并使用相同的容器,则它们将共享w的相同变量值。什么时候变量初始化?什么时候被destroy?
调用其初始化程序时初始化变量,它会在会话结束时被destroy。
在分布式TensorFlow中,变量存在于集群中的容器中,因此关闭会话不会破坏变量。 要销毁变量,你需要清除其容器。
7.占位符和变量之间有什么区别?
变量和占位符非常不同,但是初学者经常会混淆他们:
- 变量是保存值的操作。如果运行变量,则返回该值。在运行它之前,你需要初始化它。你可以更改变量的值(例如,通过使用赋值操作)。它是有状态的:变量在连续运行图形时保持相同的值。它通常用于保存模型参数,但也用于其他目的(例如,对全局训练步数进行计数)。
- 占位符在技术上做不了多少:它们只保存有关它们所代表的张量的类型和形状的信息,但它们没有任何价值。实际上,如果你尝试评估依赖于占位符的操作,则必须提供TensorFlow占位符的值(使用feed_dict参数),否则你将获得异常。占位符通常用于在执行阶段将训练或测试数据提供给TensorFlow。它们也可用于将值传递给赋值节点,以更改变量的值(例如,模型权重)。
运当你运行图表来评估依赖于占位符但不提供其值的操作时? 如果操作不依赖于占位符会发生什么?
如果运行图形来评估依赖于占位符但不提供其值的操作,则会出现异常。如果操作不依赖于占位符,则不会引发异常。运行图形时,是否可以提供任何操作的输出值,或者只是占位符的值?
运行图形时,可以提供任何操作给输出值,而不仅仅是占位符的值。然而,在实践中,这是相当罕见的(它可能是有用的,例如,当你缓存冻结层的输出时;见第11章)。如何将变量设置为你想要的任何值(在执行阶段)?
你可以在构造图形时指定变量的初始值,稍后在执行阶段运行变量的初始化程序时将对其进行初始化。
如果要在执行阶段将该变量的值更改为你想要的任何值,那么最简单的选项是创建一个赋值节点(在图形构建阶段)使用
tf.assign()
函数,传递变量和占位符作为参数。在执行阶段,你可以运行赋值操作并使用占位符提供变量的新值。
import tensorflow as tf
x = tf.Variable(tf.random_uniform(shape=(), minval=0.0, maxval=1.0))
x_new_val = tf.placeholder(shape=(), dtype=tf.float32)
x_assign = tf.assign(x, x_new_val)
with tf.Session():
x.initializer.run() # random number is sampled *now*
print(x.eval()) # 0.646157 (some random number)
x_assign.eval(feed_dict={x_new_val: 5.0})
print(x.eval()) # 5.0
-
reverse-mode autodiff需要遍历图表多少次才能计算成本函数相对于10个变量的梯度?
那么forward-mode autodiff呢? symbolic differentiation呢?
reverse-mode autodiff(由TensorFlow实现)需要仅遍历图形两次,以便计算关于任意数量的变量的成本函数的梯度。
forward-mode autodifff需要为每个变量运行一次(如果我们想要关于10个不同变量的梯度,则需要运行10次)。
symbolic differentiation会构建一个不同的图来计算梯度,因此它根本不会遍历原始图(除了构建新的渐变图时)。
高度优化的symbolic differentiation系统可能只运行一次新的梯度图来计算关于所有变量的梯度,但是与原始图相比,新图可能非常复杂且效率低。