Path: blob/master/site/pt-br/federated/tutorials/random_noise_generation.ipynb
25118 views
Copyright 2021 The TensorFlow Federated Authors.
Geração de ruído aleatório no TFF
Este tutorial discute as práticas recomendadas para geração de ruído aleatório no TFF. A geração de ruído aleatório é um componente importante de diversas técnicas de proteção de privacidade em algoritmos de aprendizado federado, como a privacidade diferencial.
Antes de começarmos
Primeiro, vamos garantir que o notebook esteja conectado a um back-end que tenha os componentes relevantes compilados.
Execute o exemplo "Olá, mundo" abaixo para garantir que o ambiente do TFF esteja configurado corretamente. Se não funcionar, consulte as instruções no guia de instalação.
Ruído aleatório nos clientes
Em geral, há dois casos de necessidade de ruído em clientes: ruído idêntico e ruído independente e identicamente distribuído.
Para ruído idêntico, o padrão recomendado é manter uma semente no servidor, enviá-la aos clientes e usar funções
tf.random.stateless
para gerar ruído.Para ruído independente e identicamente distribuído, use um tf.random.Generator iniciado no cliente com from_non_deterministic_state, de acordo com a recomendação do TF para evitar as funções de tf.random.
O comportamento do cliente é diferente do comportamento do servidor (ele não sofre das desvantagens discutidas mais adiante), pois cada cliente construirá seu próprio grafo de computações e inicializará sua própria semente padrão.
Ruído idêntico nos clientes
Ruído independente nos clientes
Inicializador do modelo nos clientes
Ruído aleatório no servidor
Não é recomendado usar diretamente tf.random.normal
As APIs do TF1.x tf.random.normal
para geração de ruído aleatório são fortemente desencorajadas no TF2 de acordo com o tutorial de geração de ruído aleatório no TF. Pode ocorrer um comportamento surpreendente quando essas APIs são usadas em conjunto com tf.function
e tf.random.set_seed
. Por exemplo: o código abaixo gerará o mesmo valor em cada chamada. Esse comportamento surpreendente é esperado pelo TF, e a explicação está disponível na documentação de tf.random.set_seed
.
No TFF, as coisas são um pouco diferentes. Se encapsularmos a geração de ruído como tff.tf_computation
em vez de tf.function
, será gerado ruído aleatório não determinístico. Porém, se executarmos esse trecho de código diversas vezes, será gerado um conjunto diferente de (n1, n2)
a cada vez. Não existe uma maneira fácil de definir uma semente aleatória global para o TFF.
Além disso, é possível gerar ruído determinístico no TFF sem definir explicitamente uma semente. A função return_two_noise
no trecho de código abaixo retorna dois valores de ruído idênticos. Esse é o comportamento esperado, pois o TFF construirá o grafo de computações antecipadamente, antes da execução. Porém, isso indica que os usuários precisam prestar atenção ao uso de tf.random.normal
no TFF.
Use com cuidado: tf.random.Generator
Podemos usar tf.random.Generator
conforme sugerido no tutorial do TF.
Entretanto, os usuários precisam ter cuidado com o uso.
tf.random.Generator
usatf.Variable
para manter os estados dos algoritmos de RNG. No TFF, é recomendável construir o gerador dentro de umatff.tf_computation
, e é difícil passar o gerador e seu estado entre funções detff.tf_computation
.O trecho de código anterior também depende da definição cuidadosa de sementes nos geradores. Podemos obter resultados esperados, mas surpreendentes (
n1==n2
determinístico) se usarmostf.random.Generator.from_non_deterministic_state()
no lugar.
De forma geral, o TFF prefere operações funcionais, e demonstraremos o uso de funções tf.random.stateless_*
nas próximas seções.
No TFF para aprendizado federado, costumamos trabalhar com estruturas aninhadas em vez de escalares, e o trecho de código anterior pode ser estendido naturalmente para estruturas aninhadas.
Uso recomendado: tf.random.stateless_*
com um helper
Uma recomendação geral no TFF é usar as funções tf.random.stateless_*
funcionais para gerar ruído aleatório. Essas funções recebem seed
(um Tensor com formato [2]
ou uma tuple
de dois tensores escalares) como um argumento de entrada explícito para gerar ruído aleatório. Primeiro, definimos uma classe helper para manter a semente como pseudoestado. O helper RandomSeedGenerator
tem operadores funcionais de última geração. É razoável usar um contador como pseudoestado para tf.random.stateless_*
, pois essas funções embaralham a semente antes de usá-la para fazer ruídos gerados por sementes correlacionadas serem estatisticamente não correlacionados.
Agora, vamos usar a classe helper e tf.random.stateless_normal
para gerar ruído aleatório no TFF (uma estrutura aninhada de ruídos aleatórios). O seguinte trecho de código parece muito com um processo iterativo do TFF (confira um exemplo de como expressar um algoritmo de aprendizado federado como processo iterativo do TFF em simple_fedavg). Aqui, o pseudoestado da semente para geração de ruído aleatório é tf.Tensor
, que pode ser facilmente transformado para funções do TFF e TF.