基于同态加密的机器学习 (一)
基于同态加密的机器学习 (一)
1 项目说明
随着计算机技术的发展和人工智能的兴起,机器学习在许多领域的应用已经取得了巨大的成功。机器学习的性能表现通常与使用的数据量成正比,因此需要收集大量的数据。在大数据背景下,用户和服务商都面临着隐私泄露问题,此外还有一些攻击者通过一些手段来获取数据进行牟利。另一方面,也要防止机器学习中模型参数的泄露。因此解决机器学习中的隐私保护问题成为当务之急。在不影响机器学习性能的前提下,本项目使用神经网络的隐私保护训练方法,以有效的同态加密方案来保护数据的隐私性。
同时为了方便对比,本项目分为两部分,项目(一)未使用同态加密方案进行神经网络训练,项目(二)使用同态加密进行神将网络训练。
2 环境配置
- windows 10
- python>=3.6
- 常见python库
3 数据准备
3.1 数据介绍
这个数据集有两个类别值用于诊断它们是M(恶性)和B(良性)。
Breast cancer Wisconsin
3.2 数据结构
每个细胞核计算10个实值特征:
半径(平均点距离中心的周长)
纹理(灰度值的标准差)
周长
面积
平滑(本地半径长度变化)
密实度
凹度(凹部分轮廓的严重性)
凹点
对称性
分形维数
计算这些特征的平均值、标准误差和“最差”或最大(三个最大值的平均值),得到30个特征。所有特征值都用四位有效数字记录。此数据集不包含任何缺失的属性值。
3.3 数据预处理
导入依赖
from sklearn.model_selection import train_test_split
载入数据
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)
4 模型构建
神经网络(Neural network, NN)作为一种人工智能技术,经常用于数据挖掘等任务。神经网络具有学习和建立非线性复杂关系模型的能力,因此得到了广泛的应用。本项目采用了一种基于梯度的反向传播人工神经网络(GBP-ANN)。
4.1 网络结构
神经网络可以被认为是逻辑回归在宽度和深度上的扩展;正传播是一个复合函数的连续传播过程。反向传播是对一个复合函数求导的过程。当神经网络的隐藏层变成多层[22]时,神经网络就变成了一个深度学习模型。
4.2 前向传播
将上一层的输出作为下一层的输入,并计算下一层的输出,一直到运算到输出层为止。
l1 = self.sigmoid(np.dot(self.X, self.w1))
l2 = self.sigmoid(np.dot(l1, self.w2))
4.3 激活函数
选择sigmoid函数,因为它函数输出在(0,1)之间,输出范围有限,优化稳定,可以用作输出层。而且sigmoid是连续函数,便于求导。
def sigmoid(self, X):
return (1 / (1 + np.exp(-X)))
def sigmoid_prime(self, X):
return X * (1 - X)
4.4 后向传播
是对网络中所有权重计算损失函数的梯度。我们使用梯度下降来训练模型,这个梯度会反馈给最优化方法,用来更新权值以最小化损失函数。在这个阶段,我们计算网络在前向传播中的误差,error= True- Predicted。
error = self.Y - l2
l2_delta = error * self.sigmoid_prime(l2)
l1_delta = l2_delta.dot(self.w2.T) * self.sigmoid_prime(l1)
4.5 权值更新
为了使结果更接近实际值,对权值进行更新。
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)
4.6 完整模型训练代码
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import precision_recall_fscore_support
from sklearn import datasets
def train(self, epochs):
for e in range(epochs):
l1 = self.sigmoid(np.dot(self.X, self.w1))
l2 = self.sigmoid(np.dot(l1, self.w2))
error = self.Y - l2
l2_delta = error * self.sigmoid_prime(l2)
l1_delta = l2_delta.dot(self.w2.T) * self.sigmoid_prime(l1)
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)
5 模型预测
将训练所得的模型用测试数据进行预测:
def test(self):
correct = 0
pred_list = []
l1 = self.sigmoid(np.dot(self.X_test, self.w1))
l2 = self.sigmoid(np.dot(l1, self.w2))
for i in range(len(l2)):
if l2[i] >= 0.5:
pred = 1
else:
pred = 0
if pred == self.Y_test[i]:
correct += 1
pred_list.append(pred)
print('Test Accuracy : ', ((correct / len(Y_test)) * 100), ‘%’)
数据可视化,画出热力图
cm = confusion_matrix(Y_test, pred_list)
sns.heatmap(cm, annot=True,cmap=‘BuPu’,fmt=‘3g’)
图片标题文本和字体大小
plt.title(‘Ciphertext data’,fontsize=15)
x轴label的文本和字体大小
plt.xlabel(‘Real Value’,fontsize=15, color=‘k’)
y轴label的文本和字体大小
plt.ylabel(‘Predict Value’,fontsize=15, color=‘k’)
plt.x_tick = [‘False’, ‘True’]
plt.y_tick = [‘False’, ‘True’]
plt.savefig(‘h.png’)
plt.show()
6 总结
项目(一)实现了明文下的神经网络训练和学习,项目(二)将在此基础上对代码进行改进,实现同态加密的神经网络训练。
下面附上项目(一)的完整代码
In [1]
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import precision_recall_fscore_support
from sklearn import datasets
class NeuralNetwork:
def init(self, X, Y, X_test, Y_test, hidden_nodes=10, learninig_rate=0.01, epochs=5000):
# data
self.X = X
self.Y = Y
self.X_test = X_test
self.Y_test = Y_test
self.see = {}
self.input_nodes = self.X.shape[1]
self.hidden_nodes = hidden_nodes
self.output_nodes = self.Y.shape[1]
self.learning_rate = learninig_rate
self.w1 = 2 * np.random.random((self.input_nodes, self.hidden_nodes)) - 1
self.w2 = 2 * np.random.random((self.hidden_nodes, self.output_nodes)) - 1
self.train(epochs)
self.test()
def sigmoid(self, X):
return (1 / (1 + np.exp(-X)))
def sigmoid_prime(self, X):
return X * (1 - X)
def train(self, epochs):
for e in range(epochs):
l1 = self.sigmoid(np.dot(self.X, self.w1))
l2 = self.sigmoid(np.dot(l1, self.w2))
error = self.Y - l2
l2_delta = error * self.sigmoid_prime(l2)
l1_delta = l2_delta.dot(self.w2.T) * self.sigmoid_prime(l1)
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)
def test(self):
correct = 0
pred_list = []
l1 = self.sigmoid(np.dot(self.X_test, self.w1))
l2 = self.sigmoid(np.dot(l1, self.w2))
for i in range(len(l2)):
if l2[i] >= 0.5:
pred = 1
else:
pred = 0
if pred == self.Y_test[i]:
correct += 1
pred_list.append(pred)
print('Test Accuracy : ', ((correct / len(Y_test)) * 100), '%')
#print(Y_test)
#print(pred_list)
cm = confusion_matrix(Y_test, pred_list)
sns.heatmap(cm, annot=True,cmap='BuPu',fmt='3g')
plt.title('Plaintext Data', fontsize=15) # 图片标题文本和字体大小
plt.xlabel('Real Value', fontsize=15, color='k') # x轴label的文本和字体大小
plt.ylabel('Predict Value', fontsize=15, color='k') # y轴label的文本和字体大小
plt.x_tick = ['False', 'True']
plt.y_tick = ['False', 'True']
plt.savefig('h.png')
plt.show()
if name == “main”:
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,random_state=25)
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)
nn = NeuralNetwork(X_train, Y_train, X_test, Y_test)
Test Accuracy : 93.85964912280701 %
更多推荐
所有评论(0)