定制TensorFlow Keras优化器

问题描述 投票:27回答:2

假设我想编写一个符合tf.keras API的自定义优化器类(使用TensorFlow版本> = 2.0)。我对记录下来的实现方式与实现中的执行方式感到困惑。

tf.keras.optimizers.Optimizer states的文档,

  ### Write a customized optimizer.
  If you intend to create your own optimization algorithm, simply inherit from
  this class and override the following methods:

    - resource_apply_dense (update variable given gradient tensor is dense)
    - resource_apply_sparse (update variable given gradient tensor is sparse)
    - create_slots (if your optimizer algorithm requires additional variables)

但是,当前的tf.keras.optimizers.Optimizer实现未定义resource_apply_dense方法,但确实定义了看起来很私密的_resource_apply_dense method stub。同样,没有_resource_apply_denseresource_apply_sparse方法,但是有create_slots_resource_apply_sparse method stub

在正式的_resource_apply_sparse子类中(以_create_slots method call为例),有_create_slotstf.keras.optimizers.Optimizertf.keras.optimizers.Adam方法,没有前导下划线就没有这样的方法。

在不太正式的_resource_apply_dense子类中有类似的前导下划线方法(例如,来自TensorFlow Addons的_resource_apply_dense_resource_apply_sparse_resource_apply_sparse_create_slots)。

对我来说,另一个困惑点是,某些TensorFlow Addons优化器覆盖了_create_slots方法(例如tf.keras.optimizers.Optimizer),而tfa.optimizers.MovingAverage优化器则没有。

此外,我注意到_resource_apply_dense方法_resource_apply_dense_resource_apply_sparse方法,但是基类_resource_apply_sparse类没有_create_slots方法。因此,似乎在优化器子类中定义了_create_slots方法must,如果该子类未覆盖apply_gradients


问题

继承tfa.optimizers.MovingAverage的正确方法是什么?具体来说,

  1. 顶部列出的tfa.optimizers.MovingAverage文档是否仅是要覆盖它们提及的方法的前导下划线版本(例如,tf.keras.optimizers而不是apply_gradients)?如果是这样,是否有关于这些私有方法的API保证不会在TensorFlow的未来版本中更改其行为?这些方法的签名是什么?
  2. [tf.keras.optimizers.Optimizer方法之外,何时还会覆盖calls _create_slots

Edit。在GitHub上发布的问题:_create_slots

python tensorflow deep-learning tf.keras tensorflow2.x
2个回答
0
投票
  1. 是,这似乎是文档错误。前面的下划线名称是正确的重写方法。与此相关的是非Keras Optimizer,它具有所有定义,但未在基类tf.keras.optimizers.Optimizer
  2. 中实现
_create_slots
  1. 我不知道_create_slots。一方面,如果您重写它,那么代码会提到每个副本的DistributionStrategy可能是“危险的”]
apply_gradients

0
投票

我已经在所有主要TF和Keras版本中实现了tf.keras.optimizers.Optimizer-我邀请您检查tf.keras.optimizers.Optimizer。几点:

  • 您应该继承_resource_apply_dense,这实际上是您链接的内容;它是resource_apply_dense优化器的最新和最新基类
  • 您在(1)中是正确的-这是文档错误;这些方法是私有的,因为它们并不意味着用户直接使用它们。
  • apply_gradients(或任何其他方法)仅在默认值不能满足给定优化器所需的条件时才被覆盖;在您的链接示例中,它只是原始文件的一线附加程序
  • “因此,似乎必须在优化器子类中定义_apply_resource_[dense|sparse]方法,如果该子类未覆盖#36449”]]-两者是不相关的;这是巧合。

    • https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/training/optimizer.py def _create_slots(self, var_list): """Create all slots needed by the variables. Args: var_list: A list of `Variable` objects. """ # No slots needed by default pass def _resource_apply_dense(self, grad, handle): """Add ops to apply dense gradients to the variable `handle`. Args: grad: a `Tensor` representing the gradient. handle: a `Tensor` of dtype `resource` which points to the variable to be updated. Returns: An `Operation` which updates the value of the variable. """ raise NotImplementedError() def _resource_apply_sparse(self, grad, handle, indices): """Add ops to apply sparse gradients to the variable `handle`. Similar to `_apply_sparse`, the `indices` argument to this method has been de-duplicated. Optimizers which deal correctly with non-unique indices may instead override `_resource_apply_sparse_duplicate_indices` to avoid this overhead. Args: grad: a `Tensor` representing the gradient for the affected indices. handle: a `Tensor` of dtype `resource` which points to the variable to be updated. indices: a `Tensor` of integral type representing the indices for which the gradient is nonzero. Indices are unique. Returns: An `Operation` which updates the value of the variable. """ raise NotImplementedError() 有什么区别?

    后期处理sparse

层-例如apply_dense-以及其他所有内容; # TODO(isaprykin): When using a DistributionStrategy, and when an # optimizer is created in each replica, it might be dangerous to # rely on some Optimizer methods. When such methods are called on a # per-replica optimizer, an exception needs to be thrown. We do # allow creation per-replica optimizers however, because the # compute_gradients()->apply_gradients() sequence is safe.
  • 我何时应使用OptimizerV2

    相当多,每当不使用tf.keras时;就像设置类属性一样,但是要执行额外的预处理步骤以确保用法的正确性。因此,Python apply_gradients_create_slotsapply_gradients等。 (我应该在Keras AdamW中更多地使用它。)>


  • :虽然我的链接优化器可以正常工作并且与原始优化器一样快,但是代码遵循TensorFlow最佳实践,并且仍然可以更快;我不建议将其作为“理想参考”。例如。一些Python对象(例如_resource_apply_dense)应为张量; _resource_apply_sparse被定义为Embedding,但在example方法中立即被覆盖为_create_slots()。没什么大不了的,只是没有时间进行装修。
© www.soinside.com 2019 - 2024. All rights reserved.