Angenommen, ich möchte eine benutzerdefinierte Optimierungsklasse schreiben, die der tf.keras
API entspricht (mit TensorFlow-Version> = 2.0). Ich bin verwirrt über die dokumentierte Vorgehensweise im Vergleich zu den Implementierungen.
Die Dokumentation für tf.keras.optimizers.Optimizer
Staaten ,
### 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)
Doch die aktuelle tf.keras.optimizers.Optimizer
ist die Umsetzung eine nicht definieren resource_apply_dense
Methode, aber es hat definiert einen privaten aussehende _resource_apply_dense
Methode Stummel . Ebenso gibt es keine resource_apply_sparse
oder create_slots
Methoden, aber es gibt einen _resource_apply_sparse
Methodenstub und einen _create_slots
Methodenaufruf .
In offiziellen tf.keras.optimizers.Optimizer
Unterklassen (unter Verwendung tf.keras.optimizers.Adam
als ein Beispiel), gibt es _resource_apply_dense
, _resource_apply_sparse
und _create_slots
Methoden, und es gibt keine solche Methoden ohne den führenden Unterstrich.
Es gibt ähnliche leading-Unterstreichungsverfahren in etwas weniger amtlichen tf.keras.optimizers.Optimizer
Subklassen (zB tfa.optimizers.MovingAverage
von TensorFlow Addons: _resource_apply_dense
, _resource_apply_sparse
, _create_slots
).
Ein weiterer verwirrender Punkt für mich ist, dass einige der TensorFlow Addons-Optimierer die Methode ebenfalls überschreiben apply_gradients
(z. B. tfa.optimizers.MovingAverage
), während die tf.keras.optimizers
Optimierer dies nicht tun.
Außerdem bemerkte ich , dass die apply_gradients
Methode der tf.keras.optimizers.Optimizer
Methode Anrufe_create_slots
, aber die tf.keras.optimizers.Optimizer
Basisklasse keine hat _create_slots
Methode. Es scheint also, dass eine _create_slots
Methode in einer Optimierer-Unterklasse definiert werden muss , wenn diese Unterklasse nicht überschreibt apply_gradients
.
Fragen
Was ist der richtige Weg, um eine Unterklasse a tf.keras.optimizers.Optimizer
? Speziell,
- Bedeutet die oben
tf.keras.optimizers.Optimizer
aufgeführte Dokumentation lediglich, die führenden Unterstrichversionen der von ihnen erwähnten Methoden zu überschreiben (z. B._resource_apply_dense
anstelle vonresource_apply_dense
)? Wenn ja, gibt es API-Garantien dafür, dass diese privat aussehenden Methoden ihr Verhalten in zukünftigen Versionen von TensorFlow nicht ändern? Was sind die Signaturen dieser Methoden? - Wann würde man
apply_gradients
zusätzlich zu den_apply_resource_[dense|sparse]
Methoden überschreiben ?
Bearbeiten. Geöffnetes Problem auf GitHub: # 36449
quelle
get_config
), aber dann sollten sie noch nicht in der öffentlichen Dokumentation erscheinen ._resource_apply_dense
oder_resource_apply_sparse
einsehen und deren Verwendung in implementierten Optimierern sehen. Ich denke, es ist zwar keine öffentliche API mit Stabilitätsgarantien, aber ich würde sagen, es ist ziemlich sicher, sie zu verwenden. Sie sollten in dieser Hinsicht nur eine bessere Anleitung geben.Antworten:
Ich habe Keras AdamW in allen wichtigen TF- und Keras-Versionen implementiert. Ich lade Sie ein, optimizers_v2.py zu untersuchen . Mehrere Punkte:
OptimizerV2
, was eigentlich das ist, was Sie verlinkt haben; Es ist die neueste und aktuelle Basisklasse fürtf.keras
Optimiererapply_gradients
(oder eine andere Methode) wird nur überschrieben, wenn die Standardeinstellung nicht die Anforderungen für einen bestimmten Optimierer erfüllt. In Ihrem verknüpften Beispiel handelt es sich nur um ein Einzeiler-Addon zum Original_create_slots
Methode in einer Optimierer-Unterklasse definiert werden muss, wenn diese Unterklasse nicht überschreibtapply_gradients
" - die beiden sind nicht miteinander verbunden. es ist zufällig._resource_apply_dense
und_resource_apply_sparse
?Letzteres befasst sich mit spärlichen Schichten - zB
Embedding
- und erstere mit allem anderen; Beispiel ._create_slots()
?Bei der Definition von trainierbaren
tf.Variable
s; Beispiel: Momente erster und zweiter Ordnung der Gewichte (z. B. Adam). Es verwendetadd_slot()
._set_hyper()
?Ziemlich genau, wenn man es nicht benutzt
_create_slots()
; Es ist wie beim Festlegen von Klassenattributen, jedoch mit zusätzlichen Vorverarbeitungsschritten, um die Richtigkeit der Verwendung sicherzustellen. So Pythonint, float
,tf.Tensor
,tf.Variable
, und andere. (Ich hätte es mehr in Keras AdamW verwenden sollen).Hinweis : Während meine verknüpften Optimierer ordnungsgemäß funktionieren und ungefähr so schnell wie die Originale sind, folgt der Code den besten TensorFlow-Praktiken und kann immer noch schneller sein. Ich empfehle es nicht als "ideale Referenz". ZB sollten einige Python-Objekte (z. B.
int
) Tensoren sein;eta_t
wird als a definierttf.Variable
, aber sofort alstf.Tensor
in-_apply
Methoden überschrieben . Nicht unbedingt eine große Sache, hatte nur keine Zeit zu renovieren.quelle
apply_dense
. Zum einen wird im Code erwähnt, dass eine DistributionStrategy pro Replikat "gefährlich" sein kann, wenn Sie sie überschreiben.quelle