如何在 keras 镜像策略中控制有状态指标的缩减策略



我使用keras方法fit()将自定义指标传递给模型。 度量是有状态的 - 即是Metric的子类,如 https://keras.io/api/metrics/#as-subclasses-of-metric-stateful 中所述 当我使用tf.distribute.MirroredStrategy()在多 GPU 环境中运行代码时,我的指标代码会在每个 GPU 上单独调用,并传递batch_size/no_of_gpus示例,这是合理的预期。

接下来发生的事情是,度量值的多个标量(每个 GPU 一个)需要减少到单个标量,而我一直得到的是sum减少,而我想控制它。 请记住,reduction参数是 keras 中的Loss参数之一,Metric类中没有这样的东西:https://github.com/tensorflow/tensorflow/blob/acbc065f8eb2ed05c7ab5c42b5c5bd6abdd2f91f/tensorflow/python/keras/metrics.py#L87

(我尝试的唯一疯狂的事情是从Mean类继承,该类是Metric的子类,但这并没有改变任何东西)

指标代码中提到了reduction,但这是对单个指标对象和多 GPU 设置中多个累积值的减少 - 事实并非如此,因为每个指标都在自己的 GPU 中工作,并且最终以某种方式聚合。

我调试它以了解这种行为的方式是 - 我在度量方法中打印形状和结果update_state。然后我在回调中查看了logs对象on_batch_end指标的值。

我尝试查看TF代码,但找不到发生这种情况的地方。 我希望能够控制这种行为 - 所以要么为指标选择"平均值"或"总和",要么至少知道它在代码中的位置。

编辑:我想这个 https://github.com/tensorflow/tensorflow/issues/39268 对这个问题有更多的了解

我面临着与您相同的问题(这就是我找到您的问题的原因)。

看到您提出问题已经 15 天了,还没有答案/评论,我想我可能会分享我的临时解决方法。

和您一样,我也认为在组合多个 GPU 的进度时已经执行了SUM缩减。我所做的是将 GPU 的数量(例如,由tf.distribute策略对象的num_replicas_in_sync属性给出)传递到子类化指标对象的__init__(...)构造函数中,并使用它来划分results()方法中的返回值。

您可能还可以使用指标对象中的tf.distribute.get_strategy()来使其"策略感知",并使用这些信息来决定如何以临时方式修改值,以便SUM缩减将产生您想要的结果。

我希望这现在有所帮助,无论是作为建议还是确认您并不孤单。

在实现 Keras Metric 类的子类时,必须正确覆盖 merge_state() 函数。如果不覆盖此函数,将使用默认实现 - 这是一个简单的总和。

请参阅:https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Metric

相关内容

  • 没有找到相关文章

最新更新