
嗨,habrozhiteli! 我们最近将这本书交给了Andrew W. Trask,为进一步精通深度学习技术奠定了基础。 它从描述神经网络的基础开始,然后详细研究其他层和体系结构。
我们对“联合学习”这一段落进行了评论
联合学习的思想源于以下事实:难以获得足以教授强大的深度学习模型的大量数据,这些数据包含用于解决问题的有用信息(例如,用于使用MRI诊断肿瘤疾病)。 除了训练模型所需的有用信息外,数据集还包含与当前任务无关的其他信息,但向某人透露这些信息可能有害。
联合学习是一种用于在安全环境中封闭模型并在不移动数据的情况下进行教学的技术。 考虑一个例子。
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:
学习检测垃圾邮件。
假设我们需要训练一个模型来从人们的电子邮件中检测垃圾邮件在这种情况下,我们正在谈论电子邮件分类。 我们将在名为Enron的公共数据集上训练我们的第一个模型。 这是在安然听证会期间发布的大量电子邮件(现在是标准的电子邮件分析机构)。 一个有趣的事实:我熟悉一些人,根据他们的活动性质,他们必须阅读/评论此数据集,并且他们注意到人们在这些信中互相发送了各种信息(通常是非常个人的信息)。 但是由于该军团在审判期间公开,因此现在可以不受限制地使用。
上一节和本节中的代码仅实现准备操作。 输入文件(ham.txt和spam.txt)可在该书的网页:
www.manning.com/books/grokking-deep-learning和GitHub存储库中找到:
github.com/iamtrask/Grokking-Deep-Learning 。 我们需要对其进行预处理,以便准备将其从第13章转移到Embedding类,在第13章中,我们创建了深度学习框架。 和以前一样,该语料库中的所有单词都将转换为索引列表。 另外,我们将所有字母的长度都限制为500个单词,或者修剪它们或添加标记。 因此,我们得到了一个矩形数据集。
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()
定义了辅助函数train()和test()之后,我们可以初始化神经网络并通过编写几行代码来对其进行训练。 经过三轮迭代,网络能够以99.45%的准确度对控制数据集进行分类(控制数据集具有很好的平衡性,因此该结果可以认为是出色的):
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
让我们将模型设为联邦
上面,完成了最常见的深度学习。 现在增加隐私在上一节中,我们实现了一个电子邮件分析示例。 现在,将所有电子邮件放在一个位置。 这是一种很好的旧工作方法(至今仍在世界范围内广泛使用)。 首先,我们将模仿联邦教育的环境,其中有几种不同的字母集合:
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:])
没什么复杂的。 现在,我们可以执行与以前相同的训练过程,但是已经对三个单独的数据集进行了训练。 每次迭代之后,我们将平均Bob,Alice和Sue模型中的值,并评估结果。 请注意,一些联合学习方法涉及在每个软件包(或软件包集合)之后进行合并; 我决定使代码尽可能简单:
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")
以下是结果片段。 这种模型的准确性几乎达到了与先前模型相同的水平,并且从理论上讲,我们无法访问训练数据-是吗? 无论如何,但是每个人都会在学习过程中改变模型,对吗? 我们真的不能从他们的数据集中得到任何东西吗?
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
破解联邦模型
让我们看一下如何从训练数据集中提取信息的简单示例。当每个人只有少数培训示例时,联合学习会遇到两个大问题,尤其是难以解决的问题:速度和保密性。 事实证明,如果某人只有几个训练示例(或者仅通过几个例子对发送给您的模型进行了训练:一个训练包),您仍然可以学到很多有关源数据的知识。 如果您想象自己有10,000人(每个人的数据量都很小),那么您将花费大部分时间来回发送模型,而无需花费太多的培训(尤其是模型很大的时候)。
但是,让我们不要超越自己。 让我们看看在用户更新一个包装上的重量后您可以找到什么:
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)
鲍勃通过收件箱中的电子邮件创建和训练模型。 但是碰巧的是,他通过给自己发送一封信来保存密码,该信上写着:“我的计算机密码是披萨。” 天真鲍勃! 在查看了哪些权重发生了变化之后,我们可以找出鲍勃字母的字典(并理解其含义):
for i, v in enumerate(bobs_model.weight.data - model.weight.data): if(v != 0): print(vocab[i])
用这种简单的方法,我们找出了鲍勃的绝密密码(可能还有他的烹饪偏好)。 怎么办? 如果很容易找出导致重量变化的训练数据,如何信任联合学习?
is pizza computer password my
»这本书的更多信息可以
在出版商的网站上找到»
目录»
摘录优惠券上的Habrozhiteli预购书有30%的折扣
-Grokking Deep Learning