《基于Numpy实现同态加密神经网络.doc》由会员分享,可在线阅读,更多相关《基于Numpy实现同态加密神经网络.doc(14页珍藏版)》请在三一文库上搜索。
1、基于Numpy实现同态加密神经网络在分布式AI环境下,同态加密神经网络有助于保护商业公司知识产权和消费者隐私。让我们和DeepMind数据科学家、Udacity深度学习导师Andrew Trask一起,来看看如何基于Numpy实现同态加密神经网络吧。TLDR:在这篇文章中,我们将训练一个在训练阶段完全加密的神经网络(在未加密的数据上训练)。得到的神经网络将具备两个有益的性质。首先,保护神经网络的智能免遭窃取,使有价值的AI可以在不安全的环境中加以训练而不用冒智能遭窃的风险。其次,网络只能进行加密预测(大概对外部世界毫无影响,因为在没有密钥的情况下,外部世界无法理解预测)。这在用户和超智能间构成
2、了一个有价值的权力失衡。如果AI是同态加密的,那么在AI看来,整个外部世界也是同态加密的。一个控制密钥的人类可以选择解锁AI本身(将AI释放到世界中)或仅仅解密AI做出的单个预测(看起来更安全)。超智能很多人都担忧超智能有一天会选择伤害人类。史蒂芬霍金曾呼吁建立新的世界政府来管理我们赋予人工智能的能力,以防人工智能最终摧毁人类。这些是相当大胆的主张,我认为它们反映了科学界和整个世界对这一问题的普遍担忧。本文将是一篇介绍解决这一问题的潜在技术方案的教程,我将通过一些玩具样例代码来演示这一方法。目标很简单。我们想要创建未来会变得非常智能的AI技术(智能到可以解决治愈癌症、终结世界上的饥饿等问题),
3、但是这样的智能受人类的控制(基于密钥),因而其智能的应用是受限的。不受限的学习是很棒的,但知识的不受限的应用可能具有潜在危险性。为了介绍这一想法,让我先简要介绍两个非常激动人心的研究领域:深度学习和同态加密。一、什么是深度学习?深度学习是用于自动化智能的工具套件,主要基于神经网络。这一计算机科学的领域,是最近AI技术爆发的主要动力,因为深度学习在许多智能任务上超越了先前的表现记录。例如,他是DeepMind的AlphaGo系统的主要组成部分。神经网络基于输入做出预测。它通过试错法学习做出有效的预测。刚开始,它做出一个预测(起初基本上是随机预测),接着接收一个“错误信号”,该信号表明它的预测过高
4、或过低(通常是概率)。在这一周期重复数百万次后,网络开始搞明白情况。想要了解更多神经网络如何工作的细节,请参考基于Numpy实现神经网络:反向传播一文。这里最神奇的是错误信号。如果不告知预测的表现有多好,神经网络无法学习。牢记这一点。二、什么是同态加密?顾名思义,同态加密是一种加密的形式。在不对称情形下,它可以接受完全可读的文本,然后基于“公钥”将其转变为乱码。更重要的是,它可以基于“私钥”将乱码转回同样的文本。然而,除非你有“私钥”,(理论上)你无法解码加密后的乱码。同态加密是一种特殊形式的加密。它允许某人在无法阅读信息的前提下以特定的方式修改加密信息。例如,同态加密可以应用于数字上,让加密
5、过的数字可以进行乘法和加法运算而无需解密数字。下面是一些玩具样例。现在出现了越来越多的同态加密方案,各有不同的性质。这是一个相对年轻的领域,仍有一些明显的问题有待解决,不过我们将这些内容留待以后讨论。就目前而言,让我们从整数公钥加密方案开始。整数公钥加密方案是一种乘法和加法上的同态加密,允许进行上图的操作。不仅如此,由于公钥允许“单向”加密,你甚至可以进行未加密数字和加密数字间的运算(通过单向加密),上图的2 * Cypher A就是一个例子。(某些加密方案甚至不要求这一点不过同样我们以后讨论这个。)三、我们可以结合这两者吗?也许深度学习和同态加密之间最频繁的互动体现在数据隐私上。当你同态加密
6、数据时,你无法读取数据但仍然可以保持大多数有趣的统计学结构。这让人们得以在加密数据上训练模型(CryptoNets)。甚至有一家名为Numer.ai的初创对冲基金加密昂贵的专有数据,允许任何人尝试训练机器学习模型预测股票市场。通常这不可能办到,因为会导致放弃极为昂贵的信息(不可能基于通常的加密数据训练模型)。然而,本文将反其道而行,加密神经网络,然后在解密信息上加以训练。复杂度惊人的神经网络,事实上可以划分成很少(少得惊人)几种组件,这些组件不断重复以构成神经网络。其实,仅仅基于如下操作,就可以创建很多最先进的神经网络:加法乘法除法减法SigmoidTanh指数函数那么,让我们提出这一明显的技
7、术问题,我们能否同态加密神经网络本身?我们会想这么做吗?结果发现,基于一些保守的逼近,这是可以办到的。加法 开箱即用乘法 开箱即用除法 开箱即用?只是乘法的倒数加法 开箱即用?只是加上负数Sigmoid 嗯也许有点难度Tanh 嗯也许有点难度指数函数 嗯也许有点难度看起来实现除法和减法会是相当微不足道的事情,但那些更复杂的函数就好吧比简单的加法和乘法更复杂。为了尝试同态加密一个深度神经网络,我们还需要一个秘密原料。四、泰勒级数展开也许你在小学学过,泰勒级数允许我们使用无限项加法、减法、乘法、除法来计算一个复杂(非线性)函数。这很完美!(除了无限部分)。幸运的是,如果你早早地停止了计算精确的泰勒
8、级数展开,你仍然能得到手头的函数的一个逼近值。下面是通过泰勒级数逼近一些流行函数的例子(来源)。等下!这里有指数!别担心。指数不过是反复相乘。下面是使用泰勒级数逼近sigmoid函数的python实现(相关公式见Wolfram Alpha)。我们将选取级数的开始几项,看看能逼近到什么程度。import numpy as npdef sigmoid_exact(x):return1 / (1 + np.exp(-x)# 使用泰勒级数def sigmoid_approximation(x):return (1 / 2) + (x / 4) - (x*3 / 48) + (x*5 / 480)for
9、 lil_number in 0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0:print(n输入: + str(lil_number)print(精确的Sigmoid值: + str(sigmoid_exact(lil_number)print(逼近Sigmoid: + str(sigmoid_approximation(lil_number)结果:输入:0.1精确的Sigmoid值:0.52497918747894逼近Sigmoid:0.5249791874999999输入:0.2精确的Sigmoid值:0.549833997312478逼近Sigmoid:0
10、.549834输入:0.3精确的Sigmoid值:0.574442516811659逼近Sigmoid:0.5744425624999999输入:0.4精确的Sigmoid值:0.598687660112452逼近Sigmoid:0.598688输入:0.5精确的Sigmoid值:0.6224593312018546逼近Sigmoid:0.6224609375000001输入:0.6精确的Sigmoid值:0.6456563062257954逼近Sigmoid:0.6456620000000001输入:0.7精确的Sigmoid值:0.6681877721681662逼近Sigmoid:0.6
11、682043125000001输入:0.8精确的Sigmoid值:0.6899744811276125逼近Sigmoid:0.690016输入:0.9精确的Sigmoid值:0.7109495026250039逼近Sigmoid:0.7110426875输入:1.0精确的Sigmoid值:0.7310585786300049逼近Sigmoid:0.73125仅仅使用了泰勒级数的前4项,我们已经相当逼近sigmoid函数了。既然我们已经具备了通用的策略,是时候选择一个同态加密算法了。五、选择加密算法同态加密是一个相对较新的领域,其中的主要里程碑是Craig Gentry在2009年发现的第一个全
12、同态加密算法。这一里程碑为许多后来者建立了据点。大部分关于同态加密的激动人心的研究围绕开发图灵完备的同态加密计算机展开。因此,对全同态加密方案的需求让人们试图找到一个算法,使得进行任意计算所需的多种逻辑门都可以通这一算法高效而安全地计算。大体的希望是人们能够安全地将工作放到云端,而不必冒发送到云端的数据被发送者以外的人读取的风险。这是一个非常酷的想法,也取得了很多进展。然而,这一角度存在一些缺陷。一般而言,相比普通电脑,大多数全同态加密方案慢得让人怀疑人生(目前还不实用)。这鼓舞了一系列有趣的研究,将操作种类限制为某种程度上同态,这样至少可以进行某些操作。不那么灵活,但是更快,这是常见的计算上
13、的折衷。这是我们想要开始查看的地方。理论上,我们想要一个操作浮点数的同态加密方案(不过很快我们将看到,最终我们选择了操作整数的方案),而不是操作二进制值的方案。二进制可以工作,但它不仅要求全同态加密的灵活性(以性能为代价),还要求我们管理二进制表示和我们想要计算的数学运算之间的逻辑。一个不那么强大,为浮点运算定制的HE(HE为同态加密Homomorphic Encryption的缩写)算法会更合适。尽管加上了这一限制,仍有非常多的选择。下面是一些具备我们需要的特性的流行算法:Efficient Homomorphic Encryption on Integer Vectors and Its
14、Applications(基于整数向量的高效同态加密及其应用)Yet Another Somewhat Homomorphic Encryption (YASHE)(又一个某种程度上的同态加密)Somewhat Practical Fully Homomorphic Encryption (FV)(某种程度上实用的全同态加密)Fully Homomorphic Encryption without Bootstrapping(非自举的全同态加密)最佳的选择可能是YASHE或FV。YASHE是流行的CryptoNet使用的算法,对浮点运算的支持很棒。然而,它相当复杂。为了让这篇文章容易阅读、便于
15、尝试,我们将选择稍微不那么高级(可能也不那么安全)的Efficient Integer Vector Homomorphic Encryption(高效整数向量同态加密)。然而,我认为非常值得指出的是,在你阅读本文的时候,更多新的HE算法正在开发之中,同时本文展示的想法通用于任何在整数或浮点数的加法和乘法上同态加密的方案。甚至说,我的愿望是引起对HE的这一应用的关注,以便更多的为深度学习优化的HE算法能被开发出来。Yu、Lai、Paylor的论文Efficient Integer Vector Homomorphic Encryption详细描述了这一算法,相应的实现可以在GitHub上获取(
16、jamespayor/vector-homomorphic-encryption)。主要部分在C+文件vhe.cpp中。下面我们引导读者阅读代码的一个python移植,说明代码是干什么的。如果你选择实现一个更高级的方案,这也会很有帮助,因为有一些主题相对而言是通用的(一般函数名,变量名,等等)。六、Python中的同态加密首先是一些同态加密术语:明文(plaintext)未加密数据。也叫“消息”。在我们的例子中,这将是一些表示神经网络的数字。密文(cyphertext)加密数据。我们将在密文之上进行数学运算,这些运算会改变底层的明文。公钥(public key)伪随机数字序列,让任何人得以加密
17、数据。可以和别人分享,因为(理论上)公钥只能用于加密。私钥/密钥(private/secret key)伪随机数字序列,让你解密被公钥加密的数据。你不想和别人分享私钥。否则,别人可以解密你的消息。对应的变量名(不同的同态加密技术都倾向于使用这些标准变量名):S表示密钥/私钥的矩阵。用于解密。M公钥。用于加密和进行数学运算。在有些算法中,不是所有数学运算都需要公钥。但这一算法非常广泛地使用公钥。c加密数据向量,密文。x消息,即明文。有些论文使用m作明文的变量名。w单个“加权(weighting)”标量变量,用于重加权输入消息x(让它一致地更长或更短)。这一变量用于调节信噪比。加强信号后,对于给定
18、的操作而言,消息较不容易受噪声影响。然而,过于加强信号,会增加完全毁坏数据的概率。这是一个平衡。E或e一般指随机噪声。在某些情形下,指用公钥加密数据前添加的噪声。一般而言,噪声使解密更困难。噪声使同一消息的两次加密可以不一样,在让消息难以破解方面,这很重要。注意,取决于算法和实现,这可能是一个向量,也可能是一个矩阵。在其他情形下,指随操作积累的噪声,详见后文。和许多数学论文的惯用法一样,大写字母对应矩阵,小写字母对应向量,斜体小写对应标量。我们关注同态加密的四种操作:公私钥对生成,单向加密,解密,数学运算。让我们从解密开始。左边的公式描述了密钥S和消息x的一般关系。右边的公式显示了如何使用密钥
19、解密消息。不知道你注意到没有,右边的公式并不包含e。基本上,同态加密技术一般引入足够多的噪声使没有密钥的情况下难以破解出原始消息,但是引入的噪声的量又足够少,当你确实具有密钥时噪声可以通过取整忽略。右边的公式中的框表示“取整到最接近的整数”。其他同态加密算法使用不同的取整。模数运算几乎普遍存在。而加密则生成使上述关系为真的c. 如果S是一个随机矩阵,那么c很难解密。一个简单的、非对称的生成加密钥的方式是找到密钥的逆矩阵。让我们看下相应的Python代码。import numpy as npdef generate_key(w,m,n):S = (np.random.rand(m,n) * w
20、/ (2 * 16) # 可证明 max(S) 注意,我们可以对密文进行一些基本的运算,这些运算改动了相应的明文。很优雅,不是吗?七、优化加密重要一课:回顾一下之前的公式。如果密钥S是一个单位矩阵,那么c不过是输入x的一个重加权的、略带噪声的版本。如果你不明白上面的话,请Google“单位矩阵教程”。限于篇幅,这里就不详细介绍单位矩阵了。这引导我们思考加密是如何进行的。论文作者没有显式地分配一对独立的“公钥”和“私钥”,相反,提出了一种“钥交换”技术,将私钥S替换为S。更具体地,这一私钥交换技术涉及生成一个可以进行该变换的矩阵M。由于M具备将消息从未加密状态(单位矩阵密钥)转换为加密状态(随机
21、而难以猜测的密钥),这个M矩阵正好可以用作我们的公钥!上面一段话包含许多信息,我们也许讲得太快了。让我们重新概括一下。发生了什么基于上面两个公式,如果密钥是一个单位矩阵,那么消息是未加密的。基于上面两个公式,如果密钥是一个随机矩阵,那么消息是加密的。我们构造一个矩阵M将一个密钥转换为另一个私钥。当矩阵M将单位矩阵转换为一个随机密钥时,根据定义,它使用单向加密方式加密了消息。由于M充当了“单向加密”的角色,我们称它为“公钥”,并且可以像公钥一样分发它,因为它无法用于解密。好了,不多拖延了,让我们看下这一切是如何通过Python实现的。import numpy as npdef generate_
22、key(w,m,n):S = (np.random.rand(m,n) * w / (2 * 16) # 可证明 max(S) via_switch(x,w,m,n,T):c,S = switch_key(x*w,np.eye(m),m,n,T)return c,Sx = np.array(0,1,2,5)m = len(x)n = mw = 16S = generate_key(w,m,n)上面的代码的基本思路是让S大体上是单位矩阵,然后在其之上连接一个随机向量T。因此T具备所有密钥所需的信息,不过我们仍然需要构建一个尺寸为S的矩阵使得一切可以工作。八、创建一个XOR神经网络既然我们已经知道
23、如何加密和解密消息(以及进行基本的加法和乘法计算),是时候尝试扩展剩余的运算,以便构建一个简单的XOR神经网络。尽管从技术上说,神经网络不过是一系列非常简单的操作,我们还是需要一些操作的组合以实现便利的功能。下面我将描述我们需要的每项操作,以及在一个较高的抽象层次上,我们是如何实现这些操作的(基本上是我们将使用的加法和乘法的序列)。接着我会向你展示代码。关于一些细节,请参考前面提到的论文。浮点数我们将简单地scale浮点数到整数。我们将在整数上训练我们的网络(把整数当成浮点数)。比如,假设scale=1000,0.2 * 0.5 = 0.1就是200 * 500 = 100000。还原时,10
24、0000 / (1000 * 1000) = 0.1(因为我们使用了乘法,所以需要除以1000的平方)。初看起来这很有技巧性,但你会适应的。由于我们使用的HE方案取整到最接近的整数,这也让我们得以控制神经网络的精度。向量矩阵乘法这是我们的黄油面包(最基本的操作)。事实上,转换密钥的矩阵M是一种线性变换的方式。内积在合适的背景下,上述线性变换可能是内积。sigmoid由于我们可以进行向量矩阵乘法运算,基于足够的乘法,我们可以演算任意多项式的值。因为我们已经知道了对应sigmoid的泰勒级数多项式,我们可以演算sigmoid的逼近值!逐元素矩阵乘法这一操作惊人地低效。我们需要进行向量矩阵乘法或一系
25、列内积运算。外积我们可以通过掩码和内积完成这一运算。声明一下,可能存在完成这些运算的更高效的方法,但我不想冒打破同态加密方案完整性的风险。所以某种程度上我是通过论文中提供的函数来反推如何完成上述运算的(除了算法容许的sigmoid扩展)。现在,让我们看看完成这些的Python代码:def sigmoid(layer_2_c):out_rows = list()for position in range(len(layer_2_c)-1):M_position = M_onehotlen(layer_2_c)-20layer_2_index_c = innerProd(layer_2_c,v_o
26、nehotlen(layer_2_c)-2position,M_position,l) / scaling_factorx = layer_2_index_cx2 = innerProd(x,x,M_position,l) / scaling_factorx3 = innerProd(x,x2,M_position,l) / scaling_factorx5 = innerProd(x3,x2,M_position,l) / scaling_factorx7 = innerProd(x5,x2,M_position,l) / scaling_factorxs = copy.deepcopy(v
27、_onehot50)xs1 = x0xs2 = x20xs3 = x30xs4 = x50xs5 = x70out = mat_mul_forward(xs,H_sigmoid0:1,scaling_factor)out_rows.append(out)return transpose(out_rows)0def load_linear_transformation(syn0_text,scaling_factor = 1000):syn0_text *= scaling_factorreturn linearTransformClient(syn0_text.T,getSecretKey(T
28、_keyslen(syn0_text)-1),T_keyslen(syn0_text)-1,l)def outer_product(x,y):flip = Falseif(len(x) = 50):pos_neg_ratio = positive_countsterm / float(negative_countsterm+1)pos_neg_ratiosterm = pos_neg_ratiofor word,ratio in pos_neg_ratios.most_common():if(ratio 1):pos_neg_ratiosword = np.log(ratio)else:pos
29、_neg_ratiosword = -np.log(1 / (ratio + 0.01)review_vocab = set()for review in reviews:for word in review.split( ):if(total_countsword min_count):if(word in pos_neg_ratios.keys():if(pos_neg_ratiosword = polarity_cutoff) or (pos_neg_ratiosword = (total_pred / float(i+2) and label = POSITIVE):correct_s
30、o_far += 1if(s_decrypt(layer_2)0 / scaling_factor) = 0.5):returnPOSITIVEelse:returnNEGATIVEProgress:0.0% Speed(reviews/sec):0.0#Correct:1 #Trained:1 Training Accuracy:100.%0Progress:0.41% Speed(reviews/sec):1.978#Correct:66 #Trained:101 Training Accuracy:65.3%100Progress:0.83% Speed(reviews/sec):2.0
31、14#Correct:131 #Trained:201 Training Accuracy:65.1%200Progress:1.25% Speed(reviews/sec):2.011#Correct:203 #Trained:301 Training Accuracy:67.4%300Progress:1.66% Speed(reviews/sec):2.003#Correct:276 #Trained:401 Training Accuracy:68.8%400Progress:2.08% Speed(reviews/sec):2.007#Correct:348 #Trained:501
32、 Training Accuracy:69.4%500Progress:2.5% Speed(reviews/sec):2.015#Correct:420 #Trained:601 Training Accuracy:69.8%600Progress:2.91% Speed(reviews/sec):1.974#Correct:497 #Trained:701 Training Accuracy:70.8%700Progress:3.33% Speed(reviews/sec):1.973#Correct:581 #Trained:801 Training Accuracy:72.5%800P
33、rogress:3.75% Speed(reviews/sec):1.976#Correct:666 #Trained:901 Training Accuracy:73.9%900Progress:4.16% Speed(reviews/sec):1.983#Correct:751 #Trained:1001 Training Accuracy:75.0%1000Progress:4.33% Speed(reviews/sec):1.940#Correct:788 #Trained:1042 Training Accuracy:75.6%.十、相比数据加密的优势和这一做法最相似的是加密训练数据
34、,然后在加密数据上训练神经网络(接受加密输入并预测加密输出)。这是一个出色的想法。然而,其实它有一些缺陷。首先也是最重要的,加密数据意味着对任何不具有加密数据的私钥的人而言,该神经网络完全无用。这样就不可能在不同的私有数据源上训练同一深度学习模型了。大部分商业应用有这样的需求,需要汇总消费者的数据。理论上,我们本来想要让每个消费者用他们自己的密钥保护自己的数据,然而同态加密数据要求所有人使用相同的钥。而加密网络则没有这个限制。基于上述方法,你可以训练一个平常的、解密的神经网络一段时间,加密它,将它和相应的公钥发给A方(A方可以基于其所有的数据训练网络一段时间A方保留数据)。接着,你可以收回这个
35、网络,解密它,用另一个钥加密网络,然后发给B方,B方在其所有的数据上进行一些训练。由于网络自身被加密了,你可以完全控制全过程中你刻画的智能。A方和B方将无法知道他们各自收到的是同一个网络,也无法知道之前见过这个网络,或在自己的数据上用过这个网络。你的公司保留对神经网络中的知识产权的控制,而每个用户保留对他们自己的数据的控制。十一、以后的工作存在更快、更安全的同态加密算法。我相信将本项工作移植到YASHE会是一个正确的方向。由于一些系统复杂性,也许开发一个能让用户更简单地进行加密的框架会是一个好主意。一般而言,为了达到生产环境要求的质量,HE需要变得更快。然而,这方面的进展十分迅速。我确信我们会在不久的将来达到这一点。十二、潜在应用分布式AI商业公司可以分布式地部署它们的模型(用于训练或使用),而无需冒智能被窃的风险。保护消费者隐私之前的应用提供了这样的可能性:消费者保留他们的数据,选择不同的模型在自己的设备上训练,不用将数据发送到别处。如果商业公司的智能在分布式场景中没有被窃的风险,那么他们不尊重消费者隐私的借口就会少很多。数据就是力量,它需要回归到人们手中。受控超智能网络可以充分发展其智能,不过除非它具有密钥,否则它只能预测乱码。
链接地址:https://www.31doc.com/p-3411416.html