Ter uma questão? Conecte-se com a comunidade no Fórum TensorFlow Visite o Fórum

Aprendizagem Federada

Visão geral

Este documento apresenta interfaces que facilitam tarefas de aprendizado federado, como treinamento federado ou avaliação com modelos de aprendizado de máquina existentes implementados no TensorFlow. Ao projetar essas interfaces, nosso objetivo principal era tornar possível experimentar o 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. A TFF foi projetada com extensibilidade e composibilidade em mente, e aceitamos contribuições; estamos ansiosos para ver o que você criará!

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

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

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

  • Conjuntos de dados . Coleções de dados enlatados que você pode baixar e acessar em Python para uso na simulação de cenários de aprendizagem federados. Embora a aprendizagem federada seja projetada para uso com dados descentralizados que não podem ser simplesmente baixados em um local centralizado, nos estágios de pesquisa e desenvolvimento muitas vezes é conveniente conduzir experimentos iniciais usando dados que podem ser baixados e manipulados localmente, especialmente para desenvolvedores que podem ser novo para a 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 continuar, recomendamos que você primeiro leia os tutoriais sobre classificação de imagens e geração de texto , pois eles apresentam a maioria dos conceitos descritos aqui usando exemplos concretos. Se você estiver interessado em aprender mais sobre como o TFF funciona, pode 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 estudar a implementação existente do Interfaces tff.learning .

Modelos

Suposições arquitetônicas

Serialização

A 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 servidores de banco de dados poderosos, muitos usos importantes que nossa plataforma pretende oferecer envolvem dispositivos móveis e incorporados com recursos limitados. Não podemos presumir que esses dispositivos sejam capazes de hospedar tempos de execução Python; a única coisa que podemos supor neste ponto é que eles são capazes de hospedar um tempo de execução local do TensorFlow. Portanto, uma suposição arquitetônica fundamental que fazemos no TFF é que o código do modelo deve ser serializável como um gráfico do TensorFlow.

Você pode (e deve) ainda desenvolver seu código TF seguindo as práticas recomendadas mais recentes, como usar o modo antecipado. No entanto, o código final deve ser serializável (por exemplo, pode ser empacotado como um tf.function para código de modo tf.function ). Isso garante que qualquer estado Python ou fluxo de controle necessário em 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 de modo ansioso. Portanto, a serialização em TFF atualmente segue o padrão TF 1.0, em que todo o código deve ser construído dentro de um tf.Graph controlado por TFF. Isso significa que atualmente a 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 arg que retorna um tff.learning.Model . 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 fortemente que a maioria dos usuários construa modelos usando Keras, consulte a seção Conversores para Keras abaixo. Esses wrappers tratam da agregação de atualizações de modelo, bem como de quaisquer métricas definidas para o modelo automaticamente. No entanto, ainda pode ser útil entender como a agregação é tratada para um tff.learning.Model geral.

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

  • Agregação local . Este nível de agregação se refere à agregação em vários lotes de exemplos pertencentes a um cliente individual. Ele se aplica tanto aos parâmetros do modelo (variáveis), que continuam a evoluir sequencialmente conforme 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 agregação neste nível é responsabilidade do código do modelo e é realizada com o uso de construções padrão do TensorFlow.

    A estrutura geral de processamento é a seguinte:

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

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

    • Finalmente, a TFF invoca o método report_local_outputs em seu modelo para permitir que seu modelo compile todas as estatísticas de resumo que coletou em um conjunto compacto de métricas a serem exportadas pelo cliente. É aqui que o código do seu 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 . Este nível de agregação se refere à agregação em vários clientes (dispositivos) no sistema. Novamente, isso se aplica aos parâmetros do modelo (variáveis), que estão sendo calculados entre os clientes, bem como às métricas que seu modelo exportou como resultado da agregação local.

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

    A estrutura geral de processamento é a seguinte:

    • O modelo inicial e quaisquer parâmetros necessários para o treinamento são distribuídos por um servidor a 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).

    • A TFF executa um protocolo de agregação distribuída 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 linguagem de computação federada da própria TFF (não no TensorFlow), na federated_output_computation. do modelo federated_output_computation. Consulte o tutorial de algoritmos personalizados para obter mais informações sobre a API de agregação.

Interfaces abstratas

Este construtor básico + interface de metadados é representado pela interface tff.learning.Model , da seguinte maneira:

  • Os métodos constructor, forward_pass e report_local_outputs devem construir variáveis ​​de modelo, passagem direta e estatísticas que você deseja relatar, de forma correspondente. 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. A TFF usa essas informações para determinar como conectar partes de seu modelo aos algoritmos de otimização federados e definir assinaturas de tipo interno para auxiliar na verificação da exatidão do sistema construído (de modo 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.Model expõe uma propriedade federated_output_computation que, junto com a propriedade report_local_outputs mencionada anteriormente, permite controlar o processo de agregação de estatísticas resumidas.

Você pode encontrar exemplos de como definir seu próprio tff.learning.Model personalizado na segunda parte de nosso tutorial de classificação de imagens , 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á contar com tff.learning.from_keras_model para construir um tff.learning.Model .

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

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

Além do próprio modelo, você fornece um lote de amostra de dados que a 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 do cliente (uma vez que assumimos que esses dados não estão geralmente disponíveis no momento em que você está construindo o TensorFlow para ser serializado).

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

Construtores de computação federada

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 : o TFF primeiro compila algoritmos de aprendizagem 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 oferecer 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 só é suportada por meio de uma simulação local (por exemplo, em um notebook usando dados descentralizados simulados).

Um cálculo federado gerado pela API Federated Learning da TFF, como um algoritmo de treinamento que usa a média do modelo federado ou uma avaliação federada, inclui vários elementos, mais notavelmente:

  • Uma forma serializada de seu código de modelo, bem como código TensorFlow adicional construído pela estrutura Federated Learning para conduzir o loop de treinamento / avaliação de seu modelo (como construir otimizadores, aplicar atualizações de modelo, iterar sobretf.data.Dataset s e métricas de computação, 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 do cliente e transmissão do servidor para todos os clientes) e como essa comunicação distribuída é intercalada com a execução local do cliente ou local do servidor do código TensorFlow.

Os cálculos federados representados nesta forma serializada são expressos em uma linguagem interna independente de plataforma distinta do Python, mas para usar a API Federated Learning, você não precisa 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 opacos Python callable .

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

Estado de modelagem

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 cálculo da média do modelo federado é um exemplo do que poderíamos classificar como um processo com estado . Nesse processo, o estado que evolui de rodada para rodada inclui o conjunto de parâmetros do modelo que estão sendo treinados e, possivelmente, o estado adicional associado ao otimizador (por exemplo, um vetor de momentum).

Como o TFF é funcional, os processos com estado são modelados no TFF como cálculos que aceitam o estado atual como uma entrada e, em seguida, fornecem o estado atualizado como uma saída. Para definir totalmente 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 correspondendo à inicialização e iteração, respectivamente.

Construtores disponíveis

No momento, a TFF fornece duas funções de construtor que geram os cálculos federados para treinamento e avaliação federados:

Conjuntos de dados

Suposições arquitetônicas

Seleção de 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 qualquer momento (por exemplo, isso pode ser limitado a clientes que estão conectado a uma fonte de alimentação, não em uma rede medida e ocioso). Geralmente, o conjunto de clientes disponíveis para participar de 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 os cálculos federados, por design, são expressos de uma maneira que não leva em conta o conjunto exato de participantes; todo o 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, é modelada fora da própria computação.

Para simular uma implantação realista de seu código de aprendizado federado, geralmente você escreverá um loop de treinamento semelhante a este:

trainer = tff.learning.build_federated_averaging_process(...)
state = trainer.initialize()
federated_training_data = ...

def sample(federate_data):
  return ...

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

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 otf.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 umtf.data.Dataset que contém os dados de um determinado cliente. Essestf.data.Dataset s podem ser alimentados diretamente como entrada para os cálculos federados gerados no modotf.data.Dataset .

Deve-se notar que a capacidade de acessar identidades de clientes é um recurso que só é fornecido pelos conjuntos de dados para uso em simulações, onde a capacidade de treinar em 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. Depois que os dados de um subconjunto específico de clientes são selecionados como 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 tff.simulation.datasets.ClientData com 2 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.