Załóżmy, że chcę napisać niestandardową klasę optymalizatora zgodną z tf.keras
interfejsem API (używając wersji TensorFlow> = 2.0). Jestem zdezorientowany co do udokumentowanego sposobu wykonania tej czynności w porównaniu z tym, co zostało zrobione we wdrożeniach.
Dokumentacja tf.keras.optimizers.Optimizer
stanów ,
### 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)
Jednak obecna tf.keras.optimizers.Optimizer
implementacja nie definiuje resource_apply_dense
metody, ale nie definiują prywatną wyglądające _resource_apply_dense
metody niedopałek . Podobnie nie ma metod resource_apply_sparse
ani create_slots
metod, ale istnieją kody pośredniczące _resource_apply_sparse
metod i _create_slots
wywołanie metod .
Oficjalnych tf.keras.optimizers.Optimizer
podklasy (stosując tf.keras.optimizers.Adam
jako przykład), są _resource_apply_dense
, _resource_apply_sparse
, i _create_slots
sposobów, i nie ma takiej metody bez początkowego podkreślenia.
Istnieją podobne metody wiodące podkreślenia w nieznacznie mniej oficjalnych tf.keras.optimizers.Optimizer
podklasy (np tfa.optimizers.MovingAverage
z TensorFlow dodatki: _resource_apply_dense
, _resource_apply_sparse
, _create_slots
).
Innym mylącym dla mnie punktem jest to, że niektóre optymalizatory TensorFlow Addons również zastępują apply_gradients
metodę (np. tfa.optimizers.MovingAverage
), Podczas gdy tf.keras.optimizers
optymalizatory nie.
Ponadto zauważyłem, że apply_gradients
metody tf.keras.optimizers.Optimizer
metody połączeń_create_slots
, ale podstawa tf.keras.optimizers.Optimizer
klasa nie ma _create_slots
metody. Wygląda więc na to, że należy zdefiniować _create_slots
metodę w podklasie optymalizatora, jeśli ta podklasa się nie przesłoni .apply_gradients
pytania
Jaki jest prawidłowy sposób na podklasę a tf.keras.optimizers.Optimizer
? Konkretnie,
- Czy
tf.keras.optimizers.Optimizer
dokumentacja wymieniona u góry oznacza po prostu zastąpienie wiodących wersji podkreślonych metod, o których wspominają (np._resource_apply_dense
Zamiastresource_apply_dense
)? Jeśli tak, to czy są jakieś gwarancje API, że te prywatne metody nie zmieniają swojego zachowania w przyszłych wersjach TensorFlow? Jakie są podpisy tych metod? - Kiedy można zastąpić metody
apply_gradients
oprócz_apply_resource_[dense|sparse]
metod?
Edytować. Otwarty problem w GitHub: # 36449
źródło
get_config
), ale wtedy nie powinny jeszcze pojawić się w dokumentacji publicznej ._resource_apply_dense
lub_resource_apply_sparse
i zobaczyć ich użycie w zaimplementowanych optymalizatorach. Wydaje mi się, że nie może to być publiczny interfejs API z gwarancjami stabilności, ale powiedziałbym, że korzystanie z nich jest całkiem bezpieczne. Powinny po prostu zapewnić lepsze wytyczne w tym zakresie.Odpowiedzi:
Zaimplementowałem Keras AdamW we wszystkich głównych wersjach TF i Keras - zapraszam do zapoznania się z optimizers_v2.py . Kilka punktów:
OptimizerV2
, czyli tak naprawdę to, co połączyłeś; to najnowsza i aktualna klasa bazowa dlatf.keras
optymalizatorówapply_gradients
(lub dowolna inna metoda) jest zastępowana tylko wtedy, gdy domyślna wartość nie spełnia wymagań danego optymalizatora; w połączonym przykładzie jest to tylko jedno-liniowy dodatek do oryginału_create_slots
należy zdefiniować metodę w podklasie optymalizatora, jeśli podklasa ta nie zastępujeapply_gradients
” - obie są ze sobą niezwiązane; to przypadek._resource_apply_dense
i_resource_apply_sparse
?Później zajmuje się rzadkimi warstwami - np.
Embedding
- a wcześniej wszystkim innym; przykładem ._create_slots()
?Podczas definiowania treningów
tf.Variable
; przykład: momenty pierwszego i drugiego rzędu wag (np. Adam). Używaadd_slot()
._set_hyper()
?Prawie, ilekroć nie używasz
_create_slots()
; to jak ustawianie atrybutów klasy, ale z dodatkowymi krokami wstępnego przetwarzania, aby zapewnić poprawność użycia. Więc Pythonint, float
,tf.Tensor
,tf.Variable
, i inni. (Powinienem był użyć go częściej w Keras AdamW).Uwaga : chociaż moje powiązane optymalizatory działają poprawnie i są tak szybkie jak oryginały, kod postępuje zgodnie z najlepszymi praktykami TensorFlow i wciąż może być szybszy; Nie polecam tego jako „idealnego odniesienia”. Np. Niektóre obiekty Pythona (np.
int
) Powinny być tensorami;eta_t
jest zdefiniowany jakotf.Variable
, ale natychmiast zastąpiony jakotf.Tensor
w_apply
metodach. Niekoniecznie wielka sprawa, po prostu nie miałem czasu na remont.źródło
apply_dense
. Po pierwsze, jeśli go przesłonisz, kod wspomina, że strategia dystrybucji dla repliki może być „niebezpieczna”źródło