Na última seção, nós aprendemos sobre PointerTensors, que criam a infraestrutura necessária que precisamos para proteção de privacidade em Deep Learning. Nessa seção, nós iremos ver como usar essas ferramentas básicas para implementar nosso primeiro algoritmo de proteção de privacidade em Deep Learning: Federated Learning.
Autores:
Tradução:
É uma simples, porém poderosa maneira de treinar modelos de Deep Learning. Pense em dados de treinamento, são sempre o resultado de algum processo de coleta. As pessoas (via dispositivos) geram dados ao gravar eventos no mundo real. Normalmente, esses dados são agregados em uma simples localização central em que você pode treinar um modelo de aprendizegam de máquina. O Federated Learning vira isso de ponta a cabeça!
Ao invés de trazer dados de treinamento para o modelo (um servidor central), você trás o modelo para os dados de treinamento (onde quer que ele esteja).
A ideia é que isso permita que quem estiver criando os dados possua a única cópia permanente e, assim, mantenha o controle sobre quem já teve acesso a eles. Muito legal, não acha?
Vamos começar treinando um modelo de exemplo da maneira centralizada. Isso é tão simples quanto obter o modelo. Primeiro precisamos:
Obs.: Se para você, a seguinte API ainda não é familar. Visite o fast.ai e faça os seus cursos antes de continuar esse tutorial.
In [ ]:
import torch
from torch import nn
from torch import optim
In [ ]:
# Dataset de exemplo
data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)
target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)
# Modelo simples de exemplo
model = nn.Linear(2,1)
def train():
# Lógica de treinamento
opt = optim.SGD(params=model.parameters(),lr=0.1)
for iter in range(20):
# 1) apague os gradientes anteriores (caso eles existam)
opt.zero_grad()
# 2) faça uma predição
pred = model(data)
# 3) calcule o erro, isto é, o quanto perdemos
loss = ((pred - target)**2).sum()
# 4) descubra quais pesos nos causaram essa perda
loss.backward()
# 5) altere esses pesos
opt.step()
# 6) mostre o progresso até então
print(loss.data)
In [ ]:
train()
E aí está! Nós treinamos um modelo simples da maneira convencional. Todos os nossos dados estão agregados em nossa máquina local e podemos usá-los para fazer atualizações em nosso modelo. O aprendizado federado, no entanto, não funciona dessa maneira. Então, vamos modificar este exemplo para fazê-lo da maneira federada!
Então, o que precisamos:
atualizadar a lógica de treinamento para fazer o aprendizado federado
Novas etapas de treinamento:
In [ ]:
import syft as sy
hook = sy.TorchHook(torch)
In [ ]:
# cria dois nós (ou duas entidades de computação)
bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")
In [ ]:
# Nosso dataset de exemplo
data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)
target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)
# obtenha apontadores para os dados de treinamento de cada worker
# enviando alguns dados de treinamento para bob e alice
data_bob = data[0:2]
target_bob = target[0:2]
data_alice = data[2:]
target_alice = target[2:]
# Inicialize o modelo
model = nn.Linear(2,1)
data_bob = data_bob.send(bob)
data_alice = data_alice.send(alice)
target_bob = target_bob.send(bob)
target_alice = target_alice.send(alice)
# organize os apontadores numa lista
datasets = [(data_bob,target_bob),(data_alice,target_alice)]
opt = optim.SGD(params=model.parameters(),lr=0.1)
In [ ]:
def train():
# Lógica de treinamento
opt = optim.SGD(params=model.parameters(),lr=0.1)
for iter in range(10):
# NOVO) itere através do dataset de cada worker
for data,target in datasets:
# NOVO) envie o modelo para corrigir/atualizar o worker
model.send(data.location)
# 1) apague os gradientes anteriores (caso eles existam)
opt.zero_grad()
# 2) faça uma predição
pred = model(data)
# 3) calcule o erro, isto é, o quanto perdemos
loss = ((pred - target)**2).sum()
# 4) descubra quais pesos nos causaram essa perda
loss.backward()
# 5) atualize os pesos
opt.step()
# NOVO) pegue o modelo (com gradientes)
model.get()
# 6) mostre o progresso até então
print(loss.get()) # NOVO) leve edição... precisa usar o .get() a partir do loss\
# média federada
In [ ]:
train()
E voilà! Agora estamos treinando um modelo muito simples de Deep Learning usando o Federated Learning! Enviamos o modelo para cada worker, geramos um novo gradiente e, em seguida, devolvemos o gradiente ao servidor local, onde atualizamos nosso modelo global. Nunca, neste processo, jamais vemos ou solicitamos acesso aos dados subjacentes ao treinamento! Preservamos a privacidade de Bob e Alice!!!
Embora este exemplo seja uma boa introdução ao Federated Learning, ele ainda apresenta algumas falhas importantes. A mais notável, é que quando chamamos model.get()
e recebemos o modelo atualizado de Bob ou Alice, podemos aprender muito sobre os dados de treinamento de ambos apenas observando seus gradientes. Em alguns casos, podemos restaurar os dados de treinamento de forma completa!
Então o que poderíamos fazer? Bem, a primeira estratégia empregada pelas pessoas é calcular a média do gradiente em vários indivíduos antes de carregá-lo no servidor central. Essa estratégia, no entanto, exigirá um uso mais sofisticado dos objetos PointerTensor. Portanto, na próxima seção, vamos passar um algum tempo aprendendo sobre funcionalidades mais avançada ao utilizar ponteiros e, em seguida, iremos atualizar este exemplo de Federated Learning.
Parabéns por concluir esta etapa do tutorial! Se você gostou e gostaria de se juntar ao movimento em direção à proteção de privacidade, propriedade descentralizada e geração, demanda em cadeia, de dados em IA, você pode fazê-lo das seguintes maneiras!
A maneira mais fácil de ajudar nossa comunidade é adicionando uma estrela nos nossos repositórios! Isso ajuda a aumentar a conscientização sobre essas ferramentas legais que estamos construindo.
A melhor maneira de manter-se atualizado sobre os últimos avanços é se juntar à nossa comunidade! Você pode fazer isso preenchendo o formulário em http://slack.openmined.org
A melhor maneira de contribuir para a nossa comunidade é se tornando um contribuidor do código! A qualquer momento, você pode acessar a página de Issues (problemas) do PySyft no GitHub e filtrar por "Projetos". Isso mostrará todas as etiquetas (tags) na parte superior, com uma visão geral de quais projetos você pode participar! Se você não deseja ingressar em um projeto, mas gostaria de codificar um pouco, também pode procurar mais mini-projetos "independentes" pesquisando problemas no GitHub marcados como "good first issue".
Se você não tem tempo para contribuir com nossa base de códigos, mas ainda deseja nos apoiar, também pode se tornar um Apoiador em nosso Open Collective. Todas as doações vão para hospedagem na web e outras despesas da comunidade, como hackathons e meetups!
In [ ]: