假设我想编写一个符合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_dense
或resource_apply_sparse
方法,但是有create_slots
和_resource_apply_sparse
method stub。
在正式的_resource_apply_sparse
子类中(以_create_slots
method call为例),有_create_slots
,tf.keras.optimizers.Optimizer
和tf.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
的正确方法是什么?具体来说,
tfa.optimizers.MovingAverage
文档是否仅是要覆盖它们提及的方法的前导下划线版本(例如,tf.keras.optimizers
而不是apply_gradients
)?如果是这样,是否有关于这些私有方法的API保证不会在TensorFlow的未来版本中更改其行为?这些方法的签名是什么?tf.keras.optimizers.Optimizer
方法之外,何时还会覆盖calls _create_slots
?Edit。在GitHub上发布的问题:_create_slots
tf.keras.optimizers.Optimizer
_create_slots
_create_slots
。一方面,如果您重写它,那么代码会提到每个副本的DistributionStrategy可能是“危险的”]apply_gradients
我已经在所有主要TF和Keras版本中实现了tf.keras.optimizers.Optimizer
-我邀请您检查tf.keras.optimizers.Optimizer
。几点:
_resource_apply_dense
,这实际上是您链接的内容;它是resource_apply_dense
优化器的最新和最新基类apply_gradients
(或任何其他方法)仅在默认值不能满足给定优化器所需的条件时才被覆盖;在您的链接示例中,它只是原始文件的一线附加程序_apply_resource_[dense|sparse]
方法,如果该子类未覆盖#36449”]]-两者是不相关的;这是巧合。 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.
。定义可训练的]时>optimizers_v2.pys;例如:重量的一阶和二阶矩(例如Adam)。它使用OptimizerV2
。
OptimizerV2
?相当多,每当不使用tf.keras
时;就像设置类属性一样,但是要执行额外的预处理步骤以确保用法的正确性。因此,Python apply_gradients
,_create_slots
,apply_gradients
等。 (我应该在Keras AdamW中更多地使用它。)>
注
_resource_apply_dense
)应为张量; _resource_apply_sparse
被定义为Embedding
,但在example方法中立即被覆盖为_create_slots()
。没什么大不了的,只是没有时间进行装修。