【问题标题】:Tensorflow's gradient_override_map functionTensorFlow 的 gradient_override_map 函数
【发布时间】:2017-05-14 11:42:50
【问题描述】:

有人可以解释一下 TensorFlow 中的 gradient_override_map 函数吗? 我无法准确理解它的用法。

我看到代码用法为:

with G.gradient_override_map({"Floor": "Identity"}):
    return tf.reduce_mean(SomeVals) * SomeOtherVal

这里到底发生了什么?什么是Identity

【问题讨论】:

  • 只是为了清楚起见,操作的命名“身份”并不重要。它正在改变块中所有身份操作的梯度操作

标签: python tensorflow


【解决方案1】:

“Floor”和“Identity”都是操作类型字符串,前者对应tf.floor,后者对应tf.identity所以我猜你的代码的作用是用tf.identity的反向传播梯度(简称BPG)计算机制代替tf.floor的BPG计算机制 图 G 中的操作,同时传递 tf.reduce_mean 的前向输出。这似乎有点奇怪,因为到目前为止我发现在gradient_override_map 的所有应用程序中, op_type_map 的键始终与用于在上下文中产生输出的操作的类型字符串相同。我的意思是我更熟悉返回tf.floor(SomeVals)而不是tf.reduce_mean(SomeVals)的场景。

gradient_override_map({op_A_type: op_B_type}) 所做的是将 op_A 的 BPG 计算机制替换为 op_B 的,同时保留 op_A_type 的前向传播计算机制。 lahwran 的回答中显示了 gradient_override_map 的常见应用。

@tf.RegisterGradient("CustomGrad")
def _const_mul_grad(unused_op, grad):
    return 5.0 * grad

g = tf.get_default_graph()
with g.gradient_override_map({"Identity": "CustomGrad"}):
    output = tf.identity(input, name="Identity")

通过

@tf.RegisterGradient("CustomGrad")
def _const_mul_grad(unused_op, grad):
    return 5.0 * grad

装饰器tf.RegisterGradient("CustomGrad")注册了_const_mul_grad(unused_op, grad)定义的渐变函数,用于自定义操作类型——“CustomGrad”,

同时

g = tf.get_default_graph()
with g.gradient_override_map({"Identity": "CustomGrad"}):
    output = tf.identity(input, name="Identity") 

保证字符串类型为“Identity”(tf.identity)的所有操作(在图 g 中)的输出与原样,而 tf.identity 的 BPG 计算机制s替换为字符串类型“CustomGrad”的BPG运算机制。

附:

  1. 操作的类型字符串对应于定义操作的原型的OpDef.name 字段。要查找操作的OpDef.name,请参考this question下的明星的回答

  2. 不需要声明 tf.identity 操作的名称,因为 tf.identity 中的 arg 'name' 是可选的。

【讨论】:

  • 我知道这只是一个例子,但是改变恒等函数的梯度是不是有点危险?我的意思是,恒等函数是你应该能够在不引起任何更改的情况下应用的函数,所以原则上它可以在任何 TF 函数中使用任意次数,因为它不会改变任何东西,对吧?改变它的梯度,让它突然产生效果,感觉可能会产生意想不到的后果。
  • @HelloGoodbye 你的担心是有道理的,计算图g中的恒等函数确实是手动编辑的。然而,它不是我们无法控制的,因为我们对 Opt 有所有了解:前向函数(保持不变),后向梯度(如我们定义的那样)。我们只需要格外小心地处理更改后的 Opt。
【解决方案2】:

据我所知,gradient_override_map 允许您说“在这种情况下,任何时候您将使用 X 的梯度,而不是使用 Y 的梯度”。这意味着您仍然需要 Y 的 gradient 作为您要使用的渐变。

这是我在寻找它的工作原理时看到的一个例子:

@tf.RegisterGradient("CustomGrad")
def _const_mul_grad(unused_op, grad):
    return 5.0 * grad

g = tf.get_default_graph()
with g.gradient_override_map({"Identity": "CustomGrad"}):
    output = tf.identity(input, name="Identity")

引用:https://stackoverflow.com/a/43948872/1102705

RegisterGradient() 允许您注册正在定义的新操作的渐变,从而允许您拥有具有所需渐变的操作,然后您可以在渐变覆盖图中使用该操作。这有点笨拙-您正在定义一个没有前向传递的操作。

我不清楚的是 name="Identity" 是否真的有必要。

【讨论】:

    猜你喜欢
    • 2019-09-09
    • 1970-01-01
    • 2017-03-04
    • 2018-07-23
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    相关资源
    最近更新 更多