Aprendizaje federado

Descripción general

Este documento presenta interfaces que facilitan las tareas de aprendizaje federado, como el entrenamiento o la evaluación federados con modelos de aprendizaje automático existentes implementados en TensorFlow. Al diseñar estas interfaces, nuestro objetivo principal fue hacer posible experimentar con el aprendizaje federado sin necesidad de saber cómo funciona internamente, y evaluar los algoritmos de aprendizaje federado implementados en una variedad de modelos y datos existentes. Le animamos a contribuir de nuevo a la plataforma. TFF ha sido diseñado teniendo en cuenta la extensibilidad y la composición, y agradecemos las contribuciones; ¡Estamos emocionados de ver lo que se te ocurre!

Las interfaces que ofrece esta capa constan de las siguientes tres partes clave:

  • modelos Clases y funciones auxiliares que le permiten envolver sus modelos existentes para usarlos con TFF. Envolver un modelo puede ser tan simple como llamar a una sola función de envoltura (p. ej., tff.learning.models.from_keras_model ), o definir una subclase de la interfaz tff.learning.models.VariableModel para una personalización completa.

  • Constructores de computación federados . Funciones auxiliares que construyen cálculos federados para entrenamiento o evaluación, usando sus modelos existentes.

  • conjuntos de datos Colecciones enlatadas de datos que puede descargar y acceder en Python para usar en la simulación de escenarios de aprendizaje federado. Si bien el aprendizaje federado está diseñado para usarse con datos descentralizados que no se pueden descargar simplemente en una ubicación centralizada, en las etapas de investigación y desarrollo a menudo es conveniente realizar experimentos iniciales utilizando datos que se pueden descargar y manipular localmente, especialmente para los desarrolladores que podrían estar nuevo en el enfoque.

Estas interfaces se definen principalmente en el espacio de nombres tff.learning , a excepción de los conjuntos de datos de investigación y otras capacidades relacionadas con la simulación que se han agrupado en tff.simulation . Esta capa se implementa utilizando interfaces de nivel inferior ofrecidas por Federated Core (FC) , que también proporciona un entorno de tiempo de ejecución.

Antes de continuar, le recomendamos que primero revise los tutoriales sobre clasificación de imágenes y generación de texto , ya que presentan la mayoría de los conceptos descritos aquí mediante ejemplos concretos. Si está interesado en obtener más información sobre cómo funciona TFF, puede leer el tutorial de algoritmos personalizados como una introducción a las interfaces de nivel inferior que usamos para expresar la lógica de los cálculos federados y para estudiar la implementación existente del tff.interfaces tff.learning .

Modelos

Supuestos arquitectónicos

Publicación por entregas

TFF tiene como objetivo admitir una variedad de escenarios de aprendizaje distribuido en los que el código del modelo de aprendizaje automático que escribe podría ejecutarse en una gran cantidad de clientes heterogéneos con diversas capacidades. Si bien en un extremo del espectro, en algunas aplicaciones esos clientes pueden ser potentes servidores de bases de datos, muchos usos importantes que nuestra plataforma pretende admitir involucran dispositivos móviles e integrados con recursos limitados. No podemos asumir que estos dispositivos son capaces de albergar tiempos de ejecución de Python; lo único que podemos suponer en este momento es que son capaces de alojar un tiempo de ejecución local de TensorFlow. Por lo tanto, una suposición arquitectónica fundamental que hacemos en TFF es que su código de modelo debe ser serializable como un gráfico de TensorFlow.

Puede (y debe) seguir desarrollando su código TF siguiendo las mejores prácticas más recientes, como usar el modo entusiasta. Sin embargo, el código final debe ser serializable (p. ej., puede envolverse como una tf.function para el código en modo impaciente). Esto garantiza que cualquier estado de Python o flujo de control necesario en el momento de la ejecución se pueda serializar (posiblemente con la ayuda de Autograph ).

Actualmente, TensorFlow no es totalmente compatible con la serialización y deserialización de TensorFlow en modo ansioso. Por lo tanto, la serialización en TFF actualmente sigue el patrón TF 1.0, donde todo el código debe construirse dentro de un tf.Graph que controla TFF. Esto significa que actualmente TFF no puede consumir un modelo ya construido; en cambio, la lógica de definición del modelo se empaqueta en una función sin argumentos que devuelve un tff.learning.models.VariableModel . Luego, TFF llama a esta función para garantizar que todos los componentes del modelo estén serializados. Además, al ser un entorno fuertemente tipado, TFF requerirá un poco de metadatos adicionales, como una especificación del tipo de entrada de su modelo.

Agregación

Recomendamos encarecidamente a la mayoría de los usuarios que construyan modelos utilizando Keras; consulte la sección Convertidores para Keras a continuación. Estos contenedores manejan la agregación de actualizaciones de modelos, así como cualquier métrica definida para el modelo automáticamente. Sin embargo, aún puede ser útil comprender cómo se maneja la agregación para un tff.learning.models.VariableModel general.

Siempre hay al menos dos capas de agregación en el aprendizaje federado: agregación local en el dispositivo y agregación entre dispositivos (o federada):

  • Agregación local . Este nivel de agregación se refiere a la agregación de múltiples lotes de ejemplos propiedad de un cliente individual. Se aplica tanto a los parámetros del modelo (variables), que continúan evolucionando secuencialmente a medida que el modelo se entrena localmente, como a las estadísticas que calcula (como la pérdida promedio, la precisión y otras métricas), que su modelo volverá a actualizar localmente. a medida que itera sobre el flujo de datos local de cada cliente individual.

    Realizar la agregación en este nivel es responsabilidad del código de tu modelo y se logra mediante construcciones estándar de TensorFlow.

    La estructura general del procesamiento es la siguiente:

    • El modelo primero construye tf.Variable s para contener agregados, como el número de lotes o el número de ejemplos procesados, la suma de pérdidas por lote o por ejemplo, etc.

    • TFF invoca el método forward_pass en su Model varias veces, de forma secuencial en lotes posteriores de datos del cliente, lo que le permite actualizar las variables que contienen varios agregados como efecto secundario.

    • Finalmente, TFF invoca el método report_local_unfinalized_metrics en su modelo para permitir que su modelo compile todas las estadísticas de resumen que recopiló en un conjunto compacto de métricas para que el cliente las exporte. Aquí es donde el código de su modelo puede, por ejemplo, dividir la suma de las pérdidas por la cantidad de ejemplos procesados ​​para exportar la pérdida promedio, etc.

  • Agregación federada . Este nivel de agregación se refiere a la agregación entre múltiples clientes (dispositivos) en el sistema. Una vez más, se aplica tanto a los parámetros del modelo (variables), que se promedian entre los clientes, como a las métricas que su modelo exportó como resultado de la agregación local.

    La realización de la agregación a este nivel es responsabilidad de TFF. Sin embargo, como creador de modelos, puede controlar este proceso (más sobre esto a continuación).

    La estructura general del procesamiento es la siguiente:

    • El modelo inicial y los parámetros necesarios para la capacitación son distribuidos por un servidor a un subconjunto de clientes que participarán en una ronda de capacitación o evaluación.

    • En cada cliente, de forma independiente y en paralelo, el código de su modelo se invoca repetidamente en un flujo de lotes de datos locales para producir un nuevo conjunto de parámetros del modelo (durante el entrenamiento) y un nuevo conjunto de métricas locales, como se describe anteriormente (esto es local). agregación).

    • TFF ejecuta un protocolo de agregación distribuida para acumular y agregar los parámetros del modelo y las métricas exportadas localmente en todo el sistema. Esta lógica se expresa de manera declarativa utilizando el propio lenguaje de computación federado de TFF (no en TensorFlow). Consulte el tutorial de algoritmos personalizados para obtener más información sobre la API de agregación.

Interfaces abstractas

Esta interfaz básica de constructor + metadatos está representada por la interfaz tff.learning.models.VariableModel , de la siguiente manera:

  • Los métodos constructor, forward_pass y report_local_unfinalized_metrics deben construir las variables del modelo, el pase de avance y las estadísticas que desea informar, según corresponda. El TensorFlow construido por esos métodos debe ser serializable, como se discutió anteriormente.

  • La propiedad input_spec , así como las 3 propiedades que devuelven subconjuntos de sus variables entrenables, no entrenables y locales representan los metadatos. TFF usa esta información para determinar cómo conectar partes de su modelo a los algoritmos de optimización federados y para definir firmas de tipo internas para ayudar a verificar la exactitud del sistema construido (para que su modelo no pueda ser instanciado sobre datos que no coincidan con lo que el modelo está diseñado para consumir).

Además, la interfaz abstracta tff.learning.models.VariableModel expone una propiedad metric_finalizers que toma los valores no finalizados de una métrica (devueltos por report_local_unfinalized_metrics() ) y devuelve los valores de métrica finalizados. Los métodos metric_finalizers y report_local_unfinalized_metrics() se usarán juntos para crear un agregador de métricas entre clientes al definir los procesos de capacitación federados o los cálculos de evaluación. Por ejemplo, un agregador tff.learning.metrics.sum_then_finalize simple primero sumará los valores de métrica no finalizados de los clientes y luego llamará a las funciones del finalizador en el servidor.

Puede encontrar ejemplos de cómo definir su propio tff.learning.models.VariableModel personalizado en la segunda parte de nuestro tutorial de clasificación de imágenes , así como en los modelos de ejemplo que usamos para probar en model_examples.py .

Convertidores para Keras

Casi toda la información que requiere TFF se puede derivar llamando a las interfaces tf.keras , por lo que si tiene un modelo Keras, puede confiar en tff.learning.models.from_keras_model para construir un tff.learning.models.VariableModel .

Tenga en cuenta que TFF todavía quiere que proporcione un constructor, una función de modelo sin argumentos como la siguiente:

def model_fn():
  keras_model = ...
  return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)

Además del modelo en sí, proporciona un lote de muestra de datos que TFF usa para determinar el tipo y la forma de la entrada de su modelo. Esto garantiza que TFF pueda crear una instancia adecuada del modelo para los datos que realmente estarán presentes en los dispositivos cliente (ya que asumimos que estos datos generalmente no están disponibles en el momento en que construye el TensorFlow para serializarlo).

El uso de envolturas de Keras se ilustra en nuestros tutoriales de clasificación de imágenes y generación de texto .

Constructores de computación federados

El paquete tff.learning proporciona varios constructores para tff.Computation s que realizan tareas relacionadas con el aprendizaje; esperamos que el conjunto de tales cálculos se amplíe en el futuro.

Supuestos arquitectónicos

Ejecución

Hay dos fases distintas en la ejecución de un cálculo federado.

  • Compilar : TFF primero compila algoritmos de aprendizaje federados en una representación serializada abstracta de todo el cómputo distribuido. Aquí es cuando ocurre la serialización de TensorFlow, pero pueden ocurrir otras transformaciones para respaldar una ejecución más eficiente. Nos referimos a la representación serializada emitida por el compilador como un cálculo federado .

  • Ejecutar TFF proporciona formas de ejecutar estos cálculos. Por ahora, la ejecución solo se admite a través de una simulación local (por ejemplo, en un cuaderno que usa datos descentralizados simulados).

Un cómputo federado generado por la API de aprendizaje federado de TFF, como un algoritmo de entrenamiento que utiliza promedios de modelos federados o una evaluación federada, incluye varios elementos, entre los que destacan:

  • Una forma serializada del código de su modelo, así como código adicional de TensorFlow construido por el marco de aprendizaje federado para impulsar el ciclo de capacitación/evaluación de su modelo (como la construcción de optimizadores, la aplicación de actualizaciones del modelo, la iteración sobre tf.data.Dataset sy la computación de métricas, y aplicar la actualización agregada en el servidor, por nombrar algunos).

  • Una especificación declarativa de la comunicación entre los clientes y un servidor (por lo general, varias formas de agregación entre los dispositivos del cliente y transmisión desde el servidor a todos los clientes), y cómo esta comunicación distribuida se intercala con la ejecución local del cliente o local del servidor. del código de TensorFlow.

Los cálculos federados representados en este formulario serializado se expresan en un lenguaje interno independiente de la plataforma distinto de Python, pero para usar la API de aprendizaje federado, no tendrá que preocuparse por los detalles de esta representación. Los cálculos se representan en su código de Python como objetos de tipo tff.Computation , que en su mayor parte puede tratar como s callable de Python opacos.

En los tutoriales, invocará esos cálculos federados como si fueran funciones regulares de Python, para ejecutarse localmente. Sin embargo, TFF está diseñado para expresar cómputos federados de una manera independiente de la mayoría de los aspectos del entorno de ejecución, de modo que puedan implementarse, por ejemplo, en grupos de dispositivos que ejecutan Android o en clústeres en un centro de datos. Nuevamente, la principal consecuencia de esto son fuertes suposiciones sobre la serialización . En particular, cuando invoca uno de los métodos build_... descritos a continuación, el cálculo se serializa por completo.

Estado de modelado

TFF es un entorno de programación funcional, pero muchos procesos de interés en el aprendizaje federado tienen estado. Por ejemplo, un ciclo de entrenamiento que involucra varias rondas de promedios de modelos federados es un ejemplo de lo que podríamos clasificar como un proceso con estado . En este proceso, el estado que evoluciona de ronda en ronda incluye el conjunto de parámetros del modelo que se están entrenando y posiblemente un estado adicional asociado con el optimizador (por ejemplo, un vector de impulso).

Dado que TFF es funcional, los procesos con estado se modelan en TFF como cálculos que aceptan el estado actual como entrada y luego proporcionan el estado actualizado como salida. Para definir completamente un proceso con estado, también es necesario especificar de dónde proviene el estado inicial (de lo contrario, no podemos arrancar el proceso). Esto se captura en la definición de la clase auxiliar tff.templates.IterativeProcess , con las 2 propiedades initialize y next correspondientes a la inicialización y la iteración, respectivamente.

Constructores disponibles

Por el momento, TFF proporciona varias funciones de construcción que generan cálculos federados para capacitación y evaluación federadas. Dos ejemplos notables incluyen:

conjuntos de datos

Supuestos arquitectónicos

Selección de clientes

En el escenario típico de aprendizaje federado, tenemos una gran población de potencialmente cientos de millones de dispositivos cliente, de los cuales solo una pequeña parte puede estar activa y disponible para capacitación en un momento dado (por ejemplo, esto puede estar limitado a clientes que están enchufado a una fuente de alimentación, no en una red medida, y por lo demás inactivo). Generalmente, el conjunto de clientes disponibles para participar en la capacitación o evaluación está fuera del control del desarrollador. Además, como no es práctico coordinar a millones de clientes, una ronda típica de capacitación o evaluación incluirá solo una fracción de los clientes disponibles, que pueden ser seleccionados al azar .

La consecuencia clave de esto es que los cálculos federados, por diseño, se expresan de una manera que no tiene en cuenta el conjunto exacto de participantes; todo el procesamiento se expresa como operaciones agregadas en un grupo abstracto de clientes anónimos, y ese grupo puede variar de una ronda de capacitación a otra. La vinculación real del cómputo con los participantes concretos y, por lo tanto, con los datos concretos que alimentan al cómputo, se modela fuera del cómputo mismo.

Para simular una implementación realista de su código de aprendizaje federado, generalmente escribirá un ciclo de entrenamiento que se ve así:

trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...

def sample(federate_data):
  return ...

while True:
  data_for_this_round = sample(federated_training_data)
  result = trainer.next(state, data_for_this_round)
  state = result.state

Para facilitar esto, cuando se usa TFF en simulaciones, los datos federados se aceptan como list de Python, con un elemento por dispositivo cliente participante para representar el tf.data.Dataset local de ese dispositivo.

Interfaces abstractas

Para estandarizar el manejo de conjuntos de datos federados simulados, TFF proporciona una interfaz abstracta tff.simulation.datasets.ClientData , que permite enumerar el conjunto de clientes y construir un tf.data.Dataset que contiene los datos de un determinado cliente. Esos tf.data.Dataset s pueden alimentarse directamente como entrada a los cálculos federados generados en modo entusiasta.

Cabe señalar que la capacidad de acceder a las identidades de los clientes es una función que solo proporcionan los conjuntos de datos para su uso en simulaciones, donde puede ser necesaria la capacidad de entrenar con datos de subconjuntos específicos de clientes (p. ej., para simular la disponibilidad diurna de diferentes tipos de clientes). Los cálculos compilados y el tiempo de ejecución subyacente no involucran ninguna noción de identidad del cliente. Una vez que se han seleccionado los datos de un subconjunto específico de clientes como entrada, por ejemplo, en una llamada a tff.templates.IterativeProcess.next , las identidades de los clientes ya no aparecen en él.

Conjuntos de datos disponibles

Hemos dedicado el espacio de nombres tff.simulation.datasets para conjuntos de datos que implementan la interfaz tff.simulation.datasets.ClientData para su uso en simulaciones, y lo hemos sembrado con conjuntos de datos para admitir la clasificación de imágenes y los tutoriales de generación de texto . Nos gustaría animarle a contribuir con sus propios conjuntos de datos a la plataforma.

,

Descripción general

Este documento presenta interfaces que facilitan las tareas de aprendizaje federado, como el entrenamiento o la evaluación federados con modelos de aprendizaje automático existentes implementados en TensorFlow. Al diseñar estas interfaces, nuestro objetivo principal fue hacer posible experimentar con el aprendizaje federado sin necesidad de saber cómo funciona internamente, y evaluar los algoritmos de aprendizaje federado implementados en una variedad de modelos y datos existentes. Le animamos a contribuir de nuevo a la plataforma. TFF ha sido diseñado teniendo en cuenta la extensibilidad y la composición, y agradecemos las contribuciones; ¡Estamos emocionados de ver lo que se te ocurre!

Las interfaces que ofrece esta capa constan de las siguientes tres partes clave:

  • modelos Clases y funciones auxiliares que le permiten envolver sus modelos existentes para usarlos con TFF. Envolver un modelo puede ser tan simple como llamar a una sola función de envoltura (p. ej., tff.learning.models.from_keras_model ), o definir una subclase de la interfaz tff.learning.models.VariableModel para una personalización completa.

  • Constructores de computación federados . Funciones auxiliares que construyen cálculos federados para entrenamiento o evaluación, usando sus modelos existentes.

  • conjuntos de datos Colecciones enlatadas de datos que puede descargar y acceder en Python para usar en la simulación de escenarios de aprendizaje federado. Si bien el aprendizaje federado está diseñado para usarse con datos descentralizados que no se pueden descargar simplemente en una ubicación centralizada, en las etapas de investigación y desarrollo a menudo es conveniente realizar experimentos iniciales utilizando datos que se pueden descargar y manipular localmente, especialmente para los desarrolladores que podrían estar nuevo en el enfoque.

Estas interfaces se definen principalmente en el espacio de nombres tff.learning , a excepción de los conjuntos de datos de investigación y otras capacidades relacionadas con la simulación que se han agrupado en tff.simulation . Esta capa se implementa utilizando interfaces de nivel inferior ofrecidas por Federated Core (FC) , que también proporciona un entorno de tiempo de ejecución.

Antes de continuar, le recomendamos que primero revise los tutoriales sobre clasificación de imágenes y generación de texto , ya que presentan la mayoría de los conceptos descritos aquí mediante ejemplos concretos. Si está interesado en obtener más información sobre cómo funciona TFF, puede leer el tutorial de algoritmos personalizados como una introducción a las interfaces de nivel inferior que usamos para expresar la lógica de los cálculos federados y para estudiar la implementación existente del tff.interfaces tff.learning .

Modelos

Supuestos arquitectónicos

Publicación por entregas

TFF tiene como objetivo admitir una variedad de escenarios de aprendizaje distribuido en los que el código del modelo de aprendizaje automático que escribe podría ejecutarse en una gran cantidad de clientes heterogéneos con diversas capacidades. Si bien en un extremo del espectro, en algunas aplicaciones esos clientes pueden ser potentes servidores de bases de datos, muchos usos importantes que nuestra plataforma pretende admitir involucran dispositivos móviles e integrados con recursos limitados. No podemos asumir que estos dispositivos son capaces de albergar tiempos de ejecución de Python; lo único que podemos suponer en este momento es que son capaces de alojar un tiempo de ejecución local de TensorFlow. Por lo tanto, una suposición arquitectónica fundamental que hacemos en TFF es que su código de modelo debe ser serializable como un gráfico de TensorFlow.

Puede (y debe) seguir desarrollando su código TF siguiendo las mejores prácticas más recientes, como usar el modo entusiasta. Sin embargo, el código final debe ser serializable (p. ej., puede envolverse como una tf.function para el código en modo impaciente). Esto garantiza que cualquier estado de Python o flujo de control necesario en el momento de la ejecución se pueda serializar (posiblemente con la ayuda de Autograph ).

Actualmente, TensorFlow no es totalmente compatible con la serialización y deserialización de TensorFlow en modo ansioso. Por lo tanto, la serialización en TFF actualmente sigue el patrón TF 1.0, donde todo el código debe construirse dentro de un tf.Graph que controla TFF. Esto significa que actualmente TFF no puede consumir un modelo ya construido; en cambio, la lógica de definición del modelo se empaqueta en una función sin argumentos que devuelve un tff.learning.models.VariableModel . Luego, TFF llama a esta función para garantizar que todos los componentes del modelo estén serializados. Además, al ser un entorno fuertemente tipado, TFF requerirá un poco de metadatos adicionales, como una especificación del tipo de entrada de su modelo.

Agregación

Recomendamos encarecidamente a la mayoría de los usuarios que construyan modelos utilizando Keras; consulte la sección Convertidores para Keras a continuación. Estos contenedores manejan la agregación de actualizaciones de modelos, así como cualquier métrica definida para el modelo automáticamente. Sin embargo, aún puede ser útil comprender cómo se maneja la agregación para un tff.learning.models.VariableModel general.

Siempre hay al menos dos capas de agregación en el aprendizaje federado: agregación local en el dispositivo y agregación entre dispositivos (o federada):

  • Agregación local . Este nivel de agregación se refiere a la agregación de múltiples lotes de ejemplos propiedad de un cliente individual. Se aplica tanto a los parámetros del modelo (variables), que continúan evolucionando secuencialmente a medida que el modelo se entrena localmente, como a las estadísticas que calcula (como la pérdida promedio, la precisión y otras métricas), que su modelo volverá a actualizar localmente. a medida que itera sobre el flujo de datos local de cada cliente individual.

    Realizar la agregación en este nivel es responsabilidad del código de tu modelo y se logra mediante construcciones estándar de TensorFlow.

    La estructura general del procesamiento es la siguiente:

    • El modelo primero construye tf.Variable s para contener agregados, como el número de lotes o el número de ejemplos procesados, la suma de pérdidas por lote o por ejemplo, etc.

    • TFF invoca el método forward_pass en su Model varias veces, de forma secuencial en lotes posteriores de datos del cliente, lo que le permite actualizar las variables que contienen varios agregados como efecto secundario.

    • Finalmente, TFF invoca el método report_local_unfinalized_metrics en su modelo para permitir que su modelo compile todas las estadísticas de resumen que recopiló en un conjunto compacto de métricas para que el cliente las exporte. Aquí es donde el código de su modelo puede, por ejemplo, dividir la suma de las pérdidas por la cantidad de ejemplos procesados ​​para exportar la pérdida promedio, etc.

  • Agregación federada . Este nivel de agregación se refiere a la agregación entre múltiples clientes (dispositivos) en el sistema. Una vez más, se aplica tanto a los parámetros del modelo (variables), que se promedian entre los clientes, como a las métricas que su modelo exportó como resultado de la agregación local.

    La realización de la agregación a este nivel es responsabilidad de TFF. Sin embargo, como creador de modelos, puede controlar este proceso (más sobre esto a continuación).

    La estructura general del procesamiento es la siguiente:

    • El modelo inicial y los parámetros necesarios para la capacitación son distribuidos por un servidor a un subconjunto de clientes que participarán en una ronda de capacitación o evaluación.

    • En cada cliente, de forma independiente y en paralelo, el código de su modelo se invoca repetidamente en un flujo de lotes de datos locales para producir un nuevo conjunto de parámetros del modelo (durante el entrenamiento) y un nuevo conjunto de métricas locales, como se describe anteriormente (esto es local). agregación).

    • TFF ejecuta un protocolo de agregación distribuida para acumular y agregar los parámetros del modelo y las métricas exportadas localmente en todo el sistema. Esta lógica se expresa de manera declarativa utilizando el propio lenguaje de computación federado de TFF (no en TensorFlow). Consulte el tutorial de algoritmos personalizados para obtener más información sobre la API de agregación.

Interfaces abstractas

Esta interfaz básica de constructor + metadatos está representada por la interfaz tff.learning.models.VariableModel , de la siguiente manera:

  • Los métodos constructor, forward_pass y report_local_unfinalized_metrics deben construir las variables del modelo, el pase de avance y las estadísticas que desea informar, según corresponda. El TensorFlow construido por esos métodos debe ser serializable, como se discutió anteriormente.

  • La propiedad input_spec , así como las 3 propiedades que devuelven subconjuntos de sus variables entrenables, no entrenables y locales representan los metadatos. TFF usa esta información para determinar cómo conectar partes de su modelo a los algoritmos de optimización federados y para definir firmas de tipo internas para ayudar a verificar la exactitud del sistema construido (para que su modelo no pueda ser instanciado sobre datos que no coincidan con lo que el modelo está diseñado para consumir).

Además, la interfaz abstracta tff.learning.models.VariableModel expone una propiedad metric_finalizers que toma los valores no finalizados de una métrica (devueltos por report_local_unfinalized_metrics() ) y devuelve los valores de métrica finalizados. Los métodos metric_finalizers y report_local_unfinalized_metrics() se usarán juntos para crear un agregador de métricas entre clientes al definir los procesos de capacitación federados o los cálculos de evaluación. Por ejemplo, un agregador tff.learning.metrics.sum_then_finalize simple primero sumará los valores de métrica no finalizados de los clientes y luego llamará a las funciones del finalizador en el servidor.

Puede encontrar ejemplos de cómo definir su propio tff.learning.models.VariableModel personalizado en la segunda parte de nuestro tutorial de clasificación de imágenes , así como en los modelos de ejemplo que usamos para probar en model_examples.py .

Convertidores para Keras

Casi toda la información que requiere TFF se puede derivar llamando a las interfaces tf.keras , por lo que si tiene un modelo Keras, puede confiar en tff.learning.models.from_keras_model para construir un tff.learning.models.VariableModel .

Tenga en cuenta que TFF todavía quiere que proporcione un constructor, una función de modelo sin argumentos como la siguiente:

def model_fn():
  keras_model = ...
  return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)

Además del modelo en sí, proporciona un lote de muestra de datos que TFF usa para determinar el tipo y la forma de la entrada de su modelo. Esto garantiza que TFF pueda crear una instancia adecuada del modelo para los datos que realmente estarán presentes en los dispositivos cliente (ya que asumimos que estos datos generalmente no están disponibles en el momento en que construye el TensorFlow para serializarlo).

El uso de envolturas de Keras se ilustra en nuestros tutoriales de clasificación de imágenes y generación de texto .

Constructores de computación federados

El paquete tff.learning proporciona varios constructores para tff.Computation s que realizan tareas relacionadas con el aprendizaje; esperamos que el conjunto de tales cálculos se amplíe en el futuro.

Supuestos arquitectónicos

Ejecución

Hay dos fases distintas en la ejecución de un cálculo federado.

  • Compilar : TFF primero compila algoritmos de aprendizaje federados en una representación serializada abstracta de todo el cómputo distribuido. Aquí es cuando ocurre la serialización de TensorFlow, pero pueden ocurrir otras transformaciones para respaldar una ejecución más eficiente. Nos referimos a la representación serializada emitida por el compilador como un cálculo federado .

  • Ejecutar TFF proporciona formas de ejecutar estos cálculos. Por ahora, la ejecución solo se admite a través de una simulación local (por ejemplo, en un cuaderno que usa datos descentralizados simulados).

Un cómputo federado generado por la API de aprendizaje federado de TFF, como un algoritmo de entrenamiento que utiliza promedios de modelos federados o una evaluación federada, incluye varios elementos, entre los que destacan:

  • Una forma serializada del código de su modelo, así como código adicional de TensorFlow construido por el marco de aprendizaje federado para impulsar el ciclo de capacitación/evaluación de su modelo (como la construcción de optimizadores, la aplicación de actualizaciones del modelo, la iteración sobre tf.data.Dataset sy la computación de métricas, y aplicar la actualización agregada en el servidor, por nombrar algunos).

  • Una especificación declarativa de la comunicación entre los clientes y un servidor (por lo general, varias formas de agregación entre los dispositivos del cliente y transmisión desde el servidor a todos los clientes), y cómo esta comunicación distribuida se intercala con la ejecución local del cliente o local del servidor. del código de TensorFlow.

Los cálculos federados representados en este formulario serializado se expresan en un lenguaje interno independiente de la plataforma distinto de Python, pero para usar la API de aprendizaje federado, no tendrá que preocuparse por los detalles de esta representación. Los cálculos se representan en su código de Python como objetos de tipo tff.Computation , que en su mayor parte puede tratar como s callable de Python opacos.

En los tutoriales, invocará esos cálculos federados como si fueran funciones regulares de Python, para ejecutarse localmente. Sin embargo, TFF está diseñado para expresar cómputos federados de una manera independiente de la mayoría de los aspectos del entorno de ejecución, de modo que puedan implementarse, por ejemplo, en grupos de dispositivos que ejecutan Android o en clústeres en un centro de datos. Nuevamente, la principal consecuencia de esto son fuertes suposiciones sobre la serialización . En particular, cuando invoca uno de los métodos build_... descritos a continuación, el cálculo se serializa por completo.

Estado de modelado

TFF es un entorno de programación funcional, pero muchos procesos de interés en el aprendizaje federado tienen estado. Por ejemplo, un ciclo de entrenamiento que involucra varias rondas de promedios de modelos federados es un ejemplo de lo que podríamos clasificar como un proceso con estado . En este proceso, el estado que evoluciona de ronda en ronda incluye el conjunto de parámetros del modelo que se están entrenando y posiblemente un estado adicional asociado con el optimizador (por ejemplo, un vector de impulso).

Dado que TFF es funcional, los procesos con estado se modelan en TFF como cálculos que aceptan el estado actual como entrada y luego proporcionan el estado actualizado como salida. Para definir completamente un proceso con estado, también es necesario especificar de dónde proviene el estado inicial (de lo contrario, no podemos iniciar el proceso). Esto se captura en la definición de la clase auxiliar tff.templates.IterativeProcess , con las 2 propiedades initialize y next correspondientes a la inicialización y la iteración, respectivamente.

Constructores disponibles

At the moment, TFF provides various builder functions that generate federated computations for federated training and evaluation. Two notable examples include:

Datasets

Architectural assumptions

Client selection

In the typical federated learning scenario, we have a large population of potentially hundreds of millions of client devices, of which only a small portion may be active and available for training at any given moment (for example, this may be limited to clients that are plugged in to a power source, not on a metered network, and otherwise idle). Generally, the set of clients available to participate in training or evaluation is outside of the developer's control. Furthermore, as it's impractical to coordinate millions of clients, a typical round of training or evaluation will include only a fraction of the available clients, which may be sampled at random .

The key consequence of this is that federated computations, by design, are expressed in a manner that is oblivious to the exact set of participants; all processing is expressed as aggregate operations on an abstract group of anonymous clients , and that group might vary from one round of training to another. The actual binding of the computation to the concrete participants, and thus to the concrete data they feed into the computation, is thus modeled outside of the computation itself.

In order to simulate a realistic deployment of your federated learning code, you will generally write a training loop that looks like this:

trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...

def sample(federate_data):
  return ...

while True:
  data_for_this_round = sample(federated_training_data)
  result = trainer.next(state, data_for_this_round)
  state = result.state

In order to facilitate this, when using TFF in simulations, federated data is accepted as Python list s, with one element per participating client device to represent that device's local tf.data.Dataset .

Abstract interfaces

In order to standardize dealing with simulated federated data sets, TFF provides an abstract interface tff.simulation.datasets.ClientData , which allows one to enumerate the set of clients, and to construct a tf.data.Dataset that contains the data of a particular client. Those tf.data.Dataset s can be fed directly as input to the generated federated computations in eager mode.

It should be noted that the ability to access client identities is a feature that's only provided by the datasets for use in simulations, where the ability to train on data from specific subsets of clients may be needed (eg, to simulate the diurnal availability of different types of clients). The compiled computations and the underlying runtime do not involve any notion of client identity. Once data from a specific subset of clients has been selected as an input, eg, in a call to tff.templates.IterativeProcess.next , client identities no longer appear in it.

Available data sets

We have dedicated the namespace tff.simulation.datasets for datasets that implement the tff.simulation.datasets.ClientData interface for use in simulations, and seeded it with datasets to support the image classification and text generation tutorials. We'd like to encourage you to contribute your own datasets to the platform.

,

Overview

This document introduces interfaces that facilitate federated learning tasks, such as federated training or evaluation with existing machine learning models implemented in TensorFlow. In designing these interfaces, our primary goal was to make it possible to experiment with federated learning without requiring the knowledge of how it works under the hood, and to evaluate the implemented federated learning algorithms on a variety of existing models and data. We encourage you to contribute back to the platform. TFF has been designed with extensibility and composability in mind, and we welcome contributions; we are excited to see what you come up with!

The interfaces offered by this layer consist of the following three key parts:

  • Models . Classes and helper functions that allow you to wrap your existing models for use with TFF. Wrapping a model can be as simple as calling a single wrapping function (eg, tff.learning.models.from_keras_model ), or defining a subclass of the tff.learning.models.VariableModel interface for full customizability.

  • Federated Computation Builders . Helper functions that construct federated computations for training or evaluation, using your existing models.

  • Datasets . Canned collections of data that you can download and access in Python for use in simulating federated learning scenarios. Although federated learning is designed for use with decentralized data that cannot be simply downloaded at a centralized location, at the research and development stages it is often convenient to conduct initial experiments using data that can be downloaded and manipulated locally, especially for developers who might be new to the approach.

These interfaces are defined primarily in the tff.learning namespace, except for research data sets and other simulation-related capabilities that have been grouped in tff.simulation . This layer is implemented using lower-level interfaces offered by the Federated Core (FC) , which also provides a runtime environment.

Before proceeding, we recommend that you first review the tutorials on image classification and text generation , as they introduce most of the concepts described here using concrete examples. If you're interested in learning more about how TFF works, you may want to skim over the custom algorithms tutorial as an introduction to the lower-level interfaces we use to express the logic of federated computations, and to study the existing implementation of the tff.learning interfaces.

Models

Architectural assumptions

Serialization

TFF aims at supporting a variety of distributed learning scenarios in which the machine learning model code you write might be executing on a large number of heterogeneous clients with diverse capabilities. While at one end of the spectrum, in some applications those clients might be powerful database servers, many important uses our platform intends to support involve mobile and embedded devices with limited resources. We cannot assume that these devices are capable of hosting Python runtimes; the only thing we can assume at this point is that they are capable of hosting a local TensorFlow runtime. Thus, a fundamental architectural assumption we make in TFF is that your model code must be serializable as a TensorFlow graph.

You can (and should) still develop your TF code following the latest best practices like using eager mode. However, the final code must be serializable (eg, can be wrapped as a tf.function for eager-mode code). This ensures that any Python state or control flow necessary at execution time can be serialized (possibly with the help of Autograph ).

Currently, TensorFlow does not fully support serializing and deserializing eager-mode TensorFlow. Thus, serialization in TFF currently follows the TF 1.0 pattern, where all code must be constructed inside a tf.Graph that TFF controls. This means currently TFF cannot consume an already-constructed model; instead, the model definition logic is packaged in a no-arg function that returns a tff.learning.models.VariableModel . This function is then called by TFF to ensure all components of the model are serialized. In addition, being a strongly-typed environment, TFF will require a little bit of additional metadata , such as a specification of your model's input type.

Aggregation

We strongly recommend most users construct models using Keras, see the Converters for Keras section below. These wrappers handle the aggregation of model updates as well as any metrics defined for the model automatically. However, it may still be useful to understand how aggregation is handled for a general tff.learning.models.VariableModel .

There are always at least two layers of aggregation in federated learning: local on-device aggregation, and cross-device (or federated) aggregation:

  • Local aggregation . This level of aggregation refers to aggregation across multiple batches of examples owned by an individual client. It applies to both the model parameters (variables), which continue to sequentially evolve as the model is locally trained, as well as the statistics you compute (such as average loss, accuracy, and other metrics), which your model will again update locally as it iterates over each individual client's local data stream.

    Performing aggregation at this level is the responsibility of your model code, and is accomplished using standard TensorFlow constructs.

    The general structure of processing is as follows:

    • The model first constructs tf.Variable s to hold aggregates, such as the number of batches or the number of examples processed, the sum of per-batch or per-example losses, etc.

    • TFF invokes the forward_pass method on your Model multiple times, sequentially over subsequent batches of client data, which allows you to update the variables holding various aggregates as a side effect.

    • Finally, TFF invokes the report_local_unfinalized_metrics method on your Model to allow your model to compile all the summary statistics it collected into a compact set of metrics to be exported by the client. This is where your model code may, for example, divide the sum of losses by the number of examples processed to export the average loss, etc.

  • Federated aggregation . This level of aggregation refers to aggregation across multiple clients (devices) in the system. Again, it applies to both the model parameters (variables), which are being averaged across clients, as well as the metrics your model exported as a result of local aggregation.

    Performing aggregation at this level is the responsibility of TFF. As a model creator, however, you can control this process (more on this below).

    The general structure of processing is as follows:

    • The initial model, and any parameters required for training, are distributed by a server to a subset of clients that will participate in a round of training or evaluation.

    • On each client, independently and in parallel, your model code is invoked repeatedly on a stream of local data batches to produce a new set of model parameters (when training), and a new set of local metrics, as described above (this is local aggregation).

    • TFF runs a distributed aggregation protocol to accumulate and aggregate the model parameters and locally exported metrics across the system. This logic is expressed in a declarative manner using TFF's own federated computation language (not in TensorFlow). See the custom algorithms tutorial for more on the aggregation API.

Abstract interfaces

This basic constructor + metadata interface is represented by the interface tff.learning.models.VariableModel , as follows:

  • The constructor, forward_pass , and report_local_unfinalized_metrics methods should construct model variables, forward pass, and statistics you wish to report, correspondingly. The TensorFlow constructed by those methods must be serializable, as discussed above.

  • The input_spec property, as well as the 3 properties that return subsets of your trainable, non-trainable, and local variables represent the metadata. TFF uses this information to determine how to connect parts of your model to the federated optimization algorithms, and to define internal type signatures to assist in verifying the correctness of the constructed system (so that your model cannot be instantiated over data that does not match what the model is designed to consume).

In addition, the abstract interface tff.learning.models.VariableModel exposes a property metric_finalizers that takes in a metric's unfinalized values (returned by report_local_unfinalized_metrics() ) and returns the finalized metric values. The metric_finalizers and report_local_unfinalized_metrics() method will be used together to build a cross-client metrics aggregator when defining the federated training processes or evaluation computations. For example, a simple tff.learning.metrics.sum_then_finalize aggregator will first sum the unfinalized metric values from clients, and then call the finalizer functions at the server.

You can find examples of how to define your own custom tff.learning.models.VariableModel in the second part of our image classification tutorial, as well as in the example models we use for testing in model_examples.py .

Converters for Keras

Nearly all the information that's required by TFF can be derived by calling tf.keras interfaces, so if you have a Keras model, you can rely on tff.learning.models.from_keras_model to construct a tff.learning.models.VariableModel .

Note that TFF still wants you to provide a constructor - a no-argument model function such as the following:

def model_fn():
  keras_model = ...
  return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)

In addition to the model itself, you supply a sample batch of data which TFF uses to determine the type and shape of your model's input. This ensures that TFF can properly instantiate the model for the data that will actually be present on client devices (since we assume this data is not generally available at the time you are constructing the TensorFlow to be serialized).

The use of Keras wrappers is illustrated in our image classification and text generation tutorials.

Federated Computation Builders

The tff.learning package provides several builders for tff.Computation s that perform learning-related tasks; we expect the set of such computations to expand in the future.

Architectural assumptions

Execution

There are two distinct phases in running a federated computation.

  • Compile : TFF first compiles federated learning algorithms into an abstract serialized representation of the entire distributed computation. This is when TensorFlow serialization happens, but other transformations can occur to support more efficient execution. We refer to the serialized representation emitted by the compiler as a federated computation .

  • Execute TFF provides ways to execute these computations. For now, execution is only supported via a local simulation (eg, in a notebook using simulated decentralized data).

A federated computation generated by TFF's Federated Learning API, such as a training algorithm that uses federated model averaging , or a federated evaluation, includes a number of elements, most notably:

  • A serialized form of your model code as well as additional TensorFlow code constructed by the Federated Learning framework to drive your model's training/evaluation loop (such as constructing optimizers, applying model updates, iterating over tf.data.Dataset s, and computing metrics, and applying the aggregated update on the server, to name a few).

  • A declarative specification of the communication between the clients and a server (typically various forms of aggregation across the client devices, and broadcasting from the server to all clients), and how this distributed communication is interleaved with the client-local or server-local execution of TensorFlow code.

The federated computations represented in this serialized form are expressed in a platform-independent internal language distinct from Python, but to use the Federated Learning API, you won't need to concern yourself with the details of this representation. The computations are represented in your Python code as objects of type tff.Computation , which for the most part you can treat as opaque Python callable s.

In the tutorials, you will invoke those federated computations as if they were regular Python functions, to be executed locally. However, TFF is designed to express federated computations in a manner agnostic to most aspects of the execution environment, so that they can potentially be deployable to, eg, groups of devices running Android , or to clusters in a datacenter. Again, the main consequence of this are strong assumptions about serialization . In particular, when you invoke one of the build_... methods described below the computation is fully serialized.

Modeling state

TFF is a functional programming environment, yet many processes of interest in federated learning are stateful. For example, a training loop that involves multiple rounds of federated model averaging is an example of what we could classify as a stateful process . In this process, the state that evolves from round to round includes the set of model parameters that are being trained, and possibly additional state associated with the optimizer (eg, a momentum vector).

Since TFF is functional, stateful processes are modeled in TFF as computations that accept the current state as an input and then provide the updated state as an output. In order to fully define a stateful process, one also needs to specify where the initial state comes from (otherwise we cannot bootstrap the process). This is captured in the definition of the helper class tff.templates.IterativeProcess , with the 2 properties initialize and next corresponding to the initialization and iteration, respectively.

Available builders

At the moment, TFF provides various builder functions that generate federated computations for federated training and evaluation. Two notable examples include:

Datasets

Architectural assumptions

Client selection

In the typical federated learning scenario, we have a large population of potentially hundreds of millions of client devices, of which only a small portion may be active and available for training at any given moment (for example, this may be limited to clients that are plugged in to a power source, not on a metered network, and otherwise idle). Generally, the set of clients available to participate in training or evaluation is outside of the developer's control. Furthermore, as it's impractical to coordinate millions of clients, a typical round of training or evaluation will include only a fraction of the available clients, which may be sampled at random .

The key consequence of this is that federated computations, by design, are expressed in a manner that is oblivious to the exact set of participants; all processing is expressed as aggregate operations on an abstract group of anonymous clients , and that group might vary from one round of training to another. The actual binding of the computation to the concrete participants, and thus to the concrete data they feed into the computation, is thus modeled outside of the computation itself.

In order to simulate a realistic deployment of your federated learning code, you will generally write a training loop that looks like this:

trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...

def sample(federate_data):
  return ...

while True:
  data_for_this_round = sample(federated_training_data)
  result = trainer.next(state, data_for_this_round)
  state = result.state

In order to facilitate this, when using TFF in simulations, federated data is accepted as Python list s, with one element per participating client device to represent that device's local tf.data.Dataset .

Abstract interfaces

In order to standardize dealing with simulated federated data sets, TFF provides an abstract interface tff.simulation.datasets.ClientData , which allows one to enumerate the set of clients, and to construct a tf.data.Dataset that contains the data of a particular client. Those tf.data.Dataset s can be fed directly as input to the generated federated computations in eager mode.

It should be noted that the ability to access client identities is a feature that's only provided by the datasets for use in simulations, where the ability to train on data from specific subsets of clients may be needed (eg, to simulate the diurnal availability of different types of clients). The compiled computations and the underlying runtime do not involve any notion of client identity. Once data from a specific subset of clients has been selected as an input, eg, in a call to tff.templates.IterativeProcess.next , client identities no longer appear in it.

Available data sets

We have dedicated the namespace tff.simulation.datasets for datasets that implement the tff.simulation.datasets.ClientData interface for use in simulations, and seeded it with datasets to support the image classification and text generation tutorials. We'd like to encourage you to contribute your own datasets to the platform.

,

Overview

This document introduces interfaces that facilitate federated learning tasks, such as federated training or evaluation with existing machine learning models implemented in TensorFlow. In designing these interfaces, our primary goal was to make it possible to experiment with federated learning without requiring the knowledge of how it works under the hood, and to evaluate the implemented federated learning algorithms on a variety of existing models and data. We encourage you to contribute back to the platform. TFF has been designed with extensibility and composability in mind, and we welcome contributions; we are excited to see what you come up with!

The interfaces offered by this layer consist of the following three key parts:

  • Models . Classes and helper functions that allow you to wrap your existing models for use with TFF. Wrapping a model can be as simple as calling a single wrapping function (eg, tff.learning.models.from_keras_model ), or defining a subclass of the tff.learning.models.VariableModel interface for full customizability.

  • Federated Computation Builders . Helper functions that construct federated computations for training or evaluation, using your existing models.

  • Datasets . Canned collections of data that you can download and access in Python for use in simulating federated learning scenarios. Although federated learning is designed for use with decentralized data that cannot be simply downloaded at a centralized location, at the research and development stages it is often convenient to conduct initial experiments using data that can be downloaded and manipulated locally, especially for developers who might be new to the approach.

These interfaces are defined primarily in the tff.learning namespace, except for research data sets and other simulation-related capabilities that have been grouped in tff.simulation . This layer is implemented using lower-level interfaces offered by the Federated Core (FC) , which also provides a runtime environment.

Before proceeding, we recommend that you first review the tutorials on image classification and text generation , as they introduce most of the concepts described here using concrete examples. If you're interested in learning more about how TFF works, you may want to skim over the custom algorithms tutorial as an introduction to the lower-level interfaces we use to express the logic of federated computations, and to study the existing implementation of the tff.learning interfaces.

Models

Architectural assumptions

Serialization

TFF aims at supporting a variety of distributed learning scenarios in which the machine learning model code you write might be executing on a large number of heterogeneous clients with diverse capabilities. While at one end of the spectrum, in some applications those clients might be powerful database servers, many important uses our platform intends to support involve mobile and embedded devices with limited resources. We cannot assume that these devices are capable of hosting Python runtimes; the only thing we can assume at this point is that they are capable of hosting a local TensorFlow runtime. Thus, a fundamental architectural assumption we make in TFF is that your model code must be serializable as a TensorFlow graph.

You can (and should) still develop your TF code following the latest best practices like using eager mode. However, the final code must be serializable (eg, can be wrapped as a tf.function for eager-mode code). This ensures that any Python state or control flow necessary at execution time can be serialized (possibly with the help of Autograph ).

Currently, TensorFlow does not fully support serializing and deserializing eager-mode TensorFlow. Thus, serialization in TFF currently follows the TF 1.0 pattern, where all code must be constructed inside a tf.Graph that TFF controls. This means currently TFF cannot consume an already-constructed model; instead, the model definition logic is packaged in a no-arg function that returns a tff.learning.models.VariableModel . This function is then called by TFF to ensure all components of the model are serialized. In addition, being a strongly-typed environment, TFF will require a little bit of additional metadata , such as a specification of your model's input type.

Aggregation

We strongly recommend most users construct models using Keras, see the Converters for Keras section below. These wrappers handle the aggregation of model updates as well as any metrics defined for the model automatically. However, it may still be useful to understand how aggregation is handled for a general tff.learning.models.VariableModel .

There are always at least two layers of aggregation in federated learning: local on-device aggregation, and cross-device (or federated) aggregation:

  • Local aggregation . This level of aggregation refers to aggregation across multiple batches of examples owned by an individual client. It applies to both the model parameters (variables), which continue to sequentially evolve as the model is locally trained, as well as the statistics you compute (such as average loss, accuracy, and other metrics), which your model will again update locally as it iterates over each individual client's local data stream.

    Performing aggregation at this level is the responsibility of your model code, and is accomplished using standard TensorFlow constructs.

    The general structure of processing is as follows:

    • The model first constructs tf.Variable s to hold aggregates, such as the number of batches or the number of examples processed, the sum of per-batch or per-example losses, etc.

    • TFF invokes the forward_pass method on your Model multiple times, sequentially over subsequent batches of client data, which allows you to update the variables holding various aggregates as a side effect.

    • Finally, TFF invokes the report_local_unfinalized_metrics method on your Model to allow your model to compile all the summary statistics it collected into a compact set of metrics to be exported by the client. This is where your model code may, for example, divide the sum of losses by the number of examples processed to export the average loss, etc.

  • Federated aggregation . This level of aggregation refers to aggregation across multiple clients (devices) in the system. Again, it applies to both the model parameters (variables), which are being averaged across clients, as well as the metrics your model exported as a result of local aggregation.

    Performing aggregation at this level is the responsibility of TFF. As a model creator, however, you can control this process (more on this below).

    The general structure of processing is as follows:

    • The initial model, and any parameters required for training, are distributed by a server to a subset of clients that will participate in a round of training or evaluation.

    • On each client, independently and in parallel, your model code is invoked repeatedly on a stream of local data batches to produce a new set of model parameters (when training), and a new set of local metrics, as described above (this is local aggregation).

    • TFF runs a distributed aggregation protocol to accumulate and aggregate the model parameters and locally exported metrics across the system. This logic is expressed in a declarative manner using TFF's own federated computation language (not in TensorFlow). See the custom algorithms tutorial for more on the aggregation API.

Abstract interfaces

This basic constructor + metadata interface is represented by the interface tff.learning.models.VariableModel , as follows:

  • The constructor, forward_pass , and report_local_unfinalized_metrics methods should construct model variables, forward pass, and statistics you wish to report, correspondingly. The TensorFlow constructed by those methods must be serializable, as discussed above.

  • The input_spec property, as well as the 3 properties that return subsets of your trainable, non-trainable, and local variables represent the metadata. TFF uses this information to determine how to connect parts of your model to the federated optimization algorithms, and to define internal type signatures to assist in verifying the correctness of the constructed system (so that your model cannot be instantiated over data that does not match what the model is designed to consume).

In addition, the abstract interface tff.learning.models.VariableModel exposes a property metric_finalizers that takes in a metric's unfinalized values (returned by report_local_unfinalized_metrics() ) and returns the finalized metric values. The metric_finalizers and report_local_unfinalized_metrics() method will be used together to build a cross-client metrics aggregator when defining the federated training processes or evaluation computations. For example, a simple tff.learning.metrics.sum_then_finalize aggregator will first sum the unfinalized metric values from clients, and then call the finalizer functions at the server.

You can find examples of how to define your own custom tff.learning.models.VariableModel in the second part of our image classification tutorial, as well as in the example models we use for testing in model_examples.py .

Converters for Keras

Nearly all the information that's required by TFF can be derived by calling tf.keras interfaces, so if you have a Keras model, you can rely on tff.learning.models.from_keras_model to construct a tff.learning.models.VariableModel .

Note that TFF still wants you to provide a constructor - a no-argument model function such as the following:

def model_fn():
  keras_model = ...
  return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)

In addition to the model itself, you supply a sample batch of data which TFF uses to determine the type and shape of your model's input. This ensures that TFF can properly instantiate the model for the data that will actually be present on client devices (since we assume this data is not generally available at the time you are constructing the TensorFlow to be serialized).

The use of Keras wrappers is illustrated in our image classification and text generation tutorials.

Federated Computation Builders

The tff.learning package provides several builders for tff.Computation s that perform learning-related tasks; we expect the set of such computations to expand in the future.

Architectural assumptions

Execution

There are two distinct phases in running a federated computation.

  • Compile : TFF first compiles federated learning algorithms into an abstract serialized representation of the entire distributed computation. This is when TensorFlow serialization happens, but other transformations can occur to support more efficient execution. We refer to the serialized representation emitted by the compiler as a federated computation .

  • Execute TFF provides ways to execute these computations. For now, execution is only supported via a local simulation (eg, in a notebook using simulated decentralized data).

A federated computation generated by TFF's Federated Learning API, such as a training algorithm that uses federated model averaging , or a federated evaluation, includes a number of elements, most notably:

  • A serialized form of your model code as well as additional TensorFlow code constructed by the Federated Learning framework to drive your model's training/evaluation loop (such as constructing optimizers, applying model updates, iterating over tf.data.Dataset s, and computing metrics, and applying the aggregated update on the server, to name a few).

  • A declarative specification of the communication between the clients and a server (typically various forms of aggregation across the client devices, and broadcasting from the server to all clients), and how this distributed communication is interleaved with the client-local or server-local execution of TensorFlow code.

The federated computations represented in this serialized form are expressed in a platform-independent internal language distinct from Python, but to use the Federated Learning API, you won't need to concern yourself with the details of this representation. The computations are represented in your Python code as objects of type tff.Computation , which for the most part you can treat as opaque Python callable s.

In the tutorials, you will invoke those federated computations as if they were regular Python functions, to be executed locally. However, TFF is designed to express federated computations in a manner agnostic to most aspects of the execution environment, so that they can potentially be deployable to, eg, groups of devices running Android , or to clusters in a datacenter. Again, the main consequence of this are strong assumptions about serialization . In particular, when you invoke one of the build_... methods described below the computation is fully serialized.

Modeling state

TFF is a functional programming environment, yet many processes of interest in federated learning are stateful. For example, a training loop that involves multiple rounds of federated model averaging is an example of what we could classify as a stateful process . In this process, the state that evolves from round to round includes the set of model parameters that are being trained, and possibly additional state associated with the optimizer (eg, a momentum vector).

Since TFF is functional, stateful processes are modeled in TFF as computations that accept the current state as an input and then provide the updated state as an output. In order to fully define a stateful process, one also needs to specify where the initial state comes from (otherwise we cannot bootstrap the process). This is captured in the definition of the helper class tff.templates.IterativeProcess , with the 2 properties initialize and next corresponding to the initialization and iteration, respectively.

Available builders

At the moment, TFF provides various builder functions that generate federated computations for federated training and evaluation. Two notable examples include:

Datasets

Architectural assumptions

Client selection

In the typical federated learning scenario, we have a large population of potentially hundreds of millions of client devices, of which only a small portion may be active and available for training at any given moment (for example, this may be limited to clients that are plugged in to a power source, not on a metered network, and otherwise idle). Generally, the set of clients available to participate in training or evaluation is outside of the developer's control. Furthermore, as it's impractical to coordinate millions of clients, a typical round of training or evaluation will include only a fraction of the available clients, which may be sampled at random .

The key consequence of this is that federated computations, by design, are expressed in a manner that is oblivious to the exact set of participants; all processing is expressed as aggregate operations on an abstract group of anonymous clients , and that group might vary from one round of training to another. The actual binding of the computation to the concrete participants, and thus to the concrete data they feed into the computation, is thus modeled outside of the computation itself.

In order to simulate a realistic deployment of your federated learning code, you will generally write a training loop that looks like this:

trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...

def sample(federate_data):
  return ...

while True:
  data_for_this_round = sample(federated_training_data)
  result = trainer.next(state, data_for_this_round)
  state = result.state

In order to facilitate this, when using TFF in simulations, federated data is accepted as Python list s, with one element per participating client device to represent that device's local tf.data.Dataset .

Abstract interfaces

In order to standardize dealing with simulated federated data sets, TFF provides an abstract interface tff.simulation.datasets.ClientData , which allows one to enumerate the set of clients, and to construct a tf.data.Dataset that contains the data of a particular client. Those tf.data.Dataset s can be fed directly as input to the generated federated computations in eager mode.

It should be noted that the ability to access client identities is a feature that's only provided by the datasets for use in simulations, where the ability to train on data from specific subsets of clients may be needed (eg, to simulate the diurnal availability of different types of clients). The compiled computations and the underlying runtime do not involve any notion of client identity. Once data from a specific subset of clients has been selected as an input, eg, in a call to tff.templates.IterativeProcess.next , client identities no longer appear in it.

Available data sets

We have dedicated the namespace tff.simulation.datasets for datasets that implement the tff.simulation.datasets.ClientData interface for use in simulations, and seeded it with datasets to support the image classification and text generation tutorials. We'd like to encourage you to contribute your own datasets to the platform.