tensorflow: cómo controlar la estrategia de reducción para métricas con estado en la estrategia reflejada de keras

CorePress2024-01-16  7

Utilizo el método keras fit() con métricas personalizadas pasadas al modelo. Las métricas tienen estado, es decir, son una subclase de una métrica, como se describe en https://keras.io/api/metrics/#as-subclasses-of-metric-stateful Cuando ejecuto el código en un entorno de múltiples GPU usando tf.distribute.MirroredStrategy(), mi código métrico se llama en cada GPU por separado con ejemplos de tamaño de lote/no_of_gpus pasados, lo cual es razonable esperar.

Lo que sucede a continuación es que varios escalares (uno de cada GPU) del valor métrico deben reducirse a un único escalar, y lo que obtengo todo el tiempo es una reducción de la suma, aunque a mí me gustaría controlar eso. Tenga en cuenta que ese parámetro de reducción es el de Pérdida en keras, y no existe tal cosa en la clase Metric: https://github.com/tensorflow/tensorflow/blob/acbc065f8eb2ed05c7ab5c42b5c5bd6abdd2f91f/tensorflow/python/keras/metrics.py#L87

(la única locura que intenté fue heredar de una clase Media que es una subclase de una Métrica pero eso no cambió nada)

La reducción se menciona en el código de métricas, sin embargo, se trata de una reducción sobre múltiples valores acumulados en un solo objeto de métrica y en una configuración de múltiples GPU; este no es el caso, ya que cada métrica funciona en su propia GPU y de alguna manera agregado al final.

La forma en que lo depuré para comprender este comportamiento fue: estaba imprimiendo las formas y los resultados dentro del método update_state de la métrica. Y luego miré el valor de la métrica en el objeto de registros en la devolución de llamada on_batch_end.

Intenté buscar el código TF, pero no pude encontrar el lugar donde sucede esto. IMe gustaría poder controlar este comportamiento, así que elija 'media' o 'suma' para la métrica, o al menos sepa dónde se hace en el código.

Editado: supongo que este https://github.com/tensorflow/tensorflow/issues/39268 arroja algo más de luz sobre este problema



------------------------------------

Estoy enfrentando el mismo problema que tú (y es por eso que encontré tu pregunta).

Viendo que han pasado 15 días desde que hiciste la pregunta y todavía no hay respuestas ni comentarios, pensé en compartir mi solución temporal.

Al igual que usted, también creo que se ha realizado una reducción de SUM al combinar el progreso en varias GPU.Lo que hice fue pasar la cantidad de GPU (por ejemplo, dada por el atributo num_replicas_in_sync de su objeto de estrategia tf.distribute) al constructor __init__(...) de su objeto métrico subclasificado y usarlo para dividir el valor de retorno. en el método resultados().

Potencialmente, también podría usar tf.distribute.get_strategy() desde dentro del objeto métrico para que sea "consciente de la estrategia" y usar la información para decidir cómo modificar los valores de manera ad hoc para que la SUM la reducción producirá lo que desea.

Espero que esto te ayude por ahora, ya sea como sugerencia o como confirmación de que no estás solo en esto.

1

1

Gracias. Me siento mejor, no estamos solos y por eso este problema parece real. Pensé en la misma solución que propones. Sin embargo, esto es un truco, rompe la lógica de lo que significa la 'métrica' es y qué debería estar en esta clase.

- Tomasz Bartczak

21 de abril de 2021 a las 9:30



------------------------------------

Al implementar la subclase de la clase Keras Metric, debe anular la función merge_state() correctamente. Si no anula esta función, la implementación predeterminada seráutilizado, que es una suma simple.

Ver: https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Metric

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare