gpt4 book ai didi

tensorflow - GradientTape、implicit_gradients、gradients_function 和implicit_value_and_gradients 之间有什么区别?

转载 作者:行者123 更新时间:2023-12-03 00:45:08 25 4
gpt4 key购买 nike

我正在尝试切换到 TensorFlow 热切模式,我找到了 GradientTape 的文档, implicit_gradients , gradients_functionimplicit_value_and_gradients令人困惑。

它们之间有什么区别?我什么时候应该使用一个?

intro point in the documentation根本没有提到隐式*函数,但几乎 TensorFlow 存储库中的所有示例似乎都使用该方法来计算梯度。

最佳答案

当启用 Eager Execution 时,有 4 种方法可以自动计算梯度(实际上,它们也可以在图形模式下工作):

  • tf.GradientTape上下文记录计算,以便您可以调用 tfe.gradient()获取在记录任何可训练变量时计算的任何张量的梯度。
  • tfe.gradients_function()接受一个函数(比如 f() )并返回一个梯度函数(比如 fg() ),它可以计算 f() 的输出的梯度关于f()的参数(或其中的一个子集)。
  • tfe.implicit_gradients()非常相似,但 fg()计算 f() 的输出梯度关于这些输出所依赖的所有可训练变量。
  • tfe.implicit_value_and_gradients()几乎相同,但 fg()还返回函数 f() 的输出.

  • 通常,在机器学习中,您会想要计算关于模型参数(即变量)的损失梯度,并且您通常也会对损失本身的值感兴趣。对于这个用例,最简单和最有效的选项是 tf.GradientTapetfe.implicit_value_and_gradients() (另外两个选项不会给你损失本身的值(value),所以如果你需要它,它将需要额外的计算)。我个人更喜欢 tfe.implicit_value_and_gradients()编写生产代码时,和 tf.GradientTape在 Jupyter 笔记本中进行实验时。

    编辑 : 在TF 2.0中,似乎只有 tf.GradientTape遗迹。也许其他功能会被添加回来,但我不会指望它。

    详细示例

    让我们创建一个小函数来突出差异:
    import tensorflow as tf
    import tensorflow.contrib.eager as tfe
    tf.enable_eager_execution()

    w1 = tfe.Variable(2.0)
    w2 = tfe.Variable(3.0)

    def weighted_sum(x1, x2):
    return w1 * x1 + w2 * x2

    s = weighted_sum(5., 7.)
    print(s.numpy()) # 31

    使用 tf.GradientTape
    GradientTape上下文,所有操作都被记录下来,然后你可以计算上下文中计算的任何张量的梯度,关于任何可训练的变量。例如,此代码计算 sGradientTape上下文,然后计算 s 的梯度关于 w1 .自 s = w1 * x1 + w2 * x2s的梯度关于 w1x1 :
    with tf.GradientTape() as tape:
    s = weighted_sum(5., 7.)

    [w1_grad] = tape.gradient(s, [w1])
    print(w1_grad.numpy()) # 5.0 = gradient of s with regards to w1 = x1

    使用 tfe.gradients_function()
    此函数返回另一个函数,该函数可以计算函数返回值相对于其参数的梯度。例如,我们可以用它来定义一个函数来计算 s 的梯度。关于 x1x2 :
    grad_fn = tfe.gradients_function(weighted_sum)
    x1_grad, x2_grad = grad_fn(5., 7.)
    print(x1_grad.numpy()) # 2.0 = gradient of s with regards to x1 = w1

    在优化的背景下,关于我们可以调整的变量计算梯度会更有意义。为此,我们可以更改 weighted_sum()取函数 w1w2作为参数,并告诉 tfe.gradients_function()只考虑名为 "w1" 的参数和 "w2" :
    def weighted_sum_with_weights(w1, x1, w2, x2):
    return w1 * x1 + w2 * x2

    grad_fn = tfe.gradients_function(weighted_sum_with_weights, params=["w1", "w2"])
    [w1_grad, w2_grad] = grad_fn(w1, 5., w2, 7.)
    print(w2_grad.numpy()) # 7.0 = gradient of s with regards to w2 = x2

    使用 tfe.implicit_gradients()
    此函数返回另一个函数,该函数可以计算函数返回值相对于它所依赖的所有可训练变量的梯度。回到 weighted_sum()的第一个版本,我们可以用它来计算 s 的梯度关于 w1w2无需显式传递这些变量。请注意,梯度函数返回一个梯度/变量对列表:
    grad_fn = tfe.implicit_gradients(weighted_sum)
    [(w1_grad, w1_var), (w2_grad, w2_var)] = grad_fn(5., 7.)
    print(w1_grad.numpy()) # 5.0 = gradient of s with regards to w1 = x1

    assert w1_var is w1
    assert w2_var is w2

    这个函数似乎是最简单和最有用的选项,因为通常我们对计算关于模型参数(即变量)的损失梯度感兴趣。
    注意:尝试制作 w1无法训练 ( w1 = tfe.Variable(2., trainable=False) ) 并重新定义 weighted_sum() ,你会看到 grad_fn只返回 s 的梯度关于 w2 .

    使用 tfe.implicit_value_and_gradients()
    此功能与 implicit_gradients() 几乎相同除了它创建的函数还返回被微分的函数的结果(在这种情况下 weighted_sum() ):
    grad_fn = tfe.implicit_value_and_gradients(weighted_sum)
    s, [(w1_grad, w1_var), (w2_grad, w2_var)] = grad_fn(5., 7.)
    print(s.numpy()) # 31.0 = s = w1 * x1 + w2 * x2

    当你需要一个函数的输出和它的梯度时,这个函数可以给你一个很好的性能提升,因为在使用 autodiff 计算梯度时你可以免费获得函数的输出。

    关于tensorflow - GradientTape、implicit_gradients、gradients_function 和implicit_value_and_gradients 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50098971/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com