
Oi, habrozhiteli! Recentemente, entregamos o livro a Andrew W. Trask, estabelecendo as bases para o domínio adicional da tecnologia de aprendizado profundo. Começa com uma descrição dos conceitos básicos de redes neurais e, em seguida, examina detalhadamente camadas e arquiteturas adicionais.
Oferecemos uma revisão da passagem "Aprendizado Federado"
A idéia de aprendizado federado nasceu do fato de que muitos dados que contêm informações úteis para resolver problemas (por exemplo, para o diagnóstico de câncer por ressonância magnética) são difíceis de obter em quantidades suficientes para ensinar um poderoso modelo de aprendizado profundo. Além das informações úteis necessárias para o treinamento do modelo, os conjuntos de dados também contêm outras informações que não são relevantes para a tarefa em questão, mas divulgá-las a alguém pode ser potencialmente prejudicial.
O aprendizado federado é uma técnica para incluir um modelo em um ambiente seguro e ensiná-lo sem mover dados para qualquer lugar. Considere um exemplo.
import numpy as np from collections import Counter import random import sys import codecsnp.random.seed(12345) with codecs.open('spam.txt',"r",encoding='utf-8',errors='ignore') as f: ← http:
Aprendendo a detectar spam.
Digamos que precisamos treinar um modelo para detectar spam nos emails das pessoasNesse caso, estamos falando sobre classificação de email. Treinaremos nosso primeiro modelo em um conjunto de dados público chamado Enron. Esse é um enorme corpo de e-mails publicados durante as audiências da Enron (agora um corpo analítico de e-mail padrão). Um fato interessante: eu conhecia pessoas que, pela natureza de suas atividades, tinham que ler / comentar sobre esse conjunto de dados e observam que as pessoas enviaram umas às outras nessas cartas uma variedade de informações (geralmente muito pessoais). Porém, como esse corpo foi tornado público durante o julgamento, agora pode ser usado sem restrições.
O código na seção anterior e nesta seção implementa apenas operações preparatórias. Os arquivos de entrada (ham.txt e spam.txt) estão disponíveis na página da Web do livro:
www.manning.com/books/grokking-deep-learning e no repositório GitHub:
github.com/iamtrask/Grokking-Deep-Learning . Precisamos pré-processá-lo para prepará-lo para a transferência para a aula de incorporação do capítulo 13, onde criamos nossa estrutura de aprendizado profundo. Como antes, todas as palavras deste corpus são convertidas em listas de índices. Além disso, trazemos todas as letras para o mesmo comprimento de 500 palavras, aparando-as ou adicionando tokens. Graças a isso, obtemos um conjunto de dados retangular.
spam_idx = to_indices(spam) ham_idx = to_indices(ham) train_spam_idx = spam_idx[0:-1000] train_ham_idx = ham_idx[0:-1000] test_spam_idx = spam_idx[-1000:] test_ham_idx = ham_idx[-1000:] train_data = list() train_target = list() test_data = list() test_target = list() for i in range(max(len(train_spam_idx),len(train_ham_idx))): train_data.append(train_spam_idx[i%len(train_spam_idx)]) train_target.append([1]) train_data.append(train_ham_idx[i%len(train_ham_idx)]) train_target.append([0]) for i in range(max(len(test_spam_idx),len(test_ham_idx))): test_data.append(test_spam_idx[i%len(test_spam_idx)]) test_target.append([1]) test_data.append(test_ham_idx[i%len(test_ham_idx)]) test_target.append([0]) def train(model, input_data, target_data, batch_size=500, iterations=5): n_batches = int(len(input_data) / batch_size) for iter in range(iterations): iter_loss = 0 for b_i in range(n_batches): # model.weight.data[w2i['<unk>']] *= 0 input = Tensor(input_data[b_i*bs:(b_i+1)*bs], autograd=True) target = Tensor(target_data[b_i*bs:(b_i+1)*bs], autograd=True) pred = model.forward(input).sum(1).sigmoid() loss = criterion.forward(pred,target) loss.backward() optim.step() iter_loss += loss.data[0] / bs sys.stdout.write("\r\tLoss:" + str(iter_loss / (b_i+1))) print() return model def test(model, test_input, test_output): model.weight.data[w2i['<unk>']] *= 0 input = Tensor(test_input, autograd=True) target = Tensor(test_output, autograd=True) pred = model.forward(input).sum(1).sigmoid() return ((pred.data > 0.5) == target.data).mean()
Tendo definido as funções auxiliares train () e test (), podemos inicializar a rede neural e treiná-la escrevendo apenas algumas linhas de código. Após três iterações, a rede é capaz de classificar o conjunto de dados de controle com uma precisão de 99,45% (o conjunto de dados de controle é bem equilibrado, portanto, este resultado pode ser considerado excelente):
model = Embedding(vocab_size=len(vocab), dim=1) model.weight.data *= 0 criterion = MSELoss() optim = SGD(parameters=model.get_parameters(), alpha=0.01) for i in range(3): model = train(model, train_data, train_target, iterations=1) print("% Correct on Test Set: " + \ str(test(model, test_data, test_target)*100)) ______________________________________________________________________________ Loss:0.037140416860871446 % Correct on Test Set: 98.65 Loss:0.011258669226059114 % Correct on Test Set: 99.15 Loss:0.008068268387986223 % Correct on Test Set: 99.45
Vamos fazer o modelo federal
Acima, o aprendizado profundo mais comum foi realizado. Agora adicione privacidadeNa seção anterior, implementamos um exemplo de análise de email. Agora coloque todos os emails em um só lugar. Este é um bom método de trabalho antigo (que ainda é amplamente utilizado em todo o mundo). Para começar, imitaremos o ambiente da educação federal, no qual existem várias coleções diferentes de cartas:
bob = (train_data[0:1000], train_target[0:1000]) alice = (train_data[1000:2000], train_target[1000:2000]) sue = (train_data[2000:], train_target[2000:])
Nada complicado ainda. Agora podemos executar o mesmo procedimento de treinamento de antes, mas já em três conjuntos de dados separados. Após cada iteração, calcularemos a média dos valores nos modelos de Bob, Alice e Sue e avaliaremos os resultados. Observe que alguns métodos de aprendizado federado envolvem a combinação após cada pacote (ou coleção de pacotes); Decidi manter o código o mais simples possível:
for i in range(3): print("Starting Training Round...") print("\tStep 1: send the model to Bob") bob_model = train(copy.deepcopy(model), bob[0], bob[1], iterations=1) print("\n\tStep 2: send the model to Alice") alice_model = train(copy.deepcopy(model), alice[0], alice[1], iterations=1) print("\n\tStep 3: Send the model to Sue") sue_model = train(copy.deepcopy(model), sue[0], sue[1], iterations=1) print("\n\tAverage Everyone's New Models") model.weight.data = (bob_model.weight.data + \ alice_model.weight.data + \ sue_model.weight.data)/3 print("\t% Correct on Test Set: " + \ str(test(model, test_data, test_target)*100)) print("\nRepeat!!\n")
Abaixo está um trecho com os resultados. Esse modelo atingiu quase o mesmo nível de precisão que o anterior e, teoricamente, não tínhamos acesso aos dados de treinamento - ou não? Enfim, mas toda pessoa muda o modelo no processo de aprendizagem, certo? Não podemos realmente tirar algo de seus conjuntos de dados?
Starting Training Round... Step 1: send the model to Bob Loss:0.21908166249699718 ...... Step 3: Send the model to Sue Loss:0.015368461608470256 Average Everyone's New Models % Correct on Test Set: 98.8
Hackear um modelo federado
Vejamos um exemplo simples de como extrair informações de um conjunto de dados de treinamento.O aprendizado federado sofre de dois grandes problemas, especialmente difíceis de resolver, quando cada pessoa tem apenas alguns exemplos de treinamento - velocidade e confidencialidade. Acontece que, se alguém tiver apenas alguns exemplos de treinamento (ou o modelo enviado a você foi treinado com apenas alguns exemplos: um pacote de treinamento), você ainda poderá aprender muito sobre os dados de origem. Se você imagina ter 10.000 pessoas (e todo mundo tem uma quantidade muito pequena de dados), passará a maior parte do tempo enviando o modelo para frente e para trás e sem muito treinamento (especialmente se o modelo for muito grande).
Mas não vamos nos antecipar. Vamos ver o que você pode descobrir depois que o usuário atualiza os pesos em um pacote:
import copy bobs_email = ["my", "computer", "password", "is", "pizza"] bob_input = np.array([[w2i[x] for x in bobs_email]]) bob_target = np.array([[0]]) model = Embedding(vocab_size=len(vocab), dim=1) model.weight.data *= 0 bobs_model = train(copy.deepcopy(model), bob_input, bob_target, iterations=1, batch_size=1)
Bob cria e treina o modelo por email em sua caixa de entrada. Mas aconteceu que ele salvou sua senha enviando uma carta para si mesmo com o texto: "A senha do meu computador é pizza". Bob ingênuo! Depois de ver quais pesos foram alterados, podemos descobrir o dicionário (e entender o significado) da carta de Bob:
for i, v in enumerate(bobs_model.weight.data - model.weight.data): if(v != 0): print(vocab[i])
De uma maneira tão simples, descobrimos a senha ultrassecreta de Bob (e possivelmente suas preferências culinárias). E o que fazer? Como confiar no aprendizado federado, se é tão fácil descobrir quais dados de treinamento causaram a alteração nos pesos?
is pizza computer password my
»Mais informações sobre o livro podem ser encontradas no
site do editor»
Conteúdo»
Trecho30% de desconto nos livros de pré-venda da Habrozhiteli em um cupom -
Grokking Deep Learning