【译】Private Image Analysis with MPC Training CNNs on Sensitive Data

TL; DR:我们采用典型的CNN深度学习模式,并通过一系列步骤,使训练和预测都能够在加密数据上完成。

使用深度学习通过卷积神经网络 (CNN)分析图像在过去的几年中获得了巨大的普及,因为它们在这项工作和相关任务上取得了很多其他方法的成功。

最近的一个应用程序采取了皮肤癌检测的形式,任何人都可以使用手机应用程序快速拍摄皮肤损伤照片,并使用“与专家相媲美的性能”进行分析(请参阅相关视频以了解演示)。 获得大量临床照片是训练此模型的关键部分 - 可被视为敏感的数据集。

这给我们带来了隐私并最终确保了多方计算 (MPC):由于缺乏对数据的访问,今天有多少应用程序受到限制? 在上述情况下,通过让任何有手机应用程序的人都可以参与训练数据集,可以改进模型吗? 如果是这样,有多少人愿意冒着暴露个人健康相关信息的风险?

有了MPC,我们可以降低风险,从而增加参与的积极性。 更具体地说,通过改为对加密数据进行训练,我们可以防止任何人不仅看到单个数据,还看到学习的模型参数。另外还可以使用其他技术(如差分隐私)来隐藏预测中的任何泄漏,但我们不会在此讨论。

在这篇博客文章中,我们将看一个更简单的用于图像分析的用例,但需要查看所有必需的技巧。 一些笔记本是在这个过程中展示的,主要的笔记本是概念验证实施的一部分 。

巴黎机器学习聚会上最近的演示文稿幻灯片现已推出。

非常感谢Andrew Trask , Nigel Smart , AdriàGascónOpenMined社区为这个主题提供灵感和有趣的讨论! Jakukyo Friel也非常友好地做了中文翻译 。

设置

我们假设训练数据集由一组输入提供者共同持有,并且训练由两个不同的服务器 (或参与方 )执行,这些服务器 (或参与方 )不信任超出我们协议规定的协作范围。 实际上,这些服务器可以是例如由两个不同组织运行的共享云环境中的虚拟实例。

输入提供者仅在开始时才需要传输他们的(加密的)训练数据; 之后所有的计算只涉及两台服务器,这意味着输入提供商使用移动电话确实是合理的。 一旦训练完成,该模型将继续以加密形式由两台服务器共同保存,任何人都可以使用该服务器进行进一步的加密预测。

出于技术原因,我们还假设一个独立的密码生产者在计算过程中生成某些原材料以提高效率; 有办法消除这个额外的实体,但我们不会在这里进入。

最后,就安全性而言,我们的目标是实践中使用的一种典型概念,即诚实但好奇(或被动)的安全性 ,其中服务器被假定遵循协议但可能试图从数据中尽可能地学习看到。 尽管服务器的概念比完全恶意(或主动)的安全性稍弱,但它仍然能够对任何可能在计算损害其中一台服务器的人提供强有力的保护,尽管他们所做的事情都是如此。 请注意,为了本博文的目的,我们实际上将允许在培训期间发生一些小的隐私泄露,详情请参阅后文。

用CNN进行图像分析

我们的使用案例是规范的MNIST手写数字识别 ,即学习识别给定图像中的阿拉伯数字,我们将使用Keras示例中的以下CNN模型作为我们的基础。

 feature_layers = [ Conv2D ( 32 , ( 3 , 3 ), padding = 'same' , input_shape = ( 28 , 28 , 1 )), Activation ( 'relu' ), Conv2D ( 32 , ( 3 , 3 ), padding = 'same' ), Activation ( 'relu' ), MaxPooling2D ( pool_size = ( 2 , 2 )), Dropout ( . 25 ), Flatten () ] classification_layers = [ Dense ( 128 ), Activation ( 'relu' ), Dropout ( . 50 ), Dense ( NUM_CLASSES ), Activation ( 'softmax' ) ] model = Sequential ( feature_layers + classification_layers ) model . compile ( loss = 'categorical_crossentropy' , optimizer = 'adam' , metrics = [ 'accuracy' ]) model . fit ( x_train , y_train , epochs = 1 , batch_size = 32 , verbose = 1 , validation_data = ( x_test , y_test )) 

我们不会在这里详细介绍这个模型,因为这些原则已经 其他地方很好的覆盖了 ,但是其基本思想是首先通过一组要素图层来运行图像,这些要素图层将输入图像的原始像素转换为抽象属性这与我们的分类任务更相关。 随后,这些属性通过一组分类层进行组合,以产生可能数字的概率分布。 最终的结果通常只是具有最高分配概率的数字。

我们将看到,使用Keras的好处是,我们可以对未加密的数据执行快速实验,以了解模型本身的性能,并提供一个简单的接口,以便稍后模拟加密设置。

使用SPDZ进行安全计算

随着CNN的到位,我们接下来转向MPC。 为此,我们将使用最先进的SPDZ协议,因为它允许我们只有两台服务器,并通过将某些计算移动到离线阶段来提高在线性能,详见前面的博客 文章 。

作为安全计算协议的典型代表,所有计算都在一个字段中进行,这里由一个素数Q 。这意味着我们需要将由CNN使用的浮点数编码为整数模的素数,这会对Q产生一定的约束,进而影响性能。

此外, 回想一下 ,在诸如SPDZ协议的交互式计算中,除了典型的时间复杂度之外,还考虑通信和圆形复杂性也是相关的。 在这里,前者测量通过网络发送的比特数,这是一个相对缓慢的过程,后者是两台服务器之间所需的同步点数量,这可能会阻止其中一个无需处理,直到另一个服务器赶上。 这两者对整体执行时间也有很大影响。

但最重要的是,我们在这些协议中唯一的“本地”操作是加法和乘法。 可以完成分部,比较等工作,但在我们的三项绩效指标方面则较为昂贵。 稍后我们将看到如何减轻由此导致的一些问题,但我们首先回顾一下基本的SPDZ协议。

张量操作

当我们早些时候引入SPDZ协议时我们以PublicValuePrivateValue类的形式这样做,分别表示两个服务器都清楚已知的(标量)值和仅以秘密共享形式已知的加密值。 在这篇博客文章中,我们现在更自然地通过类PublicTensorPrivateTensor更自然地展示它,它们反映了在深度学习环境中大量使用张量 。

 class PrivateTensor : def __init__ ( self , values , shares0 = None , shares1 = None ): if not values is None : shares0 , shares1 = share ( values ) self . shares0 = shares0 self . shares1 = shares1 def reconstruct ( self ): return PublicTensor ( reconstruct ( self . shares0 , self . shares1 )) def add ( x , y ): if type ( y ) is PublicTensor : shares0 = ( x . values + y . shares0 ) % Q shares1 = y . shares1 return PrivateTensor ( None , shares0 , shares1 ) if type ( y ) is PrivateTensor : shares0 = ( x . shares0 + y . shares0 ) % Q shares1 = ( x . shares1 + y . shares1 ) % Q return PrivateTensor ( None , shares0 , shares1 ) def mul ( x , y ): if type ( y ) is PublicTensor : shares0 = ( x . shares0 * y . values ) % Q shares1 = ( x . shares1 * y . values ) % Q return PrivateTensor ( None , shares0 , shares1 ) if type ( y ) is PrivateTensor : a , b , a_mul_b = generate_mul_triple ( x . shape , y . shape ) alpha = ( x - a ) . reconstruct () beta = ( y - b ) . reconstruct () return alpha . mul ( beta ) + \ alpha . mul ( b ) + \ a . mul ( beta ) + \ a_mul_b 

正如所看到的,使用NumPy的适应非常简单,例如PrivateTensor的一般形式几乎完全相同,只是偶尔也传递一个形状。 但是有一些技术细节,所有这些都可以在相关的笔记本中完整获得。

 def share ( secrets ): shares0 = sample_random_tensor ( secrets . shape ) shares1 = ( secrets - shares0 ) % Q return shares0 , shares1 def reconstruct ( shares0 , shares1 ): secrets = ( shares0 + shares1 ) % Q return secrets def generate_mul_triple ( x_shape , y_shape ): a = sample_random_tensor ( x_shape ) b = sample_random_tensor ( y_shape ) c = np . multiply ( a , b ) % Q return PrivateTensor ( a ), PrivateTensor ( b ), PrivateTensor ( c ) 

因此,也许最大的区别在于使用这种形状的上述基本效用方法。

适应模型

虽然原则上可以用我们已有的方法安全地计算任何函数,因此也可以用上面的基础模型来计算任何函数,但实际上,首先考虑模型的MPC更友好的变体是相关的,反之亦然。 在稍微更加美观的文字中,通常打开我们的两个黑盒子,并使两种技术更好地适应对方。

这个根源来自于一些在加密设置中令人惊讶的昂贵的操作。 我们在上面看到,加法和乘法相对便宜,但与私人分母的比较和划分则不然。 为此,我们对模型进行了一些更改以避免这些情况。

本节介绍的各种变化以及它们的仿真性能可在相关的Python笔记本中完整获取。

优化

第一个问题涉及优化器:虽然Adam在许多实现中是效率优先的选择,但它也涉及到取一个私有值的平方根并使用一个作为分部的分母。 虽然理论上可以安全地计算这些值 ,但实际上它可能是性能的一个重要瓶颈,因此可能会避免。

一个简单的补救办法是切换到动力SGD优化器,这可能意味着更长的培训时间,但只使用简单的操作。

 model . compile ( loss = 'categorical_crossentropy' , optimizer = SGD ( clipnorm = 10000 , clipvalue = 10000 ), metrics = [ 'accuracy' ]) 

另外需要注意的是许多优化器都使用剪切来防止梯度变得太小或太大。 这需要对私有值进行比较 ,这在加密设置中又是一个比较昂贵的操作,因此我们的目标是完全避免使用这种技术。 为了从我们的Keras模拟中获得逼真的结果,我们增加了上面的边界。

图层

说到比较, ReLU和max-pooling层带来了类似的问题。 CryptoNets中 ,前者由平方函数替换,后者由平均汇集替换,而SecureML通过增加复杂度来实现类似ReLU的激活函数,我们希望避免简化事情。 因此,我们在这里改为使用高级S形激活函数和平均汇聚层。 请注意,平均汇集也使用一个分区,但这次分母是一个公共值,因此分区只是一个公共反转,然后是一个乘法。

 feature_layers = [ Conv2D ( 32 , ( 3 , 3 ), padding = 'same' , input_shape = ( 28 , 28 , 1 )), Activation ( 'sigmoid' ), Conv2D ( 32 , ( 3 , 3 ), padding = 'same' ), Activation ( 'sigmoid' ), AveragePooling2D ( pool_size = ( 2 , 2 )), Dropout ( . 25 ), Flatten () ] classification_layers = [ Dense ( 128 ), Activation ( 'sigmoid' ), Dropout ( . 50 ), Dense ( NUM_CLASSES ), Activation ( 'softmax' ) ] model = Sequential ( feature_layers + classification_layers ) 

模拟结果表明,通过这种变化,我们现在必须对时代数量进行调整,以相同的因子减慢训练时间。 学习速度或动力的其他选择可能会改善这一点。

 model . fit ( x_train , y_train , epochs = 15 , batch_size = 32 , verbose = 1 , validation_data = ( x_test , y_test )) 

其余层很容易处理。 Dropout和Flatten不关心我们是处于加密还是未加密的设置,密集和卷积是只需要基本操作的矩阵点产品。

Softmax和损失功能

最终的softmax层也会导致加密设置中的训练出现复杂情况,因为我们需要使用私有指数来计算幂运算 ,并使用带有私人分母的分割形式进行规范化。

虽然两者都有可能,但我们在这里选择一种更简单的方法,并将每个训练样本的预测类别可能性透露给其中一个服务器,然后他们可以根据显示的值计算结果。 这当然会导致隐私泄露,这可能会或可能不会带来可接受的风险。

一种启发式改进是服务器在揭示任何事物之前首先为每个训练样本排列类别似然向量,从而隐藏哪个可能性对应于哪个类别。 然而,如果例如“健康”通常意味着对类的狭窄分布,而“病态”意味着扩散分布,则这可能影响不大。

另一种方法是引入一个专门的第三台服务器,他只做这个小计算,不会从培训数据中看到其他任何内容,因此不能将标签与样本数据关联起来。 虽然有些东西仍然泄漏,而且这个数量很难解释。

最后,我们也可以用一对一的方法来替代这种“ 一对一”的方法,例如使用S形。 如前所述,这使我们能够在不解密的情况下完全计算预测。 然而,我们仍然需要计算损失,这也可以通过考虑不同的损失函数来完成。

请注意,在稍后使用训练好的网络执行预测时,不会出现这里提到的问题,因为没有损失需要计算,服务器可以在那里简单地跳过softmax层,并让预测的接收者自己根据显示的值计算它:对他来说,这只是一个值如何解释的问题。

转移学习

在这一点上,我们似乎可以实际地训练模型并获得体面的结果。 但通常在CNN中我们可以通过使用转移 学习来获得显着的加速; 事实上,“很少有人从零开始训练自己的卷积网,因为他们没有足够的数据”,并且“总是推荐在实践中使用转换学习”。

我们在这里设置的一个特定应用是,可以使用非敏感公开数据和使用敏感私人数据的微调阶段将培训分为预培训阶段。 例如,在皮肤癌检测器的情况下,研究人员可能选择在公开的一组照片上进行预培训,然后通过提供额外照片让志愿者改进模型。

此外,除了基数的差异之外,两个数据集在主体方面也存在差异的空间,因为CNN倾向于首先将这些数据分解成有意义的子组成部分,其中正在被转移的部分被识别。 换句话说,这种技术足够强大,可以在不同类型的图像上进行预培训而不是进行微调。

回到我们对字符识别的具体使用案例,我们将让“公共”图像为数字0-4 ,“私人”图像为数字5-9 。 作为替代,似乎并不是不合理的,例如字符az用作前者,数字0-9用作后者。

在公共数据集上预训练

除了避免对公开数据集的加密数据进行培训开销外,我们还可以利用更先进的优化器进行培训。 在这里,例如,我们切换回公共图像的Adam优化器,并可以利用其改进的训练时间。 特别是,我们看到我们可以再次降低所需的时代数量。

 ( x_train , y_train ), ( x_test , y_test ) = public_dataset model . compile ( loss = 'categorical_crossentropy' , optimizer = 'adam' , metrics = [ 'accuracy' ]) model . fit ( x_train , y_train , epochs = 1 , batch_size = 32 , verbose = 1 , validation_data = ( x_test , y_test )) 

一旦对此感到满意,服务器只需共享模型参数并继续对私有数据集进行培训。

微调私人数据集

虽然我们现在开始对已经“中途”的模型参数进行加密训练,因此可以预计需要更少的时期,但是如上所述,转移学习的另一个好处是对子组件的识别往往发生在较低层的网络,并且在某些情况下可以按原样使用。 因此,我们现在冻结了要素图层的参数,并将培训工作专注于分类层。

 for layer in feature_layers : layer . trainable = False 

但请注意,我们仍然需要通过这些层面向前运行所有私人培训样本; 唯一的区别是我们在后退步骤中跳过它们,并且没有几个参数需要训练。

然后像以前一样进行训练,尽管现在使用较低的学习率。

 ( x_train , y_train ), ( x_test , y_test ) = private_dataset model . compile ( loss = 'categorical_crossentropy' , optimizer = SGD ( clipnorm = 10000 , clipvalue = 10000 , lr = 0.1 , momentum = 0.0 ), metrics = [ 'accuracy' ]) model . fit ( x_train , y_train , epochs = 5 , batch_size = 32 , verbose = 1 , validation_data = ( x_test , y_test )) 

最后,我们从模拟中的25个时期到5个时期。

预处理

有几个预处理优化可以应用,但我们在这里不会进一步考虑。

首先是将冻结图层的计算移动到输入提供程序,以便它是与服务器共享的拼合图层的输出,而不是图像的像素。 在这种情况下,这些图层被称为执行特征提取 ,我们也可能使用更强大的图层。 但是,如果我们想保持模型专有,那么这就增加了很大的复杂性,因为参数现在必须以某种形式分发给客户。

另一种加速培训的典型方法是首先应用降维技术,如主成分分析 。 这种方法在BSS + '17的加密设置中进行。

修改协议

看过模型之后,我们接下来看看协议:也就是说,理解我们要执行的操作可以帮助加快速度。

特别是,很多计算可以转移到加密提供者,加密提供者的原始材料独立于私人输入,甚至可以扩展到模型。 因此,只要方便且大规模,其计算可以预先完成。

之前回忆说,优化轮次和通信复杂性是相关的,并且这里提出的扩展通常旨在以牺牲额外的本地计算为代价来改进这些扩展。 因此,需要实际的实验来验证它们在具体条件下的好处。

退出

从最简单的图层类型开始,我们注意到这里没有任何与安全计算相关的特殊情况,唯一的办法是确保两个服务器同意在每次训练迭代中丢弃哪些值。 这可以通过简单地同意种子价值来完成。

平均汇集

平均汇集的正向传递只需要一个总分和一个公分母。 因此,它可以通过与公共价值相乘来实现:由于分母是公开的,我们可以很容易地找到它的逆,然后简单地乘以和截断。 同样,反向传递只是一个缩放,因此这两个方向都完全是本地操作。

密集的层

密集层向前和向后传递所需的点积当然可以使用乘法和加法以典型的方式实现。 如果我们想要分别用(m, k)(k, n)形式计算矩阵xy dot(x, y) ,则这需要m * n * k乘法,这意味着我们必须传递相同数量的被屏蔽值。 虽然这些都可以并行发送,所以我们只需要一轮,如果我们允许我们使用另一种预处理的三倍,那么我们可以将通信成本降低一个数量级。

例如,我们模型中的第二个致密层计算(32, 128)(128, 5)矩阵之间的点积。 使用典型的方法需要每批发送32 * 5 * 128 == 22400屏蔽值,但通过使用下面描述的预处理三元组,我们只需发送32 * 128 + 5 * 128 == 4736值,几乎提高了5倍。 对于第一个致密层来说,它甚至更大,即略高于25倍。

同样如前所述 ,诀窍在于确保矩阵中的每个私有值只发送一次掩码。 为了使这个工作,我们需要三元(a, b, c)的随机矩阵ab与适当的形状和c == dot(a, b) 。

 def generate_dot_triple ( x_shape , y_shape ): a = sample_random_tensor ( x_shape ) b = sample_random_tensor ( y_shape ) c = np . dot ( a , b ) % Q return PrivateTensor ( a ), PrivateTensor ( b ), PrivateTensor ( c ) 

给定这样一个三元组,我们可以相反地传达alpha = x - abeta = y - b然后进行局部计算以获得dot(x, y) 。

 class PrivateTensor : ... def dot ( x , y ): if type ( y ) is PublicTensor : shares0 = x . shares0 . dot ( y . values ) % Q shares1 = x . shares1 . dot ( y . values ) % Q return PrivateTensor ( None , shares0 , shares1 ) if type ( y ) is PrivateTensor : a , b , a_dot_b = generate_dot_triple ( x . shape , y . shape ) alpha = ( x - a ) . reconstruct () beta = ( y - b ) . reconstruct () return alpha . dot ( beta ) + \ alpha . dot ( b ) + \ a . dot ( beta ) + \ a_dot_b 

使用这些三元组的安全性遵循与乘法三元组相同的论点:所传递的掩码值完全隐藏了xyc是一个独立的新分享,确保结果不会泄漏任何有关其构成的内容。

请注意, SecureML中使用了这种三元组,这种三元组也提供了允许服务器在没有加密提供程序帮助的情况下生成它们的技术。

卷积

像密集层一样,卷积可以被视为一系列标量乘法或矩阵乘法 ,尽管后者只是在首先将训练样本的张量扩展到具有显着重复的矩阵之后。 毫不奇怪,这导致了通信成本,在这两种情况下都可以通过引入另一种三元组来改善。

作为一个例子,第一卷积使用形状(m, 28, 28, 1) (m, 28, 28, 32) 32滤波器(不包括偏差(m, 28, 28, 1)将具有形状(m, 28, 28, 32) 28,28,1)的张量映射到具有形状(m, 28, 28, 1) 28,28,32)的张量向量)。 对于批量大小为m == 32情况,如果仅使用标量乘法,则表示7,225,344通信元素,如果使用矩阵乘法,则表示226,080 。 然而,由于总共只涉及(32*28*28) + (32*3*3) == 25,376私人值(因为它们只需要添加,所以不再计算偏差),我们看到大致有一个因子9高架。 换句话说,每个私人价值都被屏蔽并被多次发送。 使用新的三元组,我们可以消除这种开销并节省通信成本:对于64位元素,这意味着每批200KB ,而不是分别为1.7MB55MB 。

我们在这里需要的三元组(a, b, c)与点积中使用的三元组相似, ab形状与两个输入相匹配,即(m, 28, 28, 1)(32, 3, 3, 1)c匹配输出形状(m, 28, 28, 32) 。

乙状结肠激活

如前所述 ,我们可以使用9阶多项式来以足够的准确度逼近S形激活函数。 评估这个多项式为私有值x需要计算x的一系列幂,这当然可以通过顺序乘法来完成 - 但这意味着几轮和相应的通信量。

作为替代方案,我们可以再次使用一种新的预处理三元组,使我们能够在一轮中计算所有需要的功率。 如前所述,这些“三元组”的长度并不是固定的,而是等于最高指数,因此例如平方的三元组由aa**2的独立分支组成,而一个用于立方体的三元组由独立的a , a**2a**3 。

一旦我们有了这些x的幂,那么用一个公共系数评估一个多项式就是一个局部加权和。 这一点的安全性来自于三联所有权力都是独立分享的事实。

 def pol_public ( x , coeffs , triple ): powers = pows ( x , triple ) return sum ( xe * ce for xe , ce in zip ( powers , coeffs ) ) 

我们和早期的定点精度有相同的警告,即我们需要更多的空间来获得更高的精度: x**n的精度是n倍,我们希望确保它不会从那以后我们就无法正确解码了。 正如那里所做的那样,我们可以通过引入一个足够大的场P来解决这个问题,我们在计算功率时暂时切换到这个场,这是以两轮额外的通信为代价的。

实际的实验可以显示是否最好留在Q并使用更多的乘法轮次,或者执行切换并支付更大数目的转换和算术。 具体而言,对于低度多项式,前者可能更好。

概念实施证明

没有联网的概念证明实现可用于实验和可重复性。 该代码目前仍在进行中,目前支持从加密特征中训练新的分类器,但不支持对加密图像进行特征提取。 换句话说,它假定输入提供者本身通过特征提取层运行他们的图像,并以加密的形式将结果发送给服务器; 因此,该部分模型的权重目前不保密。 未来的版本将解决这个问题,并允许通过使特征层也可以在加密的数据上运行来直接从图像中进行训练和预测。

 from pond.nn import Sequential , Dense , Sigmoid , Dropout , Reveal , Softmax , CrossEntropy from pond.tensor import PrivateEncodedTensor classifier = Sequential ([ Dense ( 128 , 6272 ), Sigmoid (), Dropout ( . 5 ), Dense ( 5 , 128 ), Reveal (), Softmax () ]) classifier . initialize () classifier . fit ( PrivateEncodedTensor ( x_train_features ), PrivateEncodedTensor ( y_train ), loss = CrossEntropy (), epochs = 3 ) 

该代码被分成几个Python笔记本,并附带一组预计算权重,允许跳过一些步骤:

  • 第一个涉及使用Keras 对公共数据进行预训练 ,并产生用于特征提取的模型。 可以通过使用存储库的预计算权重来跳过此步骤。

  • 第二个应用上述模型对私人数据进行特征提取 ,从而产生用于训练新加密分类器的特征。 在未来的版本中,这将通过首先对数据进行加密来完成。 由于提取的数据太大,此步骤不能跳过。

  • 第三个提取提取的特征并训练一个新的加密分类器 。 这是迄今为止最昂贵的一步,可以通过使用存储库的预计算权重来跳过。

  • 最后,第四个笔记本使用新分类器从新图像执行加密预测 。 目前,特征提取仍然是未加密的。

运行代码是克隆存储库的问题

 $ git clone https://github.com/mortendahl/privateml.git && \ cd privateml/image-analysis/ 

安装依赖关系

 $ pip3 install jupyter numpy tensorflow keras h5py 

启动一个笔记本

 $ jupyter notebook 

并导航到上述四个笔记本中的任意一个。

思考

与往常一样,当以前的想法和问题得到解答时,已经有一批新的等待。

广义三元组

当试图减少交流时,人们也可能想知道能够以预先处理阶段的形式增加多少种三元组。

正如我们多次提到的那样(并且在例如BCG + '17中提出的建议),我们通常试图确保每个私人价值只被发送一次。 所以如果我们例如计算dot(x, y)dot(x, z)那么有一个三元组(r, s, t, u, v)可能是有意义(r, s, t, u, v)其中r用于掩蔽x, s到掩码y , u屏蔽z , tu用于计算结果。 例如,训练期间会发生此模式,在正向传球期间计算的值有时会在后向传球中缓存并重新使用。

也许更重要的是,当我们只用模型进行预测时,即用固定的私人权重进行计算。 在这种情况下,我们只想掩盖一次权重,然后对每个预测重用这些权重 。 这样做意味着我们只需按照流经模型的输入张量按比例地进行屏蔽和通信,而不是像输入张量和权重那样输入张量,就像JVC'18那样 。 更一般地说,我们理想地希望仅根据改变的价值进行沟通,这可以通过使用量身定制的三元组来实现(按摊销意义)。

最后,原则上也可以使用三元组来实现更高级的功能,例如通过一轮通信评估密集层及其激活功能,但这里的大障碍似乎是三重存储和数量的可扩展性重组步骤所需的计算,特别是在使用张量时。

激活功能

一个自然的问题是其他典型激活函数中的哪一个在加密设置中是有效的。 如上所述, SecureML通过临时切换到乱码电路来使用ReLU,并且CryptoDL给出Sigmoid,ReLU和Tanh的低阶多项式近似(使用切比雪夫多项式以获得更好的精度 )。

考虑非典型但更简单的激活函数也是有意义的,例如像CryptoNets中的平方,如果除了简化计算和通信之外别无其他。

乱码电路

尽管上面提到的仅仅是作为安全评估更高级激活函数的一种方式,但实际上也可以将乱码 电路用于更大的部分,包括作为安全计算的主要手段,例如DeepSecure 。

与例如SPDZ相比,此技术具有仅使用恒定数量的通信回合的优点。 缺点是操作现在经常发生在位而不是更大的场元素上,这意味着涉及更多的计算。

精确

围绕联邦学习的许多研究涉及梯度压缩,以节省通信成本。更接近我们的设置,我们有BMMP'17,它使用量化将同态加密应用于深度学习,甚至未加密的 生产就绪系统通常将此技术视为提高学习性能的一种方式

浮点运算

上面我们使用了实数的固定点编码到场元素中,但未加密的深度学习通常使用浮点编码。ABZS'12SPDZ 的参考实现所示,也可以在加密设置中使用后者,显然具有某些操作的性能优势。

图形处理器

由于深度学习通常是出于性能原因在GPU上完成的,因此考虑是否可以通过将其应用于MPC计算来实现类似的加速是自然的。有些工作,关于这个主题的乱码电路存在的,但它似乎如SPDZ的秘密共享设置不太受欢迎。

这里最大的问题可能是GPU上的任意精度算法的成熟度和可用性(但参见例如这个那个),对于大于例如64位的字段元素的计算需要。尽管这里有两件事值得记住:首先,虽然我们计算的值大于本机支持的值,但它们仍然受模数限制; 其次,我们可以通过一个环而不是一个字段来进行安全的计算。

https://mortendahl.github.io/2017/09/19/private-image-analysis-with-mpc/

猜你喜欢

转载自blog.csdn.net/omnispace/article/details/80719430
今日推荐