【问题标题】:TensorFlow Variables and ConstantsTensorFlow 变量和常量
【发布时间】:2017-06-25 11:22:48
【问题描述】:

我是 tensorflow 的新手,我无法理解变量和常量的区别,我知道我们将变量用于方程,将常量用于直接值,但为什么代码 #1 只能工作,为什么不能代码# 2和#3,请解释在哪些情况下我们必须先运行图表(a)然后运行变量(b),即

 (a) session.run(model)
 (b) print(session.run(y))

在这种情况下我可以直接执行这个命令 即

print(session.run(y))

代码 #1:

x = tf.constant(35, name='x')
y = tf.Variable(x + 5, name='y')

model = tf.global_variables_initializer() 

with tf.Session() as session:
    session.run(model)
    print(session.run(y))

代码 #2:

x = tf.Variable(35, name='x')
y = tf.Variable(x + 5, name='y')

model = tf.global_variables_initializer() 

with tf.Session() as session:
    session.run(model)
    print(session.run(y))

代码 #3:

x = tf.constant(35, name='x')
y = tf.constant(x + 5, name='y')

model = tf.global_variables_initializer() 

with tf.Session() as session:
    session.run(model)
    print(session.run(y))

【问题讨论】:

  • 截至目前(2019 年 9 月),代码 #2 适用于 tensorflow 1.14

标签: python tensorflow


【解决方案1】:

在TensorFlow中,常量和变量的区别在于,当你声明一些constant时,它的值以后是不能改变的(同样初始化应该是带值的,不能带操作) >)。

不过,当你声明一个Variable时,你可以在以后通过tf.assign()方法改变它的值(并且可以通过一个值或操作来实现初始化)。

函数tf.global_variables_initializer()使用作为参数传递的值初始化代码中的所有变量,但它在异步模式下工作,因此当变量之间存在依赖关系时无法正常工作。

您的第一个代码 (#1) 可以正常工作,因为不依赖于变量初始化并且常量是用值构造的。

由于tf.global_variables_initializer() 的异步行为,第二个代码 (#2) 不起作用。您可以使用tf.variables_initializer() 修复它,如下所示:

x = tf.Variable(35, name='x')
model_x = tf.variables_initializer([x])

y = tf.Variable(x + 5, name='y')
model_y = tf.variables_initializer([y])


with tf.Session() as session:
   session.run(model_x)
   session.run(model_y)
   print(session.run(y))

第三个代码 (#3) 无法正常工作,因为您尝试使用操作初始化常量,这是不可能的。为了解决这个问题,一个合适的策略是 (#1)。

关于你的最后一个问题。当计算图中有变量(b) print(session.run(y))时,您需要运行(a) session.run(model)

【讨论】:

  • 还有1个问题,我知道'y'的值是在我们使用'session.run(y)'这个语句时计算出来的,那么运行'session.run的目的是什么? (model)',它不是执行图形来计算值吗?
  • 当你run一个变量时,它返回它的值。需要先初始化,所以是一个两阶段的过程。
  • 所以这条线'model = tf.global_variables_initializer()'的意思是,我只是将图/模型分配给名为'model'的变量,但是当我运行'session'时,这个图会执行/初始化变量.run(model)' 对吗?
  • 另外值得一提的是,不能用tf.train.Saver保存tf.constant
【解决方案2】:

我会指出使用急切执行时的区别。

从 Tensorflow 2.0.b1 开始,VariablesConstant 在使用 tf.GradientTape 时会触发不同的行为。奇怪的是,官方文件并没有足够的口头表达。

我们看https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/GradientTape中的示例代码

x = tf.constant(3.0)
with tf.GradientTape(persistent=True) as g:
  g.watch(x)
  y = x * x
  z = y * y
dz_dx = g.gradient(z, x)  # 108.0 (4*x^3 at x = 3)
dy_dx = g.gradient(y, x)  # 6.0
del g  # Drop the reference to the tape

你必须观看x,这是ConstantGradientTape 不会自动监视上下文中的常量。 此外,每个 GradientTape 只能监视一个张量。如果想得到多个Constants的渐变,需要嵌套GradientTapes。例如,

x = tf.constant(3.0)
x2 = tf.constant(3.0)
with tf.GradientTape(persistent=True) as g:
  g.watch(x)
  with tf.GradientTape(persistent=True) as g2:
    g2.watch(x2)

    y = x * x
    y2 = y * x2

dy_dx = g.gradient(y, x)       # 6
dy2_dx2 = g2.gradient(y2, x2)  # 9
del g, g2  # Drop the reference to the tape

另一方面,Variables 会被 GradientTape 自动监视。

默认情况下,GradientTape 将自动监视在上下文中访问的任何可训练变量。来源:https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/GradientTape

所以上面看起来像,

x = tf.Variable(3.0)
x2 = tf.Variable(3.0)
with tf.GradientTape(persistent=True) as g:
    y = x * x
    y2 = y * x2

dy_dx = g.gradient(y, x)       # 6
dy2_dx2 = g.gradient(y2, x2)   # 9
del g  # Drop the reference to the tape
print(dy_dx)
print(dy2_dx2)

当然,你可以通过watch_accessed_variables=False关闭自动观看。这些示例可能不太实用,但我希望这能消除某些人的困惑。

【讨论】:

  • 我很确定您可以将多个张量作为数组传递给 GradientTape.watch。也许自从你写这篇文章后 API 发生了变化
【解决方案3】:

查看差异的另一种方法是:

  1. tf.constant : 是固定值,因此不可训练。
  2. tf.Variable:这些是在会话中初始化并且可训练的张量(数组)(使用可训练意味着可以优化并且可以随时间改变)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    相关资源
    最近更新 更多