【问题标题】:Unaggregated gradients / gradients per example in tensorflow张量流中每个示例的未聚合梯度/梯度
【发布时间】:2019-03-13 21:11:48
【问题描述】:

鉴于 tensorflow 中 mnist 上的一个简单的小批量梯度下降问题(例如在这个 tutorial 中),我如何分别检索批处理中每个示例的梯度。

tf.gradients() 似乎返回了批次中所有示例的平均梯度。有没有办法在聚合之前检索梯度?

编辑:迈向这个答案的第一步是弄清楚 tensorflow 在哪一点上对批次中示例的梯度进行平均。我以为这发生在_AggregatedGrads,但似乎并非如此。有什么想法吗?

【问题讨论】:

  • 听起来你想要一个雅可比,而不是渐变。

标签: tensorflow


【解决方案1】:

tf.gradients 返回相对于损失的梯度。这意味着如果您的损失是每个示例损失的总和,那么梯度也是每个示例损失梯度的总和。

总结是隐含的。例如,如果您想最小化 Wx-y 误差的平方范数之和,则相对于 W 的梯度为 2(WX-Y)X',其中 X 是观察批次,Y 是标签批次。您永远不会显式地形成稍后总结的“每个示例”梯度,因此移除梯度管道中的某个阶段并不是一件简单的事情。

获得k 每个示例损失梯度的一种简单方法是使用大小为 1 的批次并执行k 传递。 Ian Goodfellow wrote up 如何一次性获得所有 k 渐变,为此您需要明确指定渐变,而不是依赖 tf.gradients 方法

【讨论】:

  • 您可以使用 tf.gradients 完成大部分工作。假设您想要关于 X 的每个示例梯度。您在 X 的消费者上调用 tf.gradients。假设您有一个变量 Z,它是 X 乘以某个矩阵 W。那么您需要自己的逻辑来执行 per-通过矩阵乘法进行微分示例,但您可以使用 tf.gradients 获得关于 Z 的导数。
  • 谢谢!只是为了确保我正确理解这一点:这只适用于反向传播链中的第一个矩阵乘法,对吧?这意味着计算 MLP 中第一层权重的导数将需要实现几乎所有的 back prop 步骤。无论如何?
  • 如果损失是每个示例损失的总和,那么无论 tf.gradients 计算正确的东西,即每个示例损失梯度的总和,都没有问题。问题是,当“损失”是一个为每个示例返回一个标量的函数时。
【解决方案2】:

在修补了一段时间后,部分回答了我自己的问题。似乎可以通过执行以下操作来处理每个示例的梯度,同时仍然可以批量工作:

  • 创建一个 tf.gradients() 的副本,该副本接受具有示例特定因子的额外张量/占位符
  • 创建 _AggregatedGrads() 的副本并添加使用示例特定因素的自定义聚合方法
  • 调用您的自定义 tf.gradients 函数并将损失作为切片列表给出:

custagg_gradients( ys=[cross_entropy[i] for i in xrange(batch_size)],
xs=variables.trainable_variables(), aggregation_method=CUSTOM, gradient_factors=gradient_factors )

但这可能与每个示例进行单独传递具有相同的复杂性,我需要检查渐变是否正确:-)。

【讨论】:

    【解决方案3】:

    在聚合之前检索梯度的一种方法是使用grads_ys 参数。在这里可以找到一个很好的讨论:

    Use of grads_ys parameter in tf.gradients - TensorFlow

    编辑:

    我最近没有经常使用 Tensorflow,但这里有一个未解决的问题,用于跟踪计算未聚合梯度的最佳方法:

    https://github.com/tensorflow/tensorflow/issues/675

    有很多用户(包括我自己)提供的示例代码解决方案,您可以根据自己的需要进行尝试。

    【讨论】:

    • 你能详细说明一下吗?也许提供一个代码示例,说明如何使用这种方法获得单个示例渐变?
    猜你喜欢
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 2020-12-10
    • 2023-03-27
    • 1970-01-01
    • 2016-09-12
    • 2018-03-28
    相关资源
    最近更新 更多