1 项目说明
  随着计算机技术的发展和人工智能的兴起,机器学习在许多领域的应用已经取得了巨大的成功。机器学习的性能表现通常与使用的数据量成正比,因此需要收集大量的数据。在大数据背景下,用户和服务商都面临着隐私泄露问题,此外还有一些攻击者通过一些手段来获取数据进行牟利。另一方面,也要防止机器学习中模型参数的泄露。因此解决机器学习中的隐私保护问题成为当务之急。在不影响机器学习性能的前提下,本项目使用神经网络的隐私保护训练方法,以有效的同态加密方案来保护数据的隐私性。
  同时为了方便对比,本项目分为两部分,项目(一)未使用同态加密方案进行神经网络训练,项目(二)使用同态加密进行神将网络训练。

2 前期准备
2.1 环境和数据
  环境配置以及数据处理都已经在项目(一)中详细叙述,项目(二)主要记录同态加密方面内容以及代码。
  本项目同态加密方案是采用基于共轭搜索问题( Conjugacy Search Problem, CSP)进行构造,参考了文章Privacy preservation for machine learning training and classification based on homomorphic encryption schemes,但是上述文章所提方案不具备语义安全性,因此在此基础上重新构造了CSP加密方案。

2.2 同态加密
  同态加密(Homomorphic encryption)使得用户能够直接在密文上直接进行运算,得到的结果经过解密后与在明文下的计算结果一致,是一项直接有效的保护数据隐私的技术。最近十年,在机器学习中应用FE来保护数据隐私的研究发展迅速。

2.3 CSP加密方案
  给定C←HE.Enck(M)C←HE.Enc_k (M)C←HE.Enc
k

(M)在一个非阿贝尔交换代数结构ΨΨΨ上,其中C=HMH−1C=HMH^{-1}C=HMH
−1
,求解H∈ΨH∈ΨH∈Ψ是一个困难问题。这样可以提高数据的安全性。

2.3.1 数据编码
  M←Encoding(m)M←Encoding(m)M←Encoding(m):将数据mmm经过编码函数转化为MMM,转化的MMM是满足a1+a2=a3+a4=a5+a6=ma_1+a_2=a_3+a_4=a_5+a_6=ma
1

+a
2

=a
3

+a
4

=a
5

+a
6

=m的三对随机数(a1,a2),(a3,a4),(a5,a6)(a_1,a_2 ),(a_3,a_4 ), (a_5,a_6 )(a
1

,a
2

),(a
3

,a
4

),(a
5

,a
6

),因此构造如下矩阵:

M1=(a1a2a2a1)M_{1}=\left(\begin{array}{ll}a_{1} & a_{2} \ a_{2} & a_{1}\end{array}\right)
M
1

=(
a
1

a
2

a
2

a
1


)

M2=(a3a4a4a3)M_{2}=\left(\begin{array}{ll}a_{3} & a_{4} \ a_{4} & a_{3}\end{array}\right)
M
2

=(
a
3

a
4

a
4

a
3


)

M3=(a5a6a6a5)M_{3}=\left(\begin{array}{ll}a_{5} & a_{6} \ a_{6} & a_{5}\end{array}\right)
M
3

=(
a
5

a
6

a
6

a
5


)

最终将M转换为

M=(M1R1R20M2R300M3)M=\left(\begin{array}{ccc}M_{1} & R_{1} & R_{2} \ 0 & M_{2} & R_{3} \ 0 & 0 & M_{3}\end{array}\right)
M=


M
1

0
0

R
1

M
2

0

R
2

R
3

M
3



2.3.2 密钥生成
  k←HE.KeyGen(1κ)k←HE.KeyGen(1^κ)k←HE.KeyGen(1
κ
):设置安全参数κκκ,生成加密密钥。当密钥生成时,矩阵均匀随机地从R(6×6)R^(6×6)R
(
6×6)中采样。它也可以表示为九个2×22×22×2矩阵的组合。

P=(P1P2P3P4P5P6P7P8P9),Pi=(Pi1Pi2Pi3Pi4),(i=1,2,…,9)P=\left(\begin{array}{lll}P_{1} & P_{2} & P_{3} \ P_{4} & P_{5} & P_{6} \ P_{7} & P_{8} & P_{9}\end{array}\right), P_{i}=\left(\begin{array}{ll}P_{i 1} & P_{i 2} \ P_{i 3} & P_{i 4}\end{array}\right),(i=1,2, \ldots, 9)
P=


P
1

P
4

P
7

P
2

P
5

P
8

P
3

P
6

P
9




,P
i

=(
P
i1

P
i3

P
i2

P
i4


),(i=1,2,…,9)

2.3.3 加密
  C←HE.Enck(M)C←HE.Enc_k (M)C←HE.Enc
k

(M): 根据加密密钥和加密功能,对编码后的数据进行加密,获得密文数据CCC:

C=PMP−1=P(M1R1R20M2R300M3)P−1C=P M P^{-1}=P\left(\begin{array}{ccc}M_{1} & R_{1} & R_{2} \ 0 & M_{2} & R_{3} \ 0 & 0 & M_{3}\end{array}\right) P^{-1}
C=PMP
−1
=P


M
1

0
0

R
1

M
2

0

R
2

R
3

M
3




P
−1

2.3.4 解密
  M←HE.Dec©M←HE.Dec©M←HE.Dec©: 使用密钥对编码的消息进行解密M=P−1CPM=P^{-1}CPM=P
−1
CP,因此:

M1=(a1a2a2a1)M_{1}=\left(\begin{array}{ll}a_{1} & a_{2} \ a_{2} & a_{1}\end{array}\right)
M
1

=(
a
1

a
2

a
2

a
1


)

然后计算m=a1+a2m=a_1+a_2m=a
1

+a
2

,恢复明文。

2.3 小结
本项目主要是以构建项目为主,在安全性以及同态性质方面不做过多描述,有兴趣的小伙伴约阅读上面提过的文章。

3 代码改进
3.1 CSP同态方案构造代码
编码与解码

In [ ]
def Encode_source(self,m): #源数据编码,保证a1>a2,a3>a4,a5>a6
a1=Fraction(randint(1,9))
a2=Fraction(m-a1)
a3=Fraction(randint(1,9))
a4=Fraction(m-a3)
a5=Fraction(randint(1,9))
a6=Fraction(m-a5)
M=sy.Matrix([[a1, a2, randint(1,9),randint(1,9),randint(1,9),randint(1,9)],
[a2, a1, randint(1,9),randint(1,9),randint(1,9),randint(1,9)],
[0, 0, 9, 4, randint(1,9),randint(1,9)],
[0, 0, 6, 3, randint(1,9),randint(1,9)],
[0, 0, 0, 0, 9, 4],
[0, 0, 0, 0, 6, 3]])
return M

def Decode_source(self,M):   #源数据解码
    return M[0,0]+M[0,1]

加密与解密

def Encryption(self,m):  #加密
    M=self.Encode_source(m)
    C=self.P*M*self.P_Inv
    return C

def Decryption(self,C):  #解密
    M=self.P_Inv*C*self.P
    m=self.Decode_source(M)
    return m

同态加法,同态乘法

def Hom_add(self,C1,C2):    #同态加法
    return C1+C2

def Hom_mul(self,C1,C2):    #同态乘法
    return C1*C2

完整同态方案代码:

In [ ]
import sys
sys.path.append(‘/home/aistudio/external-libraries’)
import sympy as sy
from fractions import Fraction
from random import *
import time

class CSP_1:
def init(self):
self.P= sy.randMatrix(6, 6, 1, 9)
self.P_Inv= self.P**-1
self.t = sy.Matrix([[0, 1, randint(1, 5), randint(1, 5), randint(1, 5), randint(1, 5)],
[1, 0, randint(1, 5), randint(1, 5), randint(1, 5), randint(1, 5)],
[0, 0, 0, 1, randint(1, 5), randint(1, 5)],
[0, 0, 1, 0, randint(1, 5), randint(1, 5)],
[0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 1, 0]])
self.T=self.Pself.tself.P_Inv

def Encode_source(self,m):   #源数据编码,保证a1^>a2^,a3^>a4^,a5^>a6^
    a1=Fraction(randint(1,9))
    a2=Fraction(m-a1)
    a3=Fraction(randint(1,9))
    a4=Fraction(m-a3)
    a5=Fraction(randint(1,9))
    a6=Fraction(m-a5)
    M=sy.Matrix([[a1, a2, randint(1,9),randint(1,9),randint(1,9),randint(1,9)],
                 [a2, a1, randint(1,9),randint(1,9),randint(1,9),randint(1,9)],
                 [0,  0,  9,            4,            randint(1,9),randint(1,9)],
                 [0,  0, 6,            3,            randint(1,9),randint(1,9)],
                 [0,  0,  0,             0,             9,           4],
                 [0,  0,  0,             0,             6,            3]])
    return M

def Decode_source(self,M):   #源数据解码
    return M[0,0]+M[0,1]

def Encryption(self,m):  #加密
    M=self.Encode_source(m)
    C=self.P*M*self.P_Inv
    return C

def Decryption(self,C):  #解密
    M=self.P_Inv*C*self.P
    m=self.Decode_source(M)
    return m

def Hom_add(self,C1,C2):    #同态加法
    return C1+C2

def Hom_mul(self,C1,C2):    #同态乘法
    return C1*C2

if name==“main”:
csp=CSP_1()
A = csp.Encryption(3)
B = csp.Encryption(2)
C = csp.Encryption(7)

T1 = csp.Hom_add(A,B)
T2 = csp.Hom_mul(B,C)
print('A:',3)
print('B:',2)
print('C:',7)
print("输出加密信息A,B相加,进行解密后的结果(同态加法)",csp.Decryption(T1))
print("输出加密信息B,C相加,进行解密后的结果(同态乘法)",csp.Decryption(T2))

A: 3
B: 2
C: 7
输出加密信息A,B相加,进行解密后的结果(同态加法) 5
输出加密信息B,C相加,进行解密后的结果(同态乘法) 14
3.2 同态加密神经网络代码
  构造了同态加密方案后,需要对原来的神经网络的函数进行重载,因为同态加法和同态乘法与明文数据的运算不一样,先导入上面的同态方案:

from CSP_Scheme import CSP
3.2.1 前向传播
In [ ]
#正向传播
l1={}
l2={}
#l1 = self.sigmoid(np.dot(self.X, self.w1))
#l2 = self.sigmoid(np.dot(l1, self.w2))
#输入层和隐藏层, X:(random,input), w1:(input,hidden); -->l1(random,hidden)
temp_l1=self.tool.dict_dot(X_format, self.w1,self.size_X_r,self.input_nodes,self.hidden_nodes)
for i in temp_l1:
l1[i] = self.sigmoid(temp_l1[i])
#隐藏层和输出层, l1(random,hidden) w2:(hidden,output),–>l2(random,output)
temp_l2=self.tool.dict_dot(l1, self.w2,self.size_X_r,self.hidden_nodes,self.output_nodes)
for j in temp_l2:
l2[j] = self.sigmoid(temp_l2[j])
3.2.2 sigmoid函数
由于同态加密对于sigmoid函数太复杂了,因此我们采用分段多项式去拟合sigmoid函数,达到相同的效果:

y={0.571859+(0.392773)x+(0.108706)x2+(0.014222)x3+(0.000734)x4−∞<x≤−1.512+14x−148x3+1480x5−1.5<x<1.50.428141+(0.392773)x−(0.108706)x2+(0.014222)x3−(0.000734)x41.5≤x<∞y= \begin{cases}0.571859+(0.392773) x+(0.108706) x^{2}+ (0.014222) x^{3}+(0.000734) x^{4} & -\infty<x \leq-1.5 \ \frac{1}{2}+\frac{1}{4} x-\frac{1}{48} x^{3}+\frac{1}{480} x^{5} & -1.5<x<1.5 \ 0.428141+(0.392773) x-(0.108706) x^{2}+ (0.014222) x^{3}-(0.000734) x^{4} & 1.5 \leq x<\infty\end{cases}
y=







0.571859+(0.392773)x+(0.108706)x
2
+(0.014222)x
3
+(0.000734)x
4

2
1

+
4
1

x−
48
1

x
3
+
480
1

x
5

0.428141+(0.392773)x−(0.108706)x
2
+(0.014222)x
3
−(0.000734)x
4

−∞<x≤−1.5
−1.5<x<1.5
1.5≤x<∞

In [ ]
def sigmoid(self,X): #(1 / (1 + np.exp(-X))),使用多项式进行替换,A*X^3
if self.csp.Cipher_compare(X, self.con_2) <= 0: #x<-1.5
ans= self.A1 + self.tool.sigmoid_piece(self.A2,X,1) +
self.tool.sigmoid_piece(self.A3, X,2) + self.tool.sigmoid_piece(self.A4, X,3) +
self.tool.sigmoid_piece(self.A5, X,4)

elif self.csp.Cipher_compare(X,self.con_1) > 0:        #x>1.5
    ans= self.C1 + self.tool.sigmoid_piece(self.C2,X,1) - \
            self.tool.sigmoid_piece(self.C3, X,2) + self.tool.sigmoid_piece(self.C4, X,3) -\
            self.tool.sigmoid_piece(self.C5, X,4)
else:
    ans= self.B1 + self.tool.sigmoid_piece(self.B2, X, 1) - \
            self.tool.sigmoid_piece(self.B3, X, 3) + self.tool.sigmoid_piece(self.B4, X, 5)
if self.csp.Cipher_compare(ans,self.con_4) >= 0:
    ans=self.csp.Encryption(1)
if self.csp.Cipher_compare(ans,self.con_6) <= 0:
    ans=self.csp.Encryption(-1)
return ans

def sigmoid_prime(self, X): #sigmoid方程求导,X * (1 - X),此时参数X为加密矩阵
temp = self.csp.Hom_sub(self.sig_1, X)
return self.csp.Hom_mul(X,temp)
3.2.3 后向传播
In [ ]
error={}
for i in Y_format:
error[i] = self.csp.Hom_sub(Y_format[i],l2[i]) #索引问题

l2_delta = error * self.sigmoid_prime(l2)

l1_delta = l2_delta.dot(self.w2.T) * self.sigmoid_prime(l1),字典之间的运算

l2_delta={}
sig_l2={} #self.sigmoid_prime(l2)应该设置为字典
for i in l2: #l2(random,output)
sig_l2[i]=self.sigmoid_prime(l2[i]) #error和sig_l2具有一样的索引#
for i in error:
l2_delta[i] = self.csp.Hom_mul(error[i],sig_l2[i])

#l2_delta(random,output),W2.T(output,hidden);l1(random,hideen)
l1_delta={}
sig_l1={}
for i in l1:
sig_l1[i]=self.sigmoid_prime(l1[i])
w2_T=self.tool.dict_T(self.w2, self.hidden_nodes, self.output_nodes)
l1_delta_temp=self.tool.dict_dot(l2_delta, w2_T, self.size_X_r, self.output_nodes, self.hidden_nodes)
for i in l1_delta_temp:
l1_delta[i] = self.csp.Hom_mul(l1_delta_temp[i], sig_l1[i])
3.2.4 权值更新
In [ ]

self.w2 = np.add(self.w2, l1.T.dot(l2_delta) * self.learning_rate)

self.w1 = np.add(self.w1, self.X.T.dot(l1_delta) * self.learning_rate)

w2_update=self.tool.dict_dot(self.tool.dict_T(l1,self.size_X_r,self.hidden_nodes), l2_delta, self.hidden_nodes, self.size_X_r, self.output_nodes)
for i in w2_update:
w2_update[i]=w2_update[i]*self.learning_rate
self.w2 = self.tool.dict_add(self.w2, w2_update, self.hidden_nodes, self.output_nodes)
w1_update=self.tool.dict_dot(self.tool.dict_T(X_format,self.size_X_r,self.input_nodes),l1_delta ,self.input_nodes,self.size_X_r,self.hidden_nodes)
for i in w1_update:
w1_update[i]=w1_update[i]*self.learning_rate
self.w1 = self.tool.dict_add(self.w1, w1_update,self.input_nodes,self.hidden_nodes)
3.2.5 预测
将训练好的,模型进行预测

In [ ]
correct = 0
pred_list = []
X_format,Y_format = self.tool.data_En(self.X_test, self.Y_test,1)#参数为1时,对y_编码后使用分数表示
l1 = {} #l1 = self.sigmoid(np.dot(self.X_test, self.w1))
l2 = {} #l2 = self.sigmoid(np.dot(l1, self.w2))

输入层和隐藏层, X:(random,input), w1:(input,hidden); -->l1(random,hidden)

temp_l1 = self.tool.dict_dot(X_format, self.w1, self.size_Xt_r, self.input_nodes,self.hidden_nodes)
for i in temp_l1:
l1[i] = self.sigmoid(temp_l1[i])

隐藏层和输出层, l1(random,hidden) w2:(hidden,output),–>l2(random,output)

temp_l2 = self.tool.dict_dot(l1, self.w2, self.size_Xt_r, self.hidden_nodes,self.output_nodes)
for j in temp_l2:
l2[j] = self.sigmoid(temp_l2[j])

for i in l2: #比较进行加密
if self.csp.Cipher_compare(l2[i],self.con_3)>=0: # l2[i] >= 0.5
pred = self.con_4 # pred = 1
pred_lab=1
else:
pred = self.con_5 # pred = 0
pred_lab=0
pred_list.append(pred_lab)
#精准比较
if self.csp.Cipher_compare(Y_format[i],pred,1)==0: # pred == self.Y_test[i],
correct += 1
print('Test Accuracy : ', ((correct / self.size_Yt_r) * 100), ‘%’)
print(“真实值”, self.Y_test.reshape(1,self.size_Yt_r))
print(“预测值”, pred_list)
并且将结果绘制出来在这里插入图片描述
4 总结
项目(二)实现了同态加密的神经网络学习,用的是公开数据集,其中也有很多地方未来得及优化。
同态操作复杂度高,十分耗时间,因此项目(二)的训练时间大概在20h左右。 下面附上完整的代码

In [ ]
import sys
sys.path.append(‘/home/aistudio/external-libraries’)
import numpy as np
import seaborn as sns
import time
import matplotlib.pyplot as plt
import pylab
import sympy as sy
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_recall_fscore_support
from My_Tool import Tool
from CSP_Scheme import CSP_1

#导入数据
cancer = datasets.load_breast_cancer()
X = cancer.data
Y = cancer.target

#随机划分为训练子集和测试子集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)

#按行展开
Y_train = Y_train[:, None]
Y_test = Y_test[:, None]
#数据归一化
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.fit_transform(X_test)

#建立神经网络
class NeuralNetwork:
def init(self, X, Y, X_test, Y_test, hidden_nodes=5, learninig_rate=0.1, epochs=5):
self.csp=CSP_1()
self.tool = Tool(self.csp)
self.X = X
self.Y = Y #按行展开
self.X_test = X_test
self.Y_test = Y_test

    self.size_X_r=X.shape[0]   #训练集的行数,即random
    self.size_Y_r = Y.shape[0]
    self.size_Xt_r=X_test.shape[0]
    self.size_Yt_r=Y_test.shape[0]

    self.input_nodes = self.X.shape[1]   #输入层节点,30;训练数据中特征的数量
    self.hidden_nodes = hidden_nodes     #隐藏层节点,5
    self.output_nodes = self.Y.shape[1]  #输出层节点,1
    self.learning_rate = learninig_rate  #学习率0.1

    #sigmoid函数近似替代
    self.con_1 = self.csp.Encryption_target(1.5)  #sigmoid函数的分段点,加密目标函数,注意修复没有
    self.con_2 = self.csp.Encryption_target(-1.5)
    self.con_3 = self.csp.Encryption_target(0.5)
    self.con_4 = self.csp.Encryption_target(1)
    self.con_5 = self.csp.Encryption_target(0)
    self.con_6 = self.csp.Encryption_target(-1)

    self.sig_1=self.csp.Encryption(1)
    self.A1 = self.csp.Encryption(0.571859)
    self.A2 = 0.392773
    self.A3 = 0.108706
    self.A4 = 0.014222
    self.A5 = 0.000734

    self.B1 = self.csp.Encryption(0.5)
    self.B2 = 0.25
    self.B3 = 0.020833
    self.B4 = 0.002083

    self.C1 = self.csp.Encryption(0.428141)
    self.C2 = 0.392773
    self.C3 = 0.108706
    self.C4 = 0.014222
    self.C5 = 0.000734

    #初始化网络权值
    self.w1={}
    self.w2={}

    #初始化两个权重矩阵,进行加密
    r_w1=np.random.random((self.input_nodes, self.hidden_nodes))  #随机矩阵
    r_w2=np.random.random((self.hidden_nodes, self.output_nodes))  #随机矩阵

    w1_temp =self.tool.dict_toformat(r_w1)           #加上索引
    w2_temp =self.tool.dict_toformat(r_w2)           #同上

    for i in w1_temp:
        self.w1[i]=self.csp.Encryption(w1_temp[i])           #将权重函数进行操作,
    for i in w2_temp:
        self.w2[i]=self.csp.Encryption(w2_temp[i])

    self.train(epochs)  # 模型进行多次训练
    self.test()

#定义激活函数 ,参数X是键值对,是否需要修改,注意sigmoid_price是把X当成加密矩阵,考虑是否循环
def sigmoid(self,X): #(1 / (1 + np.exp(-X))),使用多项式进行替换,A*X^3
    if self.csp.Cipher_compare(X, self.con_2) <= 0:          #x<-1.5
        ans= self.A1 + self.tool.sigmoid_piece(self.A2,X,1) + \
             self.tool.sigmoid_piece(self.A3, X,2) + self.tool.sigmoid_piece(self.A4, X,3) +\
             self.tool.sigmoid_piece(self.A5, X,4)

    elif self.csp.Cipher_compare(X,self.con_1) > 0:        #x>1.5
        ans= self.C1 + self.tool.sigmoid_piece(self.C2,X,1) - \
             self.tool.sigmoid_piece(self.C3, X,2) + self.tool.sigmoid_piece(self.C4, X,3) -\
             self.tool.sigmoid_piece(self.C5, X,4)
    else:
        ans= self.B1 + self.tool.sigmoid_piece(self.B2, X, 1) - \
             self.tool.sigmoid_piece(self.B3, X, 3) + self.tool.sigmoid_piece(self.B4, X, 5)
    if self.csp.Cipher_compare(ans,self.con_4) >= 0:
        ans=self.csp.Encryption(1)
    if self.csp.Cipher_compare(ans,self.con_6) <= 0:
        ans=self.csp.Encryption(-1)
    return ans

def sigmoid_prime(self, X):  #sigmoid方程求导,X * (1 - X),此时参数X为加密矩阵   X如果为1,??
    temp = self.csp.Hom_sub(self.sig_1, X)
    return self.csp.Hom_mul(X,temp)

def train(self, epochs):
    print('Train')
    X_format,Y_format=self.tool.data_En(self.X,self.Y)
    for e in range(epochs):
        print("\t===== epochs %d =====\t" % (e+1))
        #正向传播
        l1={}
        l2={}
        #l1 = self.sigmoid(np.dot(self.X, self.w1))
        #l2 = self.sigmoid(np.dot(l1, self.w2))
        temp_l1=self.tool.dict_dot(X_format, self.w1,self.size_X_r,self.input_nodes,self.hidden_nodes) #输入层和隐藏层, X:(random,input), w1:(input,hidden); -->l1(random,hidden)
        for i in temp_l1:
            l1[i] = self.sigmoid(temp_l1[i])
        temp_l2=self.tool.dict_dot(l1, self.w2,self.size_X_r,self.hidden_nodes,self.output_nodes)       #隐藏层和输出层, l1(random,hidden) w2:(hidden,output),-->l2(random,output)
        for j in temp_l2:
            l2[j] = self.sigmoid(temp_l2[j])

        #反向传播,误差(真实值-预测值)
        # 两加密后的字典,进行减法.,error = Y_format - l2;;;  erroe(519,1)
        error={}
        for i in Y_format:
            error[i] = self.csp.Hom_sub(Y_format[i],l2[i])   #索引问题
        #print('01:',error['0_0'])
        # l2_delta = error * self.sigmoid_prime(l2)
        # l1_delta = l2_delta.dot(self.w2.T) * self.sigmoid_prime(l1),,字典之间的运算
        l2_delta={}
        sig_l2={}         #self.sigmoid_prime(l2)应该设置为字典
        for i in l2:      #l2(random,output)
            sig_l2[i]=self.sigmoid_prime(l2[i])   #error和sig_l2具有一样的索引#
        #print(sig_l2)
        for i in error:
            l2_delta[i] = self.csp.Hom_mul(error[i],sig_l2[i])
            # print("*****************")
            print('02:',self.csp.Decryption(error[i]))
            # print('03:',self.csp.Decryption(sig_l2[i]))
            # print('04:',self.csp.Decryption(l2_delta[i]))

        #l2_delta(random,output),W2.T(output,hidden);l1(random,hideen)
        l1_delta={}
        sig_l1={}
        for i in l1:
            sig_l1[i]=self.sigmoid_prime(l1[i])
        w2_T=self.tool.dict_T(self.w2, self.hidden_nodes, self.output_nodes)
        l1_delta_temp=self.tool.dict_dot(l2_delta, w2_T, self.size_X_r, self.output_nodes, self.hidden_nodes)
        for i in l1_delta_temp:
            l1_delta[i] = self.csp.Hom_mul(l1_delta_temp[i], sig_l1[i])

        # self.w2 = np.add(self.w2, l1.T.dot(l2_delta) * self.learning_rate)
        # self.w1 = np.add(self.w1, self.X.T.dot(l1_delta) * self.learning_rate)
        w2_update=self.tool.dict_dot(self.tool.dict_T(l1,self.size_X_r,self.hidden_nodes), l2_delta, self.hidden_nodes, self.size_X_r, self.output_nodes)
        for i in w2_update:
            w2_update[i]=w2_update[i]*self.learning_rate
        self.w2 = self.tool.dict_add(self.w2, w2_update, self.hidden_nodes, self.output_nodes)

        w1_update=self.tool.dict_dot(self.tool.dict_T(X_format,self.size_X_r,self.input_nodes),l1_delta ,self.input_nodes,self.size_X_r,self.hidden_nodes)
        for i in w1_update:
            w1_update[i]=w1_update[i]*self.learning_rate
        self.w1 = self.tool.dict_add(self.w1, w1_update,self.input_nodes,self.hidden_nodes)


def test(self):
    print('Test')
    correct = 0
    pred_list = []

    X_format,Y_format = self.tool.data_En(self.X_test, self.Y_test,1)#参数为1时,对y_编码后使用分数表示
    l1 = {}    #l1 = self.sigmoid(np.dot(self.X_test, self.w1))
    l2 = {}    #l2 = self.sigmoid(np.dot(l1, self.w2))
    temp_l1 = self.tool.dict_dot(X_format, self.w1, self.size_Xt_r, self.input_nodes,self.hidden_nodes)  # 输入层和隐藏层, X:(random,input), w1:(input,hidden); -->l1(random,hidden)
    for i in temp_l1:
        l1[i] = self.sigmoid(temp_l1[i])

    temp_l2 = self.tool.dict_dot(l1, self.w2, self.size_Xt_r, self.hidden_nodes,self.output_nodes)  # 隐藏层和输出层, l1(random,hidden) w2:(hidden,output),-->l2(random,output)
    for j in temp_l2:
        l2[j] = self.sigmoid(temp_l2[j])

    for i in l2:    #比较进行加密
        if self.csp.Cipher_compare(l2[i],self.con_3)>=0:     # l2[i] >= 0.5
            pred = self.con_4                                # pred = 1
            pred_lab=1
        else:
            pred = self.con_5                                # pred = 0
            pred_lab=0
        pred_list.append(pred_lab)
            #精准比较
        if self.csp.Cipher_compare(Y_format[i],pred,1)==0:  # pred == self.Y_test[i],
            correct += 1
        #     true_list.append(pred_lab)
        # else:
        #     true_list.append(1-pred_lab)
        #pred_list.append(pred_lab)
    print('Test Accuracy : ', ((correct / self.size_Yt_r) * 100), '%')
    print("真实值", self.Y_test.reshape(1,self.size_Yt_r))
    print("预测值", pred_list)

    # 混淆矩阵
    #FN 00 预测为N,标签为P
    #FP 01 预测为P,标签为N
    #TN 10 预测为N,标签为N
    #FN 11 预测为P,标签为P
    # cm = confusion_matrix(Y_test, pred_list)
    # sns.heatmap(cm, annot=True)
    # plt.savefig('h.png')
    # plt.show()

#print(Y_test[0:20,:].reshape(1,20))
#nn = NeuralNetwork(X_train[0:10,:], Y_train[0:10,:], X_test[0:20,:], Y_test[0:20,:], 5, 0.1, 5)
nn = NeuralNetwork(X_train, Y_train, X_test, Y_test, 5, 0.1, 5)

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐