Aprendizaje federado

Descripción general

Este documento presenta interfaces que facilitan las tareas de aprendizaje federado, como la capacitación o evaluación federada con modelos de aprendizaje automático existentes implementados en TensorFlow. Al diseñar estas interfaces, nuestro objetivo principal era 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 que vuelva a contribuir a la plataforma. TFF ha sido diseñado teniendo en cuenta la extensibilidad y la componibilidad, 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 ajustar sus modelos existentes para usarlos con TFF. Ajustar un modelo puede ser tan simple como llamar a una única función de ajuste (por ejemplo, tff.learning.models.from_keras_model ) o definir una subclase de la interfaz tff.learning.models.VariableModel para una personalización total.

  • Constructores de computación federada . Funciones auxiliares que construyen cálculos federados para capacitación o evaluación, utilizando 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. Aunque el aprendizaje federado está diseñado para usarse con datos descentralizados que no pueden simplemente descargarse en una ubicación centralizada, en las etapas de investigación y desarrollo suele ser conveniente realizar experimentos iniciales utilizando datos que pueden descargarse y manipularse 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 , excepto 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 ejecución.

Antes de continuar, te recomendamos que primero revises los tutoriales sobre clasificación de imágenes y generación de texto , ya que introducen la mayoría de los conceptos aquí descritos mediante ejemplos concretos. Si está interesado en aprender más sobre cómo funciona TFF, puede echar un vistazo al tutorial de algoritmos personalizados como introducción a las interfaces de nivel inferior que utilizamos para expresar la lógica de los cálculos federados y para estudiar la implementación existente del 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 usted escribe podría ejecutarse en una gran cantidad de clientes heterogéneos con capacidades diversas. 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 sean capaces de alojar tiempos de ejecución de Python; Lo único que podemos asumir 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 el código de su modelo debe ser serializable como un gráfico de TensorFlow.

Aún puedes (y debes) desarrollar tu código TF siguiendo las mejores prácticas más recientes, como usar el modo ansioso. Sin embargo, el código final debe ser serializable (por ejemplo, puede incluirse como una tf.function código en modo ansioso). Esto garantiza que cualquier estado de Python o flujo de control necesario en el momento de la ejecución pueda serializarse (posiblemente con la ayuda de Autograph ).

Actualmente, TensorFlow no es totalmente compatible con la serialización y deseriaizació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 está empaquetada 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á algunos 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 del modelo, así como cualquier métrica definida para el modelo automáticamente. Sin embargo, aún puede resultar ú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 (variables) del modelo, que continúan evolucionando secuencialmente a medida que el modelo se entrena localmente, como a las estadísticas que usted calcula (como la pérdida promedio, la precisión y otras métricas), que su modelo actualizará nuevamente 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 su 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 las pérdidas por lote o por ejemplo, etc.

    • TFF invoca el método forward_pass en su Model varias veces, secuencialmente 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 permitirle compilar todas las estadísticas resumidas que recopiló en un conjunto compacto de métricas que el cliente exportará. Aquí es donde su código de 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. Nuevamente, se aplica tanto a los parámetros (variables) del modelo, que se promedian entre los clientes, como a las métricas que su modelo exportó como resultado de la agregación local.

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

    La estructura general del procesamiento es la siguiente:

    • Un servidor distribuye el modelo inicial y cualquier parámetro requerido para la capacitación 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 describió 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 cálculo 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 paso directo y las estadísticas que desea informar, respectivamente. El TensorFlow construido con esos métodos debe ser serializable, como se analizó anteriormente.

  • La propiedad input_spec , así como las 3 propiedades que devuelven subconjuntos de sus variables locales, no entrenables y entrenables representan los metadatos. TFF utiliza 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 (de modo que no se pueda crear una instancia de su modelo sobre datos que no coinciden 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 utilizará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 simple tff.learning.metrics.sum_then_finalize primero sumará los valores de métricas no finalizados de los clientes y luego llamará a las funciones de finalización 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 utilizamos para las pruebas 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 aún 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í, usted proporciona un lote de datos de muestra que TFF utiliza 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 se construye TensorFlow para su serialización).

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

Constructores de computación federada

El paquete tff.learning proporciona varios constructores para tff.Computation 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álculo distribuido. Aquí es cuando ocurre la serialización de TensorFlow, pero pueden ocurrir otras transformaciones para admitir 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 sólo se admite mediante una simulación local (por ejemplo, en un cuaderno que utiliza datos descentralizados simulados).

Un cálculo federado generado por la API de aprendizaje federado de TFF, como un algoritmo de entrenamiento que utiliza un promedio de modelo federado o una evaluación federada, incluye una serie de elementos, en particular:

  • Una forma serializada del código de su modelo, así como código adicional de TensorFlow creado por el marco de aprendizaje federado para impulsar el ciclo de entrenamiento/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 y 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 (normalmente 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 entrelaza con la ejecución local del cliente o local del servidor. del código 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 utilizar la API de aprendizaje federado, no necesitará preocuparse por los detalles de esta representación. Los cálculos se representan en su código Python como objetos de tipo tff.Computation , que en su mayor parte puede tratar como mensajes de texto opacos callable de Python.

En los tutoriales, invocará esos cálculos federados como si fueran funciones normales de Python, para ejecutarlas localmente. Sin embargo, TFF está diseñado para expresar cálculos federados de una manera independiente de la mayoría de los aspectos del entorno de ejecución, de modo que potencialmente 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 las fuertes suposiciones sobre la serialización . En particular, cuando invoca uno de los métodos build_... que se describen a continuación, el cálculo se serializa completamente.

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 múltiples rondas de promediado 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 una ronda a otra 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 podremos 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

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 limitarse a clientes que están conectado 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 millones de clientes, una ronda típica de capacitación o evaluación incluirá sólo una fracción de los clientes disponibles, que pueden ser muestreados 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álculo con los participantes concretos y, por tanto, con los datos concretos que introducen en el cálculo, se modela así fuera del cálculo mismo.

Para simular una implementación realista de su código de aprendizaje federado, generalmente escribirá un bucle de entrenamiento similar a este:

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 utiliza 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 se pueden enviar directamente como entrada a los cálculos federados generados en modo ansioso.

Cabe señalar que la capacidad de acceder a las identidades de los clientes es una característica 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 (por ejemplo, para simular la disponibilidad diurna de diferentes tipos de clientes). Los cálculos compilados y el tiempo de ejecución subyacente no implican ninguna noción de identidad del cliente. Una vez que se han seleccionado como entrada los datos de un subconjunto específico de clientes, por ejemplo, en una llamada a tff.templates.IterativeProcess.next , las identidades de los clientes ya no aparecen en ellos.

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 respaldar los tutoriales de clasificación de imágenes y generación de texto . Nos gustaría animarlo a contribuir con sus propios conjuntos de datos a la plataforma.