Supongamos que quiero escribir una clase optimizadora personalizada que se ajuste a la tf.keras
API (usando la versión TensorFlow> = 2.0). Estoy confundido acerca de la forma documentada de hacer esto frente a lo que se hace en las implementaciones.
La documentación para los tf.keras.optimizers.Optimizer
estados ,
### 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)
Sin embargo, la tf.keras.optimizers.Optimizer
implementación actual no define un resource_apply_dense
método, pero sí define un _resource_apply_dense
código auxiliar de aspecto privado . Del mismo modo, no hay resource_apply_sparse
o create_slots
métodos, pero hay un _resource_apply_sparse
código auxiliar de método y una _create_slots
llamada a método .
En oficiales tf.keras.optimizers.Optimizer
subclases (utilizando tf.keras.optimizers.Adam
como ejemplo), hay _resource_apply_dense
, _resource_apply_sparse
y _create_slots
métodos, y no hay tales métodos sin el carácter de subrayado líder.
Existen métodos similares líder-subrayado en ligeramente menos oficiales tf.keras.optimizers.Optimizer
subclases (por ejemplo, tfa.optimizers.MovingAverage
desde TensorFlow Addons: _resource_apply_dense
, _resource_apply_sparse
, _create_slots
).
Otro punto de confusión para mí es que algunos de los optimizadores de complementos de TensorFlow también anulan el apply_gradients
método (por ejemplo, tfa.optimizers.MovingAverage
), mientras que los tf.keras.optimizers
optimizadores no.
Además, noté que el apply_gradients
método de tf.keras.optimizers.Optimizer
método llama_create_slots
, pero la tf.keras.optimizers.Optimizer
clase base no tiene un _create_slots
método. Entonces, parece que un _create_slots
método debe definirse en una subclase de optimizador si esa subclase no anula apply_gradients
.
Preguntas
¿Cuál es la forma correcta de subclase a tf.keras.optimizers.Optimizer
? Específicamente,
- ¿La
tf.keras.optimizers.Optimizer
documentación enumerada en la parte superior simplemente significa anular las versiones de guión bajo de los métodos que mencionan (por ejemplo, en_resource_apply_dense
lugar deresource_apply_dense
)? Si es así, ¿hay alguna garantía API sobre estos métodos de aspecto privado que no cambian su comportamiento en futuras versiones de TensorFlow? ¿Cuáles son las firmas de estos métodos? - ¿Cuándo se anularía
apply_gradients
además de los_apply_resource_[dense|sparse]
métodos?
fuente
get_config
), pero que aún no deberían aparecer en la documentación pública ._resource_apply_dense
o_resource_apply_sparse
, y ver su uso en optimizadores implementados. Si bien puede no ser, creo, una API pública con garantías de estabilidad, diría que es bastante seguro usarlas. Simplemente deberían proporcionar una mejor orientación en este aspecto.Respuestas:
Implementé Keras AdamW en todas las versiones principales de TF & Keras. Los invito a examinar optimizers_v2.py . Varios puntos:
OptimizerV2
, que en realidad es lo que vinculaste; Es la clase base más reciente y actual paratf.keras
optimizadoresapply_gradients
(o cualquier otro método) solo se anula si el valor predeterminado no logra lo que se necesita para un optimizador dado; en su ejemplo vinculado, es solo un complemento de una línea al original_create_slots
método debe definirse en una subclase de optimizador si esa subclase no anulaapply_gradients
" - los dos no están relacionados; Es coincidencia._resource_apply_dense
y_resource_apply_sparse
?Último trata con capas dispersas , por ejemplo
Embedding
, y anterior con todo lo demás; ejemplo ._create_slots()
?Al definir s entrenables
tf.Variable
; ejemplo: momentos de primer y segundo orden de ponderaciones (por ejemplo, Adam). Lo utilizaadd_slot()
._set_hyper()
?Más o menos, cuando no se usa
_create_slots()
; es como establecer atributos de clase, pero con pasos de preprocesamiento adicionales para garantizar la corrección en el uso. Así Pythonint, float
,tf.Tensor
,tf.Variable
, y otros. (Debería haberlo usado más en Keras AdamW).Nota : aunque mis optimizadores vinculados funcionan correctamente y son casi tan rápidos como los originales, el código sigue las mejores prácticas de TensorFlow y aún puede ser más rápido; No lo recomiendo como la "referencia ideal". Por ejemplo, algunos objetos de Python (por ejemplo
int
) deberían ser tensores;eta_t
se define como atf.Variable
, pero se anula inmediatamente como atf.Tensor
en los_apply
métodos. No necesariamente es un gran problema, simplemente no he tenido tiempo para renovar.fuente
apply_dense
. Por un lado, si lo anula, el código menciona que una estrategia de distribución por réplica podría ser "peligrosa"fuente