Aprendizado Federado

Visão geral

Este documento apresenta interfaces que facilitam tarefas de aprendizado federado, como treinamento federado ou avaliação com modelos existentes de aprendizado de máquina implementados no TensorFlow. Ao projetar essas interfaces, nosso principal objetivo era possibilitar a experimentação do aprendizado federado sem exigir o conhecimento de como ele funciona nos bastidores e avaliar os algoritmos de aprendizado federado implementados em uma variedade de modelos e dados existentes. Nós encorajamos você a contribuir de volta para a plataforma. TFF foi projetado com extensibilidade e capacidade de composição em mente, e agradecemos as contribuições; estamos ansiosos para ver o que você inventa!

As interfaces oferecidas por esta camada consistem nas três partes principais a seguir:

  • Modelos . Classes e funções auxiliares que permitem agrupar seus modelos existentes para uso com TFF. Envolver um modelo pode ser tão simples quanto chamar uma única função de envolvimento (por exemplo, tff.learning.models.from_keras_model ) ou definir uma subclasse da interface tff.learning.models.VariableModel para total personalização.

  • Construtores Federados de Computação . Funções auxiliares que constroem cálculos federados para treinamento ou avaliação, usando seus modelos existentes.

  • Conjuntos de dados . Coleções predefinidas de dados que você pode baixar e acessar em Python para uso na simulação de cenários de aprendizagem federada. Embora o aprendizado federado seja projetado para uso com dados descentralizados que não podem ser simplesmente baixados em um local centralizado, nos estágios de pesquisa e desenvolvimento geralmente é conveniente realizar experimentos iniciais usando dados que podem ser baixados e manipulados localmente, especialmente para desenvolvedores que podem ser novo na abordagem.

Essas interfaces são definidas principalmente no namespace tff.learning , exceto para conjuntos de dados de pesquisa e outros recursos relacionados à simulação que foram agrupados em tff.simulation . Essa camada é implementada usando interfaces de nível inferior oferecidas pelo Federated Core (FC) , que também fornece um ambiente de tempo de execução.

Antes de prosseguir, recomendamos que você revise primeiro os tutoriais sobre classificação de imagens e geração de texto , pois eles introduzem a maioria dos conceitos descritos aqui usando exemplos concretos. Se você estiver interessado em aprender mais sobre como o TFF funciona, você pode querer dar uma olhada no tutorial de algoritmos personalizados como uma introdução às interfaces de nível inferior que usamos para expressar a lógica de cálculos federados e para estudar a implementação existente do interfaces tff.learning .

modelos

Suposições arquitetônicas

Serialização

O TFF visa oferecer suporte a uma variedade de cenários de aprendizado distribuído nos quais o código do modelo de aprendizado de máquina que você escreve pode estar sendo executado em um grande número de clientes heterogêneos com diversos recursos. Embora em uma extremidade do espectro, em alguns aplicativos, esses clientes possam ser poderosos servidores de banco de dados, muitos usos importantes que nossa plataforma pretende oferecer envolvem dispositivos móveis e integrados com recursos limitados. Não podemos presumir que esses dispositivos sejam capazes de hospedar tempos de execução do Python; a única coisa que podemos assumir neste momento é que eles são capazes de hospedar um tempo de execução local do TensorFlow. Portanto, uma suposição de arquitetura fundamental que fazemos no TFF é que o código do modelo deve ser serializável como um gráfico do TensorFlow.

Você ainda pode (e deve) desenvolver seu código TF seguindo as melhores práticas mais recentes, como usar o modo ansioso. No entanto, o código final deve ser serializável (por exemplo, pode ser agrupado como uma tf.function para código de modo ansioso). Isso garante que qualquer estado do Python ou fluxo de controle necessário no tempo de execução possa ser serializado (possivelmente com a ajuda do Autograph ).

Atualmente, o TensorFlow não é totalmente compatível com a serialização e desserialização do TensorFlow no modo avançado. Assim, a serialização em TFF atualmente segue o padrão TF 1.0, onde todo o código deve ser construído dentro de um tf.Graph que o TFF controla. Isso significa que atualmente o TFF não pode consumir um modelo já construído; em vez disso, a lógica de definição do modelo é empacotada em uma função sem argumentos que retorna um tff.learning.models.VariableModel . Essa função é então chamada pelo TFF para garantir que todos os componentes do modelo sejam serializados. Além disso, sendo um ambiente fortemente tipado, o TFF exigirá um pouco de metadados adicionais, como uma especificação do tipo de entrada do seu modelo.

Agregação

Recomendamos enfaticamente que a maioria dos usuários construa modelos usando Keras, consulte a seção Conversores para Keras abaixo. Esses wrappers manipulam a agregação de atualizações de modelo, bem como quaisquer métricas definidas para o modelo automaticamente. No entanto, ainda pode ser útil entender como a agregação é tratada para um tff.learning.models.VariableModel geral.

Sempre há pelo menos duas camadas de agregação no aprendizado federado: agregação local no dispositivo e agregação entre dispositivos (ou federada):

  • Agregação local . Esse nível de agregação refere-se à agregação em vários lotes de exemplos pertencentes a um cliente individual. Aplica-se tanto aos parâmetros do modelo (variáveis), que continuam a evoluir sequencialmente à medida que o modelo é treinado localmente, quanto às estatísticas que você calcula (como perda média, precisão e outras métricas), que seu modelo atualizará novamente localmente à medida que itera sobre o fluxo de dados local de cada cliente individual.

    A execução da agregação nesse nível é responsabilidade do seu código de modelo e é realizada usando construções padrão do TensorFlow.

    A estrutura geral do processamento é a seguinte:

    • O modelo primeiro constrói tf.Variable s para armazenar agregados, como o número de lotes ou o número de exemplos processados, a soma das perdas por lote ou por exemplo, etc.

    • O TFF invoca o método forward_pass em seu Model várias vezes, sequencialmente em lotes subsequentes de dados do cliente, o que permite atualizar as variáveis ​​que contêm vários agregados como efeito colateral.

    • Por fim, o TFF invoca o método report_local_unfinalized_metrics em seu modelo para permitir que seu modelo compile todas as estatísticas resumidas coletadas em um conjunto compacto de métricas a serem exportadas pelo cliente. É aqui que seu código de modelo pode, por exemplo, dividir a soma das perdas pelo número de exemplos processados ​​para exportar a perda média, etc.

  • Agregação federada . Esse nível de agregação refere-se à agregação entre vários clientes (dispositivos) no sistema. Novamente, isso se aplica aos parâmetros do modelo (variáveis), cuja média está sendo calculada entre os clientes, bem como às métricas que seu modelo exportou como resultado da agregação local.

    A realização da agregação a este nível é da responsabilidade da TFF. Como criador de modelo, no entanto, você pode controlar esse processo (mais sobre isso abaixo).

    A estrutura geral do processamento é a seguinte:

    • O modelo inicial e quaisquer parâmetros necessários para o treinamento são distribuídos por um servidor para um subconjunto de clientes que participarão de uma rodada de treinamento ou avaliação.

    • Em cada cliente, independentemente e em paralelo, seu código de modelo é invocado repetidamente em um fluxo de lotes de dados locais para produzir um novo conjunto de parâmetros de modelo (durante o treinamento) e um novo conjunto de métricas locais, conforme descrito acima (isso é local agregação).

    • O TFF executa um protocolo de agregação distribuído para acumular e agregar os parâmetros do modelo e as métricas exportadas localmente em todo o sistema. Essa lógica é expressa de maneira declarativa usando a própria linguagem de computação federada do TFF (não no TensorFlow). Consulte o tutorial de algoritmos personalizados para saber mais sobre a API de agregação.

Interfaces abstratas

Essa interface básica construtor + metadados é representada pela interface tff.learning.models.VariableModel , conforme a seguir:

  • Os métodos constructor, forward_pass e report_local_unfinalized_metrics devem construir variáveis ​​de modelo, forward pass e estatísticas que você deseja relatar, respectivamente. O TensorFlow construído por esses métodos deve ser serializável, conforme discutido acima.

  • A propriedade input_spec , bem como as 3 propriedades que retornam subconjuntos de suas variáveis ​​treináveis, não treináveis ​​e locais representam os metadados. O TFF usa essas informações para determinar como conectar partes de seu modelo aos algoritmos de otimização federados e para definir assinaturas de tipo internas para auxiliar na verificação da exatidão do sistema construído (para que seu modelo não possa ser instanciado sobre dados que não correspondam ao que o modelo é projetado para consumir).

Além disso, a interface abstrata tff.learning.models.VariableModel expõe uma propriedade metric_finalizers que recebe os valores não finalizados de uma métrica (retornados por report_local_unfinalized_metrics() ) e retorna os valores finalizados da métrica. Os métodos metric_finalizers e report_local_unfinalized_metrics() serão usados ​​juntos para criar um agregador de métricas entre clientes ao definir os processos de treinamento federados ou cálculos de avaliação. Por exemplo, um agregador tff.learning.metrics.sum_then_finalize simples primeiro somará os valores de métrica não finalizados dos clientes e, em seguida, chamará as funções do finalizador no servidor.

Você pode encontrar exemplos de como definir seu próprio tff.learning.models.VariableModel personalizado na segunda parte de nosso tutorial de classificação de imagem , bem como nos modelos de exemplo que usamos para testar em model_examples.py .

Conversores para Keras

Quase todas as informações exigidas pelo TFF podem ser derivadas chamando interfaces tf.keras , portanto, se você tiver um modelo Keras, poderá confiar em tff.learning.models.from_keras_model para construir um tff.learning.models.VariableModel .

Observe que o TFF ainda deseja que você forneça um construtor - uma função de modelo sem argumentos, como a seguinte:

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

Além do próprio modelo, você fornece um lote de amostra de dados que o TFF usa para determinar o tipo e a forma da entrada do seu modelo. Isso garante que o TFF possa instanciar adequadamente o modelo para os dados que realmente estarão presentes nos dispositivos cliente (uma vez que supomos que esses dados geralmente não estejam disponíveis no momento em que você está construindo o TensorFlow a ser serializado).

O uso de wrappers Keras é ilustrado em nossos tutoriais de classificação de imagem e geração de texto .

Construtores Federados de Computação

O pacote tff.learning fornece vários construtores para tff.Computation s que executam tarefas relacionadas ao aprendizado; esperamos que o conjunto de tais cálculos se expanda no futuro.

Suposições arquitetônicas

Execução

Existem duas fases distintas na execução de uma computação federada.

  • Compilar : TFF primeiro compila algoritmos de aprendizado federados em uma representação serializada abstrata de toda a computação distribuída. É quando a serialização do TensorFlow acontece, mas outras transformações podem ocorrer para dar suporte a uma execução mais eficiente. Referimo-nos à representação serializada emitida pelo compilador como uma computação federada .

  • Executar TFF fornece maneiras de executar esses cálculos. Por enquanto, a execução é suportada apenas por meio de uma simulação local (por exemplo, em um notebook usando dados descentralizados simulados).

Uma computação federada gerada pela API de aprendizado federado do TFF, como um algoritmo de treinamento que usa média de modelo federado ou uma avaliação federada, inclui vários elementos, principalmente:

  • Uma forma serializada de seu código de modelo, bem como código TensorFlow adicional construído pela estrutura de aprendizado federado para conduzir o loop de treinamento/avaliação de seu modelo (como construir otimizadores, aplicar atualizações de modelo, iterar sobre tf.data.Dataset s e calcular métricas, e aplicando a atualização agregada no servidor, para citar alguns).

  • Uma especificação declarativa da comunicação entre os clientes e um servidor (normalmente várias formas de agregação entre os dispositivos clientes e transmissão do servidor para todos os clientes) e como essa comunicação distribuída é intercalada com a execução cliente-local ou servidor-local do código do TensorFlow.

As computações federadas representadas neste formato serializado são expressas em uma linguagem interna independente de plataforma distinta do Python, mas para usar a API de aprendizado federado, você não precisará se preocupar com os detalhes dessa representação. As computações são representadas em seu código Python como objetos do tipo tff.Computation , que na maioria das vezes você pode tratar como s opacos callable Python.

Nos tutoriais, você invocará essas computações federadas como se fossem funções regulares do Python, a serem executadas localmente. No entanto, o TFF é projetado para expressar cálculos federados de maneira agnóstica para a maioria dos aspectos do ambiente de execução, para que possam ser implantados em, por exemplo, grupos de dispositivos executando Android ou clusters em um datacenter. Novamente, a principal consequência disso são fortes suposições sobre a serialização . Em particular, quando você chama um dos métodos build_... descritos abaixo, a computação é totalmente serializada.

Estado de modelagem

O TFF é um ambiente de programação funcional, mas muitos processos de interesse no aprendizado federado são stateful. Por exemplo, um loop de treinamento que envolve várias rodadas de média de modelo federado é um exemplo do que poderíamos classificar como um processo com estado . Nesse processo, o estado que evolui de uma rodada para outra inclui o conjunto de parâmetros do modelo que está sendo treinado e, possivelmente, um estado adicional associado ao otimizador (por exemplo, um vetor de momento).

Como a TFF é funcional, os processos com estado são modelados na TFF como cálculos que aceitam o estado atual como entrada e fornecem o estado atualizado como saída. Para definir completamente um processo com estado, também é necessário especificar de onde vem o estado inicial (caso contrário, não podemos inicializar o processo). Isso é capturado na definição da classe auxiliar tff.templates.IterativeProcess , com as 2 propriedades initialize e next correspondentes à inicialização e iteração, respectivamente.

Construtores disponíveis

No momento, o TFF fornece várias funções de construtor que geram cálculos federados para treinamento e avaliação federados. Dois exemplos notáveis ​​incluem:

Conjuntos de dados

Suposições arquitetônicas

Seleção do cliente

No cenário típico de aprendizagem federada, temos uma grande população de potencialmente centenas de milhões de dispositivos clientes, dos quais apenas uma pequena parte pode estar ativa e disponível para treinamento em um determinado momento (por exemplo, isso pode ser limitado a clientes que estão conectado a uma fonte de energia, não em uma rede limitada e, caso contrário, ocioso). Geralmente, o conjunto de clientes disponíveis para participar do treinamento ou avaliação está fora do controle do desenvolvedor. Além disso, como é impraticável coordenar milhões de clientes, uma rodada típica de treinamento ou avaliação incluirá apenas uma fração dos clientes disponíveis, que podem ser amostrados aleatoriamente .

A principal consequência disso é que as computações federadas, por design, são expressas de uma maneira que ignora o conjunto exato de participantes; todo processamento é expresso como operações agregadas em um grupo abstrato de clientes anônimos, e esse grupo pode variar de uma rodada de treinamento para outra. A ligação real da computação aos participantes concretos e, portanto, aos dados concretos que eles alimentam na computação é, portanto, modelada fora da própria computação.

Para simular uma implantação realista de seu código de aprendizado federado, você geralmente escreverá um loop de treinamento semelhante 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 isso, ao usar TFF em simulações, os dados federados são aceitos como list Python, com um elemento por dispositivo cliente participante para representar o tf.data.Dataset local desse dispositivo.

Interfaces abstratas

Para padronizar o tratamento de conjuntos de dados federados simulados, o TFF fornece uma interface abstrata tff.simulation.datasets.ClientData , que permite enumerar o conjunto de clientes e construir um tf.data.Dataset que contém os dados de um determinado cliente. Esses tf.data.Dataset s podem ser alimentados diretamente como entrada para os cálculos federados gerados no modo avançado.

Deve-se notar que a capacidade de acessar identidades de clientes é um recurso fornecido apenas pelos conjuntos de dados para uso em simulações, onde a capacidade de treinar dados de subconjuntos específicos de clientes pode ser necessária (por exemplo, para simular a disponibilidade diurna de diferentes tipos de clientes). Os cálculos compilados e o tempo de execução subjacente não envolvem nenhuma noção de identidade do cliente. Uma vez que os dados de um subconjunto específico de clientes tenham sido selecionados como uma entrada, por exemplo, em uma chamada para tff.templates.IterativeProcess.next , as identidades do cliente não aparecem mais nele.

Conjuntos de dados disponíveis

Dedicamos o namespace tff.simulation.datasets para conjuntos de dados que implementam a interface tff.simulation.datasets.ClientData para uso em simulações e o semeamos com conjuntos de dados para dar suporte aos tutoriais de classificação de imagem e geração de texto . Gostaríamos de incentivá-lo a contribuir com seus próprios conjuntos de dados para a plataforma.

,

Visão geral

Este documento apresenta interfaces que facilitam tarefas de aprendizado federado, como treinamento federado ou avaliação com modelos existentes de aprendizado de máquina implementados no TensorFlow. Ao projetar essas interfaces, nosso principal objetivo era possibilitar a experimentação do aprendizado federado sem exigir o conhecimento de como ele funciona nos bastidores e avaliar os algoritmos de aprendizado federado implementados em uma variedade de modelos e dados existentes. Nós encorajamos você a contribuir de volta para a plataforma. TFF foi projetado com extensibilidade e capacidade de composição em mente, e agradecemos as contribuições; estamos ansiosos para ver o que você inventa!

As interfaces oferecidas por esta camada consistem nas três partes principais a seguir:

  • Modelos . Classes e funções auxiliares que permitem agrupar seus modelos existentes para uso com TFF. Envolver um modelo pode ser tão simples quanto chamar uma única função de envolvimento (por exemplo, tff.learning.models.from_keras_model ) ou definir uma subclasse da interface tff.learning.models.VariableModel para total personalização.

  • Construtores Federados de Computação . Funções auxiliares que constroem cálculos federados para treinamento ou avaliação, usando seus modelos existentes.

  • Conjuntos de dados . Coleções predefinidas de dados que você pode baixar e acessar em Python para uso na simulação de cenários de aprendizagem federada. Embora o aprendizado federado seja projetado para uso com dados descentralizados que não podem ser simplesmente baixados em um local centralizado, nos estágios de pesquisa e desenvolvimento geralmente é conveniente realizar experimentos iniciais usando dados que podem ser baixados e manipulados localmente, especialmente para desenvolvedores que podem ser novo na abordagem.

Essas interfaces são definidas principalmente no namespace tff.learning , exceto para conjuntos de dados de pesquisa e outros recursos relacionados à simulação que foram agrupados em tff.simulation . Essa camada é implementada usando interfaces de nível inferior oferecidas pelo Federated Core (FC) , que também fornece um ambiente de tempo de execução.

Antes de prosseguir, recomendamos que você revise primeiro os tutoriais sobre classificação de imagens e geração de texto , pois eles introduzem a maioria dos conceitos descritos aqui usando exemplos concretos. Se você estiver interessado em aprender mais sobre como o TFF funciona, você pode querer dar uma olhada no tutorial de algoritmos personalizados como uma introdução às interfaces de nível inferior que usamos para expressar a lógica de cálculos federados e para estudar a implementação existente do interfaces tff.learning .

modelos

Suposições arquitetônicas

Serialização

O TFF visa oferecer suporte a uma variedade de cenários de aprendizado distribuído nos quais o código do modelo de aprendizado de máquina que você escreve pode estar sendo executado em um grande número de clientes heterogêneos com diversos recursos. Embora em uma extremidade do espectro, em alguns aplicativos, esses clientes possam ser poderosos servidores de banco de dados, muitos usos importantes que nossa plataforma pretende oferecer envolvem dispositivos móveis e integrados com recursos limitados. Não podemos presumir que esses dispositivos sejam capazes de hospedar tempos de execução do Python; a única coisa que podemos assumir neste momento é que eles são capazes de hospedar um tempo de execução local do TensorFlow. Portanto, uma suposição de arquitetura fundamental que fazemos no TFF é que o código do modelo deve ser serializável como um gráfico do TensorFlow.

Você ainda pode (e deve) desenvolver seu código TF seguindo as melhores práticas mais recentes, como usar o modo ansioso. No entanto, o código final deve ser serializável (por exemplo, pode ser agrupado como uma tf.function para código de modo ansioso). Isso garante que qualquer estado do Python ou fluxo de controle necessário no tempo de execução possa ser serializado (possivelmente com a ajuda do Autograph ).

Atualmente, o TensorFlow não é totalmente compatível com a serialização e desserialização do TensorFlow no modo avançado. Assim, a serialização em TFF atualmente segue o padrão TF 1.0, onde todo o código deve ser construído dentro de um tf.Graph que o TFF controla. Isso significa que atualmente o TFF não pode consumir um modelo já construído; em vez disso, a lógica de definição do modelo é empacotada em uma função sem argumentos que retorna um tff.learning.models.VariableModel . Essa função é então chamada pelo TFF para garantir que todos os componentes do modelo sejam serializados. Além disso, sendo um ambiente fortemente tipado, o TFF exigirá um pouco de metadados adicionais, como uma especificação do tipo de entrada do seu modelo.

Agregação

Recomendamos enfaticamente que a maioria dos usuários construa modelos usando Keras, consulte a seção Conversores para Keras abaixo. Esses wrappers manipulam a agregação de atualizações de modelo, bem como quaisquer métricas definidas para o modelo automaticamente. No entanto, ainda pode ser útil entender como a agregação é tratada para um tff.learning.models.VariableModel geral.

Sempre há pelo menos duas camadas de agregação no aprendizado federado: agregação local no dispositivo e agregação entre dispositivos (ou federada):

  • Agregação local . Esse nível de agregação refere-se à agregação em vários lotes de exemplos pertencentes a um cliente individual. Aplica-se tanto aos parâmetros do modelo (variáveis), que continuam a evoluir sequencialmente à medida que o modelo é treinado localmente, quanto às estatísticas que você calcula (como perda média, precisão e outras métricas), que seu modelo atualizará novamente localmente à medida que itera sobre o fluxo de dados local de cada cliente individual.

    A execução da agregação nesse nível é responsabilidade do seu código de modelo e é realizada usando construções padrão do TensorFlow.

    A estrutura geral do processamento é a seguinte:

    • O modelo primeiro constrói tf.Variable s para armazenar agregados, como o número de lotes ou o número de exemplos processados, a soma das perdas por lote ou por exemplo, etc.

    • O TFF invoca o método forward_pass em seu Model várias vezes, sequencialmente em lotes subsequentes de dados do cliente, o que permite atualizar as variáveis ​​que contêm vários agregados como efeito colateral.

    • Por fim, o TFF invoca o método report_local_unfinalized_metrics em seu modelo para permitir que seu modelo compile todas as estatísticas resumidas coletadas em um conjunto compacto de métricas a serem exportadas pelo cliente. É aqui que seu código de modelo pode, por exemplo, dividir a soma das perdas pelo número de exemplos processados ​​para exportar a perda média, etc.

  • Agregação federada . Esse nível de agregação refere-se à agregação entre vários clientes (dispositivos) no sistema. Novamente, isso se aplica aos parâmetros do modelo (variáveis), cuja média está sendo calculada entre os clientes, bem como às métricas que seu modelo exportou como resultado da agregação local.

    A realização da agregação a este nível é da responsabilidade da TFF. Como criador de modelo, no entanto, você pode controlar esse processo (mais sobre isso abaixo).

    A estrutura geral do processamento é a seguinte:

    • O modelo inicial e quaisquer parâmetros necessários para o treinamento são distribuídos por um servidor para um subconjunto de clientes que participarão de uma rodada de treinamento ou avaliação.

    • Em cada cliente, independentemente e em paralelo, seu código de modelo é invocado repetidamente em um fluxo de lotes de dados locais para produzir um novo conjunto de parâmetros de modelo (durante o treinamento) e um novo conjunto de métricas locais, conforme descrito acima (isso é local agregação).

    • O TFF executa um protocolo de agregação distribuído para acumular e agregar os parâmetros do modelo e as métricas exportadas localmente em todo o sistema. Essa lógica é expressa de maneira declarativa usando a própria linguagem de computação federada do TFF (não no TensorFlow). Consulte o tutorial de algoritmos personalizados para saber mais sobre a API de agregação.

Interfaces abstratas

Essa interface básica construtor + metadados é representada pela interface tff.learning.models.VariableModel , conforme a seguir:

  • Os métodos constructor, forward_pass e report_local_unfinalized_metrics devem construir variáveis ​​de modelo, forward pass e estatísticas que você deseja relatar, respectivamente. O TensorFlow construído por esses métodos deve ser serializável, conforme discutido acima.

  • A propriedade input_spec , bem como as 3 propriedades que retornam subconjuntos de suas variáveis ​​treináveis, não treináveis ​​e locais representam os metadados. O TFF usa essas informações para determinar como conectar partes de seu modelo aos algoritmos de otimização federados e para definir assinaturas de tipo internas para auxiliar na verificação da exatidão do sistema construído (para que seu modelo não possa ser instanciado sobre dados que não correspondam ao que o modelo é projetado para consumir).

Além disso, a interface abstrata tff.learning.models.VariableModel expõe uma propriedade metric_finalizers que recebe os valores não finalizados de uma métrica (retornados por report_local_unfinalized_metrics() ) e retorna os valores finalizados da métrica. Os métodos metric_finalizers e report_local_unfinalized_metrics() serão usados ​​juntos para criar um agregador de métricas entre clientes ao definir os processos de treinamento federados ou cálculos de avaliação. Por exemplo, um agregador tff.learning.metrics.sum_then_finalize simples primeiro somará os valores de métrica não finalizados dos clientes e, em seguida, chamará as funções do finalizador no servidor.

Você pode encontrar exemplos de como definir seu próprio tff.learning.models.VariableModel personalizado na segunda parte de nosso tutorial de classificação de imagem , bem como nos modelos de exemplo que usamos para testar em model_examples.py .

Conversores para Keras

Quase todas as informações exigidas pelo TFF podem ser derivadas chamando interfaces tf.keras , portanto, se você tiver um modelo Keras, poderá confiar em tff.learning.models.from_keras_model para construir um tff.learning.models.VariableModel .

Observe que o TFF ainda deseja que você forneça um construtor - uma função de modelo sem argumentos, como a seguinte:

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

Além do próprio modelo, você fornece um lote de amostra de dados que o TFF usa para determinar o tipo e a forma da entrada do seu modelo. Isso garante que o TFF possa instanciar adequadamente o modelo para os dados que realmente estarão presentes nos dispositivos cliente (uma vez que supomos que esses dados geralmente não estejam disponíveis no momento em que você está construindo o TensorFlow a ser serializado).

O uso de wrappers Keras é ilustrado em nossos tutoriais de classificação de imagem e geração de texto .

Construtores Federados de Computação

O pacote tff.learning fornece vários construtores para tff.Computation s que executam tarefas relacionadas ao aprendizado; esperamos que o conjunto de tais cálculos se expanda no futuro.

Suposições arquitetônicas

Execução

Existem duas fases distintas na execução de uma computação federada.

  • Compilar : TFF primeiro compila algoritmos de aprendizado federados em uma representação serializada abstrata de toda a computação distribuída. É quando a serialização do TensorFlow acontece, mas outras transformações podem ocorrer para dar suporte a uma execução mais eficiente. Referimo-nos à representação serializada emitida pelo compilador como uma computação federada .

  • Executar TFF fornece maneiras de executar esses cálculos. Por enquanto, a execução é suportada apenas por meio de uma simulação local (por exemplo, em um notebook usando dados descentralizados simulados).

Uma computação federada gerada pela API de aprendizado federado do TFF, como um algoritmo de treinamento que usa média de modelo federado ou uma avaliação federada, inclui vários elementos, principalmente:

  • Uma forma serializada de seu código de modelo, bem como código TensorFlow adicional construído pela estrutura de aprendizado federado para conduzir o loop de treinamento/avaliação de seu modelo (como construir otimizadores, aplicar atualizações de modelo, iterar sobre tf.data.Dataset s e calcular métricas, e aplicando a atualização agregada no servidor, para citar alguns).

  • Uma especificação declarativa da comunicação entre os clientes e um servidor (normalmente várias formas de agregação entre os dispositivos clientes e transmissão do servidor para todos os clientes) e como essa comunicação distribuída é intercalada com a execução cliente-local ou servidor-local do código do TensorFlow.

As computações federadas representadas neste formato serializado são expressas em uma linguagem interna independente de plataforma distinta do Python, mas para usar a API de aprendizado federado, você não precisará se preocupar com os detalhes dessa representação. Os cálculos são representados em seu código Python como objetos do tipo tff.Computation , que na maioria das vezes você pode tratar como s opacos callable Python.

Nos tutoriais, você invocará essas computações federadas como se fossem funções regulares do Python, a serem executadas localmente. No entanto, o TFF é projetado para expressar cálculos federados de maneira agnóstica para a maioria dos aspectos do ambiente de execução, para que possam ser implantados em, por exemplo, grupos de dispositivos executando Android ou clusters em um datacenter. Novamente, a principal consequência disso são fortes suposições sobre a serialização . Em particular, quando você chama um dos métodos build_... descritos abaixo, a computação é totalmente serializada.

Estado de modelagem

O TFF é um ambiente de programação funcional, mas muitos processos de interesse no aprendizado federado são stateful. Por exemplo, um loop de treinamento que envolve várias rodadas de média de modelo federado é um exemplo do que poderíamos classificar como um processo com estado . Nesse processo, o estado que evolui de uma rodada para outra inclui o conjunto de parâmetros do modelo que está sendo treinado e, possivelmente, um estado adicional associado ao otimizador (por exemplo, um vetor de momento).

Como a TFF é funcional, os processos com estado são modelados na TFF como cálculos que aceitam o estado atual como uma entrada e fornecem o estado atualizado como uma saída. Para definir completamente um processo com estado, também é necessário especificar de onde vem o estado inicial (caso contrário, não podemos inicializar o processo). Isso é capturado na definição da classe auxiliar tff.templates.IterativeProcess , com as 2 propriedades initialize e next correspondentes à inicialização e iteração, respectivamente.

Construtores disponíveis

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.