Supposons que je veuille écrire une classe d'optimiseur personnalisée conforme à l' tf.keras
API (en utilisant la version TensorFlow> = 2.0). Je suis confus quant à la façon documentée de le faire par rapport à ce qui est fait dans les implémentations.
La documentation pour les tf.keras.optimizers.Optimizer
états ,
### 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)
Cependant, le courant tf.keras.optimizers.Optimizer
mise en œuvre ne définit pas une resource_apply_dense
méthode, mais elle ne définit un privé à la recherche _resource_apply_dense
stub de la méthode . De même, il n'y a pas resource_apply_sparse
ou create_slots
méthodes, mais il y a un _resource_apply_sparse
bout de méthode et un _create_slots
appel de méthode .
Dans officielles tf.keras.optimizers.Optimizer
sous - classes ( en utilisant tf.keras.optimizers.Adam
comme exemple), il existe _resource_apply_dense
, _resource_apply_sparse
et les _create_slots
méthodes, et il n'y a pas de telles méthodes sans le trait de soulignement de premier plan.
Il existe des méthodes d' avant-underscore similaires légèrement moins officielles tf.keras.optimizers.Optimizer
sous - classes (par exemple, tfa.optimizers.MovingAverage
de tensorflow addons: _resource_apply_dense
, _resource_apply_sparse
, _create_slots
).
Un autre point de confusion pour moi est que certains des optimiseurs TensorFlow Addons remplacent également la apply_gradients
méthode (par exemple, tfa.optimizers.MovingAverage
), contrairement aux tf.keras.optimizers
optimiseurs.
De plus, j'ai remarqué que la apply_gradients
méthode des appels de tf.keras.optimizers.Optimizer
méthode , mais la classe de base n'a pas de méthode. Il semble donc qu'une méthode doit être définie dans une sous-classe d'optimiseur si cette sous-classe ne remplace pas ._create_slots
tf.keras.optimizers.Optimizer
_create_slots
_create_slots
apply_gradients
Des questions
Quelle est la bonne façon de sous-classer a tf.keras.optimizers.Optimizer
? Plus précisément,
- La
tf.keras.optimizers.Optimizer
documentation répertoriée en haut signifie-t-elle simplement remplacer les versions de soulignement principal des méthodes qu'elles mentionnent (par exemple,_resource_apply_dense
au lieu deresource_apply_dense
)? Dans l'affirmative, existe-t-il des garanties API quant à ces méthodes d'apparence privée ne modifiant pas leur comportement dans les futures versions de TensorFlow? Quelles sont les signatures de ces méthodes? - Quand remplacerait-on
apply_gradients
en plus des_apply_resource_[dense|sparse]
méthodes?
la source
get_config
), mais ils ne devraient pas encore apparaître dans la documentation publique ._resource_apply_dense
ou_resource_apply_sparse
, et voir leur utilisation dans les optimiseurs implémentés. Bien que ce ne soit pas, je pense, une API publique avec des garanties de stabilité, je dirais que c'est assez sûr de les utiliser. Ils devraient juste fournir une meilleure orientation à cet égard.Réponses:
J'ai implémenté Keras AdamW dans toutes les principales versions de TF et Keras - je vous invite à examiner optimizers_v2.py . Plusieurs points:
OptimizerV2
, qui est en fait ce que vous avez lié; c'est la classe de base la plus récente et actuelle pour lestf.keras
optimiseursapply_gradients
(ou toute autre méthode) n'est remplacée que si la valeur par défaut n'accomplit pas ce qui est nécessaire pour un optimiseur donné; dans votre exemple lié, c'est juste un addon à une ligne à l'original_create_slots
méthode doit être définie dans une sous-classe d'optimiseur si cette sous-classe ne remplace pasapply_gradients
" - les deux ne sont pas liées; c'est une coïncidence._resource_apply_dense
et_resource_apply_sparse
?Ces dernières traitent des couches clairsemées - par exemple
Embedding
- et les premières de tout le reste; exemple ._create_slots()
?Lors de la définition entraînables
tf.Variable
s; exemple: poids des moments du premier et du second ordre (par exemple Adam). Il utiliseadd_slot()
._set_hyper()
?À peu près, chaque fois que vous n'utilisez pas
_create_slots()
; c'est comme définir des attributs de classe, mais avec des étapes de prétraitement supplémentaires pour garantir l'exactitude de l'utilisation. Alors Pythonint, float
,tf.Tensor
,tf.Variable
, et d' autres. (J'aurais dû l'utiliser plus dans Keras AdamW).Remarque : alors que mes optimiseurs liés fonctionnent correctement et sont à peu près aussi rapides que les originaux, le code suit les meilleures pratiques TensorFlow et peut toujours être plus rapide; Je ne le recommande pas comme «référence idéale». Par exemple, certains objets Python (par exemple
int
) devraient être des tenseurs;eta_t
est définie comme unetf.Variable
, mais est immédiatement remplacée par une méthodetf.Tensor
in_apply
. Pas forcément un gros problème, je n'ai tout simplement pas eu le temps de rénover.la source
apply_dense
. D'une part, si vous le remplacez, le code mentionne qu'une DistributionStrategy par réplique peut être "dangereuse"la source