基于Numpy实现同态加密神经网络Word格式.docx

上传人:b****6 文档编号:8338850 上传时间:2023-05-11 格式:DOCX 页数:11 大小:24.71KB
下载 相关 举报
基于Numpy实现同态加密神经网络Word格式.docx_第1页
第1页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第2页
第2页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第3页
第3页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第4页
第4页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第5页
第5页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第6页
第6页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第7页
第7页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第8页
第8页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第9页
第9页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第10页
第10页 / 共11页
基于Numpy实现同态加密神经网络Word格式.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

基于Numpy实现同态加密神经网络Word格式.docx

《基于Numpy实现同态加密神经网络Word格式.docx》由会员分享,可在线阅读,更多相关《基于Numpy实现同态加密神经网络Word格式.docx(11页珍藏版)》请在冰点文库上搜索。

基于Numpy实现同态加密神经网络Word格式.docx

顾名思义,同态加密是一种加密的形式。

在不对称情形下,它可以接受完全可读的文本,然后基于“公钥”将其转变为乱码。

更重要的是,它可以基于“私钥”将乱码转回同样的文本。

然而,除非你有“私钥”,(理论上)你无法解码加密后的乱码。

同态加密是一种特殊形式的加密。

它允许某人在无法阅读信息的前提下以特定的方式修改加密信息。

例如,同态加密可以应用于数字上,让加密过的数字可以进行乘法和加法运算而无需解密数字。

下面是一些玩具样例。

现在出现了越来越多的同态加密方案,各有不同的性质。

这是一个相对年轻的领域,仍有一些明显的问题有待解决,不过我们将这些内容留待以后讨论。

就目前而言,让我们从整数公钥加密方案开始。

整数公钥加密方案是一种乘法和加法上的同态加密,允许进行上图的操作。

不仅如此,由于公钥允许“单向”加密,你甚至可以进行未加密数字和加密数字间的运算(通过单向加密),上图的2*CypherA就是一个例子。

(某些加密方案甚至不要求这一点……不过同样……我们以后讨论这个。

三、我们可以结合这两者吗?

也许深度学习和同态加密之间最频繁的互动体现在数据隐私上。

当你同态加密数据时,你无法读取数据但仍然可以保持大多数有趣的统计学结构。

这让人们得以在加密数据上训练模型(CryptoNets)。

甚至有一家名为Numer.ai的初创对冲基金加密昂贵的专有数据,允许任何人尝试训练机器学习模型预测股票市场。

通常这不可能办到,因为会导致放弃极为昂贵的信息(不可能基于通常的加密数据训练模型)。

然而,本文将反其道而行,加密神经网络,然后在解密信息上加以训练。

复杂度惊人的神经网络,事实上可以划分成很少(少得惊人)几种组件,这些组件不断重复以构成神经网络。

其实,仅仅基于如下操作,就可以创建很多最先进的神经网络:

加法

乘法

除法

减法

Sigmoid

Tanh

指数函数

那么,让我们提出这一明显的技术问题,我们能否同态加密神经网络本身?

我们会想这么做吗?

结果发现,基于一些保守的逼近,这是可以办到的。

加法——开箱即用

乘法——开箱即用

除法——开箱即用?

只是乘法的倒数

加法——开箱即用?

只是加上负数

Sigmoid——嗯……也许有点难度

Tanh——嗯……也许有点难度

指数函数——嗯……也许有点难度

看起来实现除法和减法会是相当微不足道的事情,但那些更复杂的函数就……好吧……比简单的加法和乘法更复杂。

为了尝试同态加密一个深度神经网络,我们还需要一个秘密原料。

四、泰勒级数展开

也许你在小学学过,泰勒级数允许我们使用无限项加法、减法、乘法、除法来计算一个复杂(非线性)函数。

这很完美!

(除了无限部分)。

幸运的是,如果你早早地停止了计算精确的泰勒级数展开,你仍然能得到手头的函数的一个逼近值。

下面是通过泰勒级数逼近一些流行函数的例子(来源)。

等下!

这里有指数!

别担心。

指数不过是反复相乘。

下面是使用泰勒级数逼近sigmoid函数的python实现(相关公式见WolframAlpha)。

我们将选取级数的开始几项,看看能逼近到什么程度。

importnumpyasnp

defsigmoid_exact(x):

return1/(1+np.exp(-x))

#使用泰勒级数

defsigmoid_approximation(x):

return(1/2)+(x/4)-(x**3/48)+(x**5/480)

forlil_numberin[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))

精确的Sigmoid值:

+str(sigmoid_exact(lil_number)))

逼近Sigmoid:

+str(sigmoid_approximation(lil_number)))

结果:

输入:

0.1

0.52497918747894

0.5249791874999999

0.2

0.549833997312478

0.549834

0.3

0.574442516811659

0.5744425624999999

0.4

0.598687660112452

0.598688

0.5

0.622459*********6

0.6224609375000001

0.6

0.6456563062257954

0.6456620000000001

0.7

0.6681877721681662

0.6682043125000001

0.8

0.6899744811276125

0.690016

0.9

0.7109495026250039

0.7110426875

1.0

0.7310585786300049

0.73125

仅仅使用了泰勒级数的前4项,我们已经相当逼近sigmoid函数了。

既然我们已经具备了通用的策略,是时候选择一个同态加密算法了。

五、选择加密算法

同态加密是一个相对较新的领域,其中的主要里程碑是CraigGentry在2009年发现的第一个全同态加密算法。

这一里程碑为许多后来者建立了据点。

大部分关于同态加密的激动人心的研究围绕开发图灵完备的同态加密计算机展开。

因此,对全同态加密方案的需求让人们试图找到一个算法,使得进行任意计算所需的多种逻辑门都可以通这一算法高效而安全地计算。

大体的希望是人们能够安全地将工作放到云端,而不必冒发送到云端的数据被发送者以外的人读取的风险。

这是一个非常酷的想法,也取得了很多进展。

然而,这一角度存在一些缺陷。

一般而言,相比普通电脑,大多数全同态加密方案慢得让人怀疑人生(目前还不实用)。

这鼓舞了一系列有趣的研究,将操作种类限制为某种程度上同态,这样至少可以进行某些操作。

不那么灵活,但是更快,这是常见的计算上的折衷。

这是我们想要开始查看的地方。

理论上,我们想要一个操作浮点数的同态加密方案(不过很快我们将看到,最终我们选择了操作整数的方案),而不是操作二进制值的方案。

二进制可以工作,但它不仅要求全同态加密的灵活性(以性能为代价),还要求我们管理二进制表示和我们想要计算的数学运算之间的逻辑。

一个不那么强大,为浮点运算定制的HE(HE为同态加密HomomorphicEncryption的缩写)算法会更合适。

尽管加上了这一限制,仍有非常多的选择。

下面是一些具备我们需要的特性的流行算法:

EfficientHomomorphicEncryptiononIntegerVectorsandItsApplications(基于整数向量的高效同态加密及其应用)

YetAnotherSomewhatHomomorphicEncryption(YASHE)(又一个某种程度上的同态加密)

SomewhatPracticalFullyHomomorphicEncryption(FV)(某种程度上实用的全同态加密)

FullyHomomorphicEncryptionwithoutBootstrapping(非自举的全同态加密)

最佳的选择可能是YASHE或FV。

YASHE是流行的CryptoNet使用的算法,对浮点运算的支持很棒。

然而,它相当复杂。

为了让这篇文章容易阅读、便于尝试,我们将选择稍微不那么高级(可能也不那么安全)的EfficientIntegerVectorHomomorphicEncryption(高效整数向量同态加密)。

然而,我认为非常值得指出的是,在你阅读本文的时候,更多新的HE算法正在开发之中,同时本文展示的想法通用于任何在整数或浮点数的加法和乘法上同态加密的方案。

甚至说,我的愿望是引起对HE的这一应用的关注,以便更多的为深度学习优化的HE算法能被开发出来。

Yu、Lai、Paylor的论文EfficientIntegerVectorHomomorphicEncryption详细描述了这一算法,相应的实现可以在GitHub上获取(jamespayor/vector-homomorphic-encryption)。

主要部分在C++++文件vhe.cpp中。

下面我们引导读者阅读代码的一个python移植,说明代码是干什么的。

如果你选择实现一个更高级的方案,这也会很有帮助,因为有一些主题相对而言是通用的(一般函数名,变量名,等等)。

六、Python中的同态加密

首先是一些同态加密术语:

明文(plaintext) 

未加密数据。

也叫“消息”。

在我们的例子中,这将是一些表示神经网络的数字。

密文(cyphertext) 

加密数据。

我们将在密文之上进行数学运算,这些运算会改变底层的明文。

公钥(publickey) 

伪随机数字序列,让任何人得以加密数据。

可以和别人分享,因为(理论上)公钥只能用于加密。

私钥/密钥(private/secretkey) 

伪随机数字序列,让你解密被公钥加密的数据。

你不想和别人分享私钥。

否则,别人可以解密你的消息。

对应的变量名(不同的同态加密技术都倾向于使用这些标准变量名):

表示密钥/私钥的矩阵。

用于解密。

公钥。

用于加密和进行数学运算。

在有些算法中,不是所有数学运算都需要公钥。

但这一算法非常广泛地使用公钥。

加密数据向量,密文。

消息,即明文。

有些论文使用m作明文的变量名。

单个“加权(weighting)”标量变量,用于重加权输入消息x(让它一致地更长或更短)。

这一变量用于调节信噪比。

加强信号后,对于给定的操作而言,消息较不容易受噪声影响。

然而,过于加强信号,会增加完全毁坏数据的概率。

这是一个平衡。

E或e 

一般指随机噪声。

在某些情形下,指用公钥加密数据前添加的噪声。

一般而言,噪声使解密更困难。

噪声使同一消息的两次加密可以不一样,在让消息难以破解方面,这很重要。

注意,取决于算法和实现,这可能是一个向量,也可能是一个矩阵。

在其他情形下,指随操作积累的噪声,详见后文。

和许多数学论文的惯用法一样,大写字母对应矩阵,小写字母对应向量,斜体小写对应标量。

我们关注同态加密的四种操作:

公私钥对生成,单向加密,解密,数学运算。

让我们从解密开始。

左边的公式描述了密钥S和消息x的一般关系。

右边的公式显示了如何使用密钥解密消息。

不知道你注意到没有,右边的公式并不包含e。

基本上,同态加密技术一般引入足够多的噪声使没有密钥的情况下难以破解出原始消息,但是引入的噪声的量又足够少,当你确实具有密钥时噪声可以通过取整忽略。

右边的公式中的框表示“取整到最接近的整数”。

其他同态加密算法使用不同的取整。

模数运算几乎普遍存在。

而加密则生成使上述关系为真的c.如果S是一个随机矩阵,那么c很难解密。

一个简单的、非对称的生成加密钥的方式是找到密钥的逆矩阵。

让我们看下相应的Python代码。

defgenerate_key(w,m,n):

S=(np.random.rand(m,n)*w/(2**16))#可证明max(S)

注意,我们可以对密文进行一些基本的运算,这些运算改动了相应的明文。

很优雅,不是吗?

七、优化加密

重要一课:

回顾一下之前的公式。

如果密钥S是一个单位矩阵,那么c不过是输入x的一个重加权的、略带噪声的版本。

如果你不明白上面的话,请Google“单位矩阵教程”。

限于篇幅,这里就不详细介绍单位矩阵了。

这引导我们思考加密是如何进行的。

论文作者没有显式地分配一对独立的“公钥”和“私钥”,相反,提出了一种“钥交换”技术,将私钥S替换为S。

更具体地,这一私钥交换技术涉及生成一个可以进行该变换的矩阵M。

由于M具备将消息从未加密状态(单位矩阵密钥)转换为加密状态(随机而难以猜测的密钥),这个M矩阵正好可以用作我们的公钥!

上面一段话包含许多信息,我们也许讲得太快了。

让我们重新概括一下。

发生了什么……

基于上面两个公式,如果密钥是一个单位矩阵,那么消息是未加密的。

基于上面两个公式,如果密钥是一个随机矩阵,那么消息是加密的。

我们构造一个矩阵M将一个密钥转换为另一个私钥。

当矩阵M将单位矩阵转换为一个随机密钥时,根据定义,它使用单向加密方式加密了消息。

由于M充当了“单向加密”的角色,我们称它为“公钥”,并且可以像公钥一样分发它,因为它无法用于解密。

好了,不多拖延了,让我们看下这一切是如何通过Python实现的。

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)

returnc,S

x=np.array([0,1,2,5])

m=len(x)

n=m

w=16

S=generate_key(w,m,n)

上面的代码的基本思路是让S大体上是单位矩阵,然后在其之上连接一个随机向量T。

因此T具备所有密钥所需的信息,不过我们仍然需要构建一个尺寸为S的矩阵使得一切可以工作。

八、创建一个XOR神经网络

既然我们已经知道如何加密和解密消息(以及进行基本的加法和乘法计算),是时候尝试扩展剩余的运算,以便构建一个简单的XOR神经网络。

尽管从技术上说,神经网络不过是一系列非常简单的操作,我们还是需要一些操作的组合以实现便利的功能。

下面我将描述我们需要的每项操作,以及在一个较高的抽象层次上,我们是如何实现这些操作的(基本上是我们将使用的加法和乘法的序列)。

接着我会向你展示代码。

关于一些细节,请参考前面提到的论文。

浮点数 

我们将简单地scale浮点数到整数。

我们将在整数上训练我们的网络(把整数当成浮点数)。

比如,假设scale=1000,0.2*0.5=0.1就是200*500=100000。

还原时,100000/(1000*1000)=0.1(因为我们使用了乘法,所以需要除以1000的平方)。

初看起来这很有技巧性,但你会适应的。

由于我们使用的HE方案取整到最接近的整数,这也让我们得以控制神经网络的精度。

向量矩阵乘法 

这是我们的黄油面包(最基本的操作)。

事实上,转换密钥的矩阵M是一种线性变换的方式。

内积 

在合适的背景下,上述线性变换可能是内积。

sigmoid 

由于我们可以进行向量矩阵乘法运算,基于足够的乘法,我们可以演算任意多项式的值。

因为我们已经知道了对应sigmoid的泰勒级数多项式,我们可以演算sigmoid的逼近值!

逐元素矩阵乘法 

这一操作惊人地低效。

我们需要进行向量矩阵乘法或一系列内积运算。

外积 

我们可以通过掩码和内积完成这一运算。

声明一下,可能存在完成这些运算的更高效的方法,但我不想冒打破同态加密方案完整性的风险。

所以某种程度上我是通过论文中提供的函数来反推如何完成上述运算的(除了算法容许的sigmoid扩展)。

现在,让我们看看完成这些的Python代码:

defsigmoid(layer_2_c):

out_rows=list()

forpositioninrange(len(layer_2_c)-1):

M_position=M_onehot[len(layer_2_c)-2][0]

layer_2_index_c=innerProd(layer_2_c,v_onehot[len(layer_2_c)-2][position],M_position,l)/scaling_factor

x=layer_2_index_c

x2=innerProd(x,x,M_position,l)/scaling_factor

x3=innerProd(x,x2,M_position,l)/scaling_factor

x5=innerProd(x3,x2,M_position,l)/scaling_factor

x7=innerProd(x5,x2,M_position,l)/scaling_factor

xs=copy.deepcopy(v_onehot[5][0])

xs[1]=x[0]

xs[2]=x2[0]

xs[3]=x3[0]

xs[4]=x5[0]

xs[5]=x7[0]

out=mat_mul_forward(xs,H_sigmoid[0:

1],scaling_factor)

out_rows.append(out)

returntranspose(out_rows)[0]

defload_linear_transformation(syn0_text,scaling_factor=1000):

syn0_text*=scaling_factor

returnlinearTransformClient(syn0_text.T,getSecretKey(T_keys[len(syn0_text)-1]),T_keys[len(syn0_text)-1],l)

defouter_product(x,y):

flip=False

if(len(x)=50):

pos_neg_ratio=positive_counts[term]/float(negative_counts[term]+1)

pos_neg_ratios[term]=pos_neg_ratio

forword,ratioinpos_neg_ratios.most_common():

if(ratio>

1):

pos_neg_ratios[word]=np.log(ratio)

else:

pos_neg_ratios[word]=-np.log((1/(ratio+0.01)))

review_vocab=set()

forreviewinreviews:

forwordinreview.split("

"

):

if(total_counts[word]>

min_count):

if(wordinpos_neg_ratios.keys()):

if((pos_neg_ratios[word]>

=polarity_cutoff)or(pos_neg_ratios[word]=(total_pred/float(i+2))andlabel==POSITIVE):

correct_so_far+=1

if((s_decrypt(layer_2)[0]/scaling_factor)=0.5):

return"

POSITIVE"

NEGATIVE"

Progress:

0.0%Speed(reviews/sec):

0.0#Correct:

1#Trained:

1TrainingAccuracy:

100.%0

0.41%Speed(reviews/sec):

1.978#Correct:

66#Trained:

101TrainingAccuracy:

65.3%100

0.83%Speed(reviews/sec):

2.014#Correct:

131#Trained:

201TrainingAccuracy:

65.1%200

1.25%Speed(reviews/sec):

2.011#Correct:

203#Trained:

301TrainingAccuracy:

67.4%300

1.66%Speed(reviews/sec):

2.003#Correct:

276#Trained:

401TrainingAccuracy:

68.8%400

2.08%Speed(reviews/sec):

2.007#Correct:

348#Trained:

501TrainingAccuracy:

69.4%500

2.5%Speed(reviews/sec):

2.015#Correct:

420#Trained:

601TrainingAccuracy:

69.8%600

2.91%Speed(

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2