0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于安全多方計算協(xié)議實現(xiàn)私密深度學(xué)習(xí)模型

zhKF_jqr_AI ? 來源:未知 ? 作者:李倩 ? 2018-03-26 11:06 ? 次閱讀

奧胡斯大學(xué)密碼學(xué)PhD、Datadog機器學(xué)習(xí)工程師Morten Dahl介紹了如何基于安全多方計算協(xié)議實現(xiàn)私密深度學(xué)習(xí)模型。

受最近一篇混合深度學(xué)習(xí)和同態(tài)加密的博客的啟發(fā)(見基于Numpy實現(xiàn)同態(tài)加密神經(jīng)網(wǎng)絡(luò)),我覺得使用安全多方計算(secure multi-party computation)替換同態(tài)加密實現(xiàn)深度學(xué)習(xí)會很有趣。

在本文中,我們將從頭構(gòu)建一個簡單的安全多方計算協(xié)議,然后嘗試基于它訓(xùn)練簡單的神經(jīng)網(wǎng)絡(luò)進行基本布爾值計算。本文的相關(guān)代碼可以通過GitHub取得(mortendahl/privateml/simple-boolean-functions)。 假設(shè)有未串通的三方P0、P1、P2,愿意一起進行計算,即訓(xùn)練神經(jīng)網(wǎng)絡(luò)并使用它們進行預(yù)測;然而,出于一些理由,他們不愿意泄露學(xué)習(xí)好的模型。同時假定有些用戶愿意在保持私密的前提下提供訓(xùn)練數(shù)據(jù),有些用戶也有興趣在他們的輸入保持私密的前提下使用學(xué)習(xí)好的模型。

為了能夠做到這一點,我們需要安全地在特定精度下計算有理數(shù);具體而言,對它們做加法和乘法。我們同時需要計算sigmoid函數(shù)1/(1+np.exp(-x)),這一函數(shù)的傳統(tǒng)形式在安全設(shè)定下會導(dǎo)致驚人沉重的運算。因此,我們將依照基于Numpy實現(xiàn)同態(tài)加密神經(jīng)網(wǎng)絡(luò)中的做法,使用多項式逼近sigmoid函數(shù),不過我們會進行一點優(yōu)化。

安全多方計算

同態(tài)加密(Homomorphic Encryption,HE)和安全多方計算(secure Multi-Party Computation,MPC)是現(xiàn)代密碼學(xué)中密切相關(guān)的兩個領(lǐng)域,常?;ハ嗍褂脤Ψ降募夹g(shù)以便解決大致相同的問題:計算接受私密數(shù)據(jù)輸入的函數(shù)而不泄露任何東西,除了(可選)最終輸出。例如,在我們的私密機器學(xué)習(xí)設(shè)定下,兩種技術(shù)可以用來訓(xùn)練我們的模型并進行預(yù)測(不過在HE的情形下,如果數(shù)據(jù)來自使用不同加密鑰的用戶,需要做一些專門的技術(shù)處理)。

就其本身而言,從高層看,HE經(jīng)??梢杂肕PC替換,反之亦然。至少就今天而言,兩者的區(qū)別大致是HE不怎么需要交互,但是需要昂貴的計算,而MPC的計算很廉價,但需要大量交互。換句話說,MCP用兩方或多方間的交互取代了昂貴的計算。

目前而言,這在實踐中提供了更好的性能,以至于人們可以主張MCP是明顯更成熟的技術(shù)——作為這一主張的依據(jù),已經(jīng)存在好幾家公司提供基于MPC的服務(wù)。

定點數(shù)算術(shù)

運算將在一個有限域上進行,因此我們首先需要決定如何將有理數(shù)r表示為域元素,即取自0, 1, ..., Q-1的整數(shù)x(Q為質(zhì)數(shù))。我們將采用典型的做法,根據(jù)固定的精度放大每個有理數(shù),比如,在6位精度的情形下,我們將放大10**6倍,然后將結(jié)果的整數(shù)部分作為定點數(shù)表示。例如,Q = 10000019時,我們得到encode(0.5) == 500000和encode(-0.5) == 10000019 - 500000 == 9500019。

def encode(rational):

upscaled = int(rational * 10**6)

field_element = upscaled % Q

return field_element

def decode(field_element):

upscaled = field_element if field_element <= Q/2else field_element - Q

rational = upscaled / 10**6

return rational

注意,在這一表示下,加法是直截了當?shù)模?r * 10**6) + (s * 10**6) == (r + s) * 10**6,而乘法添加了額外的放大因子,我們需要處理掉以保持精度和避免爆掉數(shù)字:(r * 10**6) * (s * 10**6) == (r * s) * 10**6 * 10**6。

共享和重建數(shù)據(jù)

編碼輸入后,每個用戶接著需要一種和他方共享數(shù)據(jù)的方式,以便用于計算,不過,數(shù)據(jù)需要保持私密。

為了達到這一點,我們需要的配料是秘密共享(secret sharing)。秘密共享將一個值以某種方式分成三份,任何見到少于三份數(shù)據(jù)的人,無法得知關(guān)于值的任何信息;然而,一旦見到所有三份,可以輕易地重建值。

出于簡單性考慮,這里我們將使用復(fù)制秘密共享(replicated secret sharing),其中每方收到不止一份數(shù)據(jù)。具體而言,私密值x分成部分x0、x1、x2,滿足x == x0 + x1 + x2。P0方收到(x0,x1),P1收到(x1,x2),P2收到(x2,x0)。不過本教程中這一點將是隱式的,本文會直接將共享的x儲存為由三部分組成的向量[x0, x1, x2]。

def share(x):

x0 = random.randrange(Q)

x1 = random.randrange(Q)

x2 = (x - x0 - x1) % Q

return [x0, x1, x2]

當兩方以上同意將一個值表露給某人時,他們直接發(fā)送他們所有的部分,從而使重建得以進行。

def reconstruct(shares):

return sum(shares) % Q

然而,如果部分是以下小節(jié)提到的一次或多次安全運算的結(jié)果,出于私密性考慮,我們在重建前進行一次再共享。

def reshare(xs):

Y = [ share(xs[0]), share(xs[1]), share(xs[2]) ]

return [ sum(row) % Q for row in zip(*Y) ]

嚴格來說這是不必要的,但是進行這一步可以更容易地說明為什么協(xié)議是安全的;直觀地,它確保分享的部分是新鮮的,不包含關(guān)于我們用于計算結(jié)果的數(shù)據(jù)的信息。

加法和減法

這樣我們已經(jīng)可以進行安全的加法和減法運算了:每方直接加減其擁有的部分,由于(x0 + x1 + x2) + (y0 + y1 + y2) == (x0 + y0) + (x1 + y1) + (x2 + y2),通過這一操作可以得到x + y的三部分(技術(shù)上說應(yīng)該是reconstruct(x) + reconstruct(y),但是隱式寫法更易讀)。

def add(x, y):

return [ (xi + yi) % Q for xi, yi in zip(x, y) ]

def sub(x, y):

return [ (xi - yi) % Q for xi, yi in zip(x, y) ]

注意這不需要進行任何通訊,因為這些都是本地運算。

乘法

由于每方擁有兩個部分,乘法可以通過類似上面提到的加法和減法的方式進行,即,每方基于已擁有的部分計算一個新部分。具體而言,對下面的代碼中定義的z0、z1、z2而言,我們有x * y == z0 + z1 + z2(技術(shù)上說……)

然而,每方擁有兩個部分的不變性沒有滿足,而像P1直接將z1發(fā)給P0這樣的做法是不安全的。一個簡單的修正是直接將每份zi當成私密輸入共享;這樣就得到了一個正確而安全的共享w(乘積)。

def mul(x, y):

# 本地運算

z0 = (x[0]*y[0] + x[0]*y[1] + x[1]*y[0]) % Q

z1 = (x[1]*y[1] + x[1]*y[2] + x[2]*y[1]) % Q

z2 = (x[2]*y[2] + x[2]*y[0] + x[0]*y[2]) % Q

# 重共享和分發(fā);這里需要通訊

Z = [ share(z0), share(z1), share(z2) ]

w = [ sum(row) % Q for row in zip(*Z) ]

# 將雙精度轉(zhuǎn)回單精度

v = truncate(w)

return v

不過還有一個問題,如前所述,reconstruct(w)具有雙精度:它編碼時使用的放大因子是10**6 * 10**6,而不是10**6。在不安全設(shè)定下,我們本可以通過標準的除法(除以10**6)來修正這一點,然而,由于我們操作的是有限域中的秘密共享元素,這變得不那么直截了當了。

除以一個公開的常量,這里是10**6,足夠簡單:我們直接將部分乘以其域中的逆元素10**(-6)。對某v和u < 10**6,如果reconstruct(w) == v * 10**6 + u,那么乘以逆元素得到v + u * 10**(-6),那么v就是我們要找到的值。在不安全設(shè)定下,殘值u * 10**(-6)足夠小,可以通過取整消除。與此不同,在安全設(shè)定下,基于有限域元素,這一語義丟失了,我們需要通過其他方法擺脫殘值。

一種方法是確保u == 0。具體而言,如果我們事先知道u,那么我們可以不對w作除法,而對w' == (w - share(u))作除法,接著我們就如愿以償,得到v' == v和u' == 0,即,沒有任何殘值。

剩下的問題當然是如何安全地得到u,以便計算w'。具體細節(jié)見CS’10,不過基本的思路是首先在w上加上一個大的掩碼,將掩碼后的值表露給其中一方,使其得以計算掩碼后的u。最后,共享和解掩碼這一掩碼后的值,然后計算w'。

def truncate(a):

# 映射到正值范圍

b = add(a, share(10**(6+6-1)))

# 應(yīng)用僅有P0知道的掩碼,然后重建掩碼后的b,發(fā)送給P1或P2

mask = random.randrange(Q) % 10**(6+6+KAPPA)

mask_low = mask % 10**6

b_masked = reconstruct(add(b, share(mask)))

# 提取低位數(shù)字

b_masked_low = b_masked % 10**6

b_low = sub(share(b_masked_low), share(mask_low))

# 去除低位數(shù)字

c = sub(a, b_low)

# 除法

d = imul(c, INVERSE)

return d

注意上面的imul是本地操作,將每個共享部分乘以公開的常數(shù),這里是10**6的域中逆元素。

安全數(shù)據(jù)類型

最后,我們將以上過程包裹進一個定制的抽象數(shù)據(jù)類型,這樣我們之后表達神經(jīng)網(wǎng)絡(luò)的時候就可以使用NumPy了。

classSecureRational(object):

def __init__(self, secret=None):

self.shares = share(encode(secret)) if secret isnotNoneelse []

return z

def reveal(self):

return decode(reconstruct(reshare(self.shares)))

def __repr__(self):

return"SecureRational(%f)" % self.reveal()

def __add__(x, y):

z = SecureRational()

z.shares = add(x.shares, y.shares)

return z

def __sub__(x, y):

z = SecureRational()

z.shares = sub(x.shares, y.shares)

return z

def __mul__(x, y):

z = SecureRational()

z.shares = mul(x.shares, y.shares)

return z

def __pow__(x, e):

z = SecureRational(1)

for _ in range(e):

z = z * x

return z

基于這一類型,我們可以安全地對這樣的值進行操作:

x = SecureRational(.5)

y = SecureRational(-.25)

z = x * y

assert(z.reveal() == (.5) * (-.25))

此外,需要調(diào)試的時候,我們可以切換為不安全類型而不需要修改其余(神經(jīng)網(wǎng)絡(luò))代碼。再比如,我們可以隔離計數(shù)器的使用,查看進行了多少次乘法,進而讓我們模擬下需要多少通訊。

深度學(xué)習(xí)

這里用“深度學(xué)習(xí)”這個術(shù)語屬于夸夸其談,因為我們只是簡單地擺弄了下基于Numpy實現(xiàn)同態(tài)加密神經(jīng)網(wǎng)絡(luò)中的神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)基本布爾值函數(shù)。

一個簡單函數(shù)

第一個實驗是訓(xùn)練網(wǎng)絡(luò)以識別序列中的第一位。下面的代碼中,X中的四行是輸入的訓(xùn)練數(shù)據(jù),y中相應(yīng)的列是所需輸出。

X = np.array([

[0,0,1],

[0,1,1],

[1,0,1],

[1,1,1]

])

y = np.array([[

0,

0,

1,

1

]]).T

我們將使用同樣的雙層網(wǎng)絡(luò),不過我們會將下面定義的sigmoid逼近函數(shù)作為參數(shù)。secure函數(shù)是一個簡單的輔助函數(shù),將所有值轉(zhuǎn)換為我們的安全數(shù)據(jù)類型。

classTwoLayerNetwork:

def __init__(self, sigmoid):

self.sigmoid = sigmoid

def train(self, X, y, iterations=1000):

# 初始化權(quán)重

self.synapse0 = secure(2 * np.random.random((3,1)) - 1)

# 訓(xùn)練

for i in range(iterations):

# 前向傳播

layer0 = X

layer1 = self.sigmoid.evaluate(np.dot(layer0, self.synapse0))

# 反向傳播

layer1_error = y - layer1

layer1_delta = layer1_error * self.sigmoid.derive(layer1)

# 更新

self.synapse0 += np.dot(layer0.T, layer1_delta)

def predict(self, X):

layer0 = X

layer1 = self.sigmoid.evaluate(np.dot(layer0, self.synapse0))

return layer1

同時,我們將使用原文提出的sigmoid逼近,即標準麥克勞林/泰勒多項式的前五項。出于可讀性考慮,我這里用了一個簡單多項式演算,有待進一步優(yōu)化,比如使用秦九韶算法減少乘法的數(shù)目。

classSigmoidMaclaurin5:

def __init__(self):

ONE = SecureRational(1)

W0 = SecureRational(1/2)

W1 = SecureRational(1/4)

W3 = SecureRational(-1/48)

W5 = SecureRational(1/480)

self.sigmoid = np.vectorize(lambda x: W0 + (x * W1) + (x**3 * W3) + (x**5 * W5))

self.sigmoid_deriv = np.vectorize(lambda x: (ONE - x) * x)

def evaluate(self, x):

return self.sigmoid(x)

def derive(self, x):

return self.sigmoid_deriv(x)

實現(xiàn)了這個之后我們就可以訓(xùn)練和演算網(wǎng)絡(luò)了(細節(jié)見notebook),這里使用了10000次迭代。

# 設(shè)置隨機數(shù)種子以獲得可復(fù)現(xiàn)的結(jié)果

random.seed(1)

np.random.seed(1)

# 選擇逼近

sigmoid = SigmoidMaclaurin5()

# 訓(xùn)練

network = TwoLayerNetwork(sigmoid)

network.train(secure(X), secure(y), 10000)

# 演算預(yù)測

evaluate(network)

注意訓(xùn)練數(shù)據(jù)在輸入網(wǎng)絡(luò)之前是安全共享的,并且學(xué)習(xí)到的權(quán)重從未泄露。預(yù)測同理,只有網(wǎng)絡(luò)的用戶知道輸入和輸出。

Error: 0.00539115

Error: 0.0025606125

Error: 0.00167358

Error: 0.001241815

Error: 0.00098674

Error: 0.000818415

Error: 0.0006990725

Error: 0.0006100825

Error: 0.00054113

Error: 0.0004861775

Layer0 weights:

[[SecureRational(4.974135)]

[SecureRational(-0.000854)]

[SecureRational(-2.486387)]]

Prediction on [000]: 0 (0.50000000)

Prediction on [001]: 0 (0.00066431)

Prediction on [010]: 0 (0.49978657)

Prediction on [011]: 0 (0.00044076)

Prediction on [100]: 1 (5.52331855)

Prediction on [101]: 1 (0.99969213)

Prediction on [110]: 1 (5.51898314)

Prediction on [111]: 1 (0.99946841)

從上面的演算來看,神經(jīng)網(wǎng)絡(luò)確實看起來學(xué)習(xí)到了所要求的函數(shù),在未見輸入上也能給出正確的預(yù)測。

稍微高級些的函數(shù)

在下一個實驗中,神經(jīng)網(wǎng)絡(luò)無法像之前一樣鏡像三個組件的其中一個,從直觀上說,需要計算第一位和第二位的異或(第三位是偏離)。

X = np.array([

[0,0,1],

[0,1,1],

[1,0,1],

[1,1,1]

])

y = np.array([[

0,

1,

1,

0

]]).T

如Numpy實現(xiàn)神經(jīng)神經(jīng)網(wǎng)絡(luò):反向傳播一文所解釋的,使用雙層神經(jīng)網(wǎng)絡(luò)只能給出無意義的結(jié)果,本質(zhì)上是在說“讓我們?nèi)右幻队矌虐伞薄?/p>

Error: 0.500000005

Error: 0.5

Error: 0.5000000025

Error: 0.5000000025

Error: 0.5

Error: 0.5

Error: 0.5

Error: 0.5

Error: 0.5

Error: 0.5

Layer0 weights:

[[SecureRational(0.000000)]

[SecureRational(0.000000)]

[SecureRational(0.000000)]]

Prediction on [000]: 0 (0.50000000)

Prediction on [001]: 0 (0.50000000)

Prediction on [010]: 0 (0.50000000)

Prediction on [011]: 0 (0.50000000)

Prediction on [100]: 0 (0.50000000)

Prediction on [101]: 0 (0.50000000)

Prediction on [110]: 0 (0.50000000)

Prediction on [111]: 0 (0.50000000)

提議的補救措施是在網(wǎng)絡(luò)中引入另一層:

classThreeLayerNetwork:

def __init__(self, sigmoid):

self.sigmoid = sigmoid

def train(self, X, y, iterations=1000):

# 初始權(quán)重

self.synapse0 = secure(2 * np.random.random((3,4)) - 1)

self.synapse1 = secure(2 * np.random.random((4,1)) - 1)

# 訓(xùn)練

for i in range(iterations):

# 前向傳播

layer0 = X

layer1 = self.sigmoid.evaluate(np.dot(layer0, self.synapse0))

layer2 = self.sigmoid.evaluate(np.dot(layer1, self.synapse1))

# 反向傳播

layer2_error = y - layer2

layer2_delta = layer2_error * self.sigmoid.derive(layer2)

layer1_error = np.dot(layer2_delta, self.synapse1.T)

layer1_delta = layer1_error * self.sigmoid.derive(layer1)

# 更新

self.synapse1 += np.dot(layer1.T, layer2_delta)

self.synapse0 += np.dot(layer0.T, layer1_delta)

def predict(self, X):

layer0 = X

layer1 = self.sigmoid.evaluate(np.dot(layer0, self.synapse0))

layer2 = self.sigmoid.evaluate(np.dot(layer1, self.synapse1))

return layer2

然而,如果我們采用之前的方式訓(xùn)練網(wǎng)絡(luò),即使僅僅迭代100次,我們都將面臨一個奇怪的現(xiàn)象:突然之間,誤差、權(quán)重、預(yù)測分數(shù)爆炸了,給出混亂的結(jié)果。

Error: 0.496326875

Error: 0.4963253375

Error: 0.50109445

Error: 4.50917445533e+22

Error: 4.20017387687e+22

Error: 4.38235385094e+22

Error: 4.65389939428e+22

Error: 4.25720845129e+22

Error: 4.50520005372e+22

Error: 4.31568874384e+22

Layer0 weights:

[[SecureRational(970463188850515564822528.000000)

SecureRational(1032362386093871682551808.000000)

SecureRational(1009706886834648285970432.000000)

SecureRational(852352894255113084862464.000000)]

[SecureRational(999182403614802557534208.000000)

SecureRational(747418473813466924711936.000000)

SecureRational(984098986255565992230912.000000)

SecureRational(865284701475152213311488.000000)]

[SecureRational(848400149667429499273216.000000)

SecureRational(871252067688430631387136.000000)

SecureRational(788722871059090631557120.000000)

SecureRational(868480811373827731750912.000000)]]

Layer1 weights:

[[SecureRational(818092877308528183738368.000000)]

[SecureRational(940782003999550335877120.000000)]

[SecureRational(909882533376693496709120.000000)]

[SecureRational(955267264038446787723264.000000)]]

Prediction on [000]: 1 (41452089757570437218304.00000000)

Prediction on [001]: 1 (46442301971509056372736.00000000)

Prediction on [010]: 1 (37164015478651618328576.00000000)

Prediction on [011]: 1 (43504970843252146044928.00000000)

Prediction on [100]: 1 (35282926617309558603776.00000000)

Prediction on [101]: 1 (47658769913438164484096.00000000)

Prediction on [110]: 1 (35957624290517111013376.00000000)

Prediction on [111]: 1 (47193714919561920249856.00000000)

導(dǎo)致這一切的原因很簡單,但也許乍看起來不是那么明顯(至少對我而言)。盡管(前五項)麥克勞林/泰勒逼近sigmoid函數(shù)在前面的網(wǎng)絡(luò)中表現(xiàn)良好,當我們進一步推進時,它完全崩塌了,產(chǎn)生的結(jié)果不僅不精確,而且數(shù)量級也不對。因此很快摧毀了我們可能使用的任何有窮數(shù)字表示,即使在非安全設(shè)定下也是如此,數(shù)字開始溢出了。

技術(shù)上說sigmoid函數(shù)演算的點積變得太大了,就我所知,這意味著神經(jīng)網(wǎng)絡(luò)變得非常自信。就此而言,問題在于我們的逼近不允許神經(jīng)網(wǎng)絡(luò)變得足夠自信,否則精確度會非常糟糕。

我不清楚基于Numpy實現(xiàn)同態(tài)加密神經(jīng)網(wǎng)絡(luò)是如何避免這一問題的,我最好的猜測是較低的初始權(quán)重和alpha更新參數(shù)使它可能在迭代次數(shù)較低的情形下繞過這個坑(看起來是少于300次迭代)。無比歡迎任何關(guān)于這方面的評論。

逼近sigmoid

既然是我們的sigmoid逼近阻礙了我們學(xué)習(xí)更高級的函數(shù),那么很自然地,我們接下來嘗試使用麥克勞林/泰勒多項式的更多項。

如下所示,加到第9項(而不是第5項)確實能稍微增加一點進展,但這點進展遠遠不夠。此外,它塌得更快了。

Error: 0.49546145

Error: 0.4943132225

Error: 0.49390536

Error: 0.50914575

Error: 7.29251498137e+22

Error: 7.97702462371e+22

Error: 7.01752029207e+22

Error: 7.41001528681e+22

Error: 7.33032620012e+22

Error: 7.3022511184e+22

...

或者我們該轉(zhuǎn)而使用更少的項以更好地牽制崩塌?比如,只加到第3項?這確實有點作用,能讓我們在崩塌之前訓(xùn)練500次迭代而不是100次。

Error: 0.4821573275

Error: 0.46344183

Error: 0.4428059575

Error: 0.4168092675

Error: 0.388153325

Error: 0.3619875475

Error: 0.3025045425

Error: 0.2366579675

Error: 0.19651228

Error: 0.1748352775

Layer0 weights:

[[SecureRational(1.455894) SecureRational(1.376838)

SecureRational(-1.445690) SecureRational(-2.383619)]

[SecureRational(-0.794408) SecureRational(-2.069235)

SecureRational(-1.870023) SecureRational(-1.734243)]

[SecureRational(0.712099) SecureRational(-0.688947)

SecureRational(0.740605) SecureRational(2.890812)]]

Layer1 weights:

[[SecureRational(-2.893681)]

[SecureRational(6.238205)]

[SecureRational(-7.945379)]

[SecureRational(4.674321)]]

Prediction on [000]: 1 (0.50918230)

Prediction on [001]: 0 (0.16883382)

Prediction on [010]: 0 (0.40589161)

Prediction on [011]: 1 (0.82447640)

Prediction on [100]: 1 (0.83164009)

Prediction on [101]: 1 (0.83317334)

Prediction on [110]: 1 (0.74354671)

Prediction on [111]: 0 (0.18736629)

然而,誤差和預(yù)測很糟糕,也沒有多少空間供增加迭代次數(shù)了(大約在550次迭代處崩塌)。

插值

作為替代,我們可以放棄標準多項式逼近,轉(zhuǎn)而嘗試在區(qū)間上進行多項式插值。這里主要的參數(shù)是多項式的項數(shù),我們希望它保持在一個較低的值,以提高效率。不過,系數(shù)的精度也是相關(guān)參數(shù)。

# 我們想要逼近的函數(shù)

f_real = lambda x: 1/(1+np.exp(-x))

# 我們想要優(yōu)化的區(qū)間

interval = np.linspace(-10, 10, 100)

# 給定項數(shù),進行多項式插值

degree = 10

coefs = np.polyfit(interval, f_real(interval), degree)

# 降低插值系數(shù)的精度

precision = 10

coefs = [ int(x * 10**precision) / 10**precision for x in coefs ]

# 逼近函數(shù)

f_interpolated = np.poly1d(coefs)

一同繪制標準逼近和插值多項式(紅色曲線)的圖像我們看到了改進的希望:我們無法避免在某點崩塌,但它的崩塌點顯然要大很多。

當然,我們也可以嘗試其他項數(shù)、精度、區(qū)間的組合,如下所示,不過對我們的應(yīng)用而言,上面的參數(shù)組合看起來已經(jīng)足夠了。

現(xiàn)在讓我們回到我們的三層網(wǎng)絡(luò),我們定義一個新的Sigmoid逼近:

classSigmoidInterpolated10:

def __init__(self):

ONE = SecureRational(1)

W0 = SecureRational(0.5)

W1 = SecureRational(0.2159198015)

W3 = SecureRational(-0.0082176259)

W5 = SecureRational(0.0001825597)

W7 = SecureRational(-0.0000018848)

W9 = SecureRational(0.0000000072)

self.sigmoid = np.vectorize(lambda x: \

W0 + (x * W1) + (x**3 * W3) + (x**5 * W5) + (x**7 * W7) + (x**9 * W9))

self.sigmoid_deriv = np.vectorize(lambda x:(ONE - x) * x)

def evaluate(self, x):

return self.sigmoid(x)

def derive(self, x):

return self.sigmoid_deriv(x)

……然后開始訓(xùn)練:

# 設(shè)置隨機數(shù)種子以獲得可復(fù)現(xiàn)的結(jié)果

random.seed(1)

np.random.seed(1)

# 選擇逼近

sigmoid = SigmoidInterpolated10()

# 訓(xùn)練

network = TwoLayerNetwork(sigmoid)

network.train(secure(X), secure(y), 10000)

# 演算預(yù)測

evaluate(network)

現(xiàn)在,盡管我們運行了10000次迭代,沒有發(fā)生崩塌,預(yù)測表現(xiàn)也提升了,只有一個預(yù)測錯誤([0 1 0])。

Error: 0.0384136825

Error: 0.01946007

Error: 0.0141456075

Error: 0.0115575225

Error: 0.010008035

Error: 0.0089747225

Error: 0.0082400825

Error: 0.00769687

Error: 0.007286195

Error: 0.00697363

Layer0 weights:

[[SecureRational(3.208028) SecureRational(3.359444)

SecureRational(-3.632461) SecureRational(-4.094379)]

[SecureRational(-1.552827) SecureRational(-4.403901)

SecureRational(-3.997194) SecureRational(-3.271171)]

[SecureRational(0.695226) SecureRational(-1.560569)

SecureRational(1.758733) SecureRational(5.425429)]]

Layer1 weights:

[[SecureRational(-4.674311)]

[SecureRational(5.910466)]

[SecureRational(-9.854162)]

[SecureRational(6.508941)]]

Prediction on [000]: 0 (0.28170669)

Prediction on [001]: 0 (0.00638341)

Prediction on [010]: 0 (0.33542098)

Prediction on [011]: 1 (0.99287968)

Prediction on [100]: 1 (0.74297185)

Prediction on [101]: 1 (0.99361066)

Prediction on [110]: 0 (0.03599433)

Prediction on [111]: 0 (0.00800036)

注意錯誤情形的分數(shù)不是完全偏離,某種程度上和正確預(yù)測的零值有所不同。再運行5000次迭代看起來不會改善這一點,這時我們已經(jīng)快要崩塌了。

結(jié)語

本文重點介紹了一個簡單的安全多方計算協(xié)議,而沒有顯式地論證開頭提到的安全多方計算比同態(tài)加密更高效。我們看到,使用非?;镜牟僮鲗崿F(xiàn)私密機器學(xué)習(xí)確實是可能的。

也許更需要批評的是我們沒有測量運行協(xié)議需要的通訊量,主要是每次乘法時所需交換的一些消息。基于這一簡單的協(xié)議進行大量計算的話,顯然讓三方通過高速局域網(wǎng)連接會比較好。不過更高級的協(xié)議不僅減少了來回收發(fā)的數(shù)據(jù)量,同時改善了其他性質(zhì),比如回合數(shù)(像亂碼電路(garbled circuits)就可以將回合數(shù)壓到一個小常數(shù))。

最后,本文基本上將協(xié)議和機器學(xué)習(xí)過程看成是正交的,讓后者僅僅以一種黑盒的方式使用前者(除了sigmoid計算)。兩者更好的配合需要兩個領(lǐng)域的專門知識,但可能顯著地提升總體性能。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴

原文標題:基于安全多方計算協(xié)議實現(xiàn)私密深度學(xué)習(xí)模型

文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    labview實現(xiàn)深度學(xué)習(xí),還在用python?

    如何使用labview實現(xiàn)深度學(xué)習(xí)應(yīng)用。ok樣本ng樣本這些圖片的特征是:ok與ok,ng與ng之間都有差異,傳統(tǒng)的方法要實現(xiàn),就需要復(fù)雜的算法編程
    發(fā)表于 07-23 20:33

    深度學(xué)習(xí)模型是如何創(chuàng)建的?

    具有深度學(xué)習(xí)模型的嵌入式系統(tǒng)應(yīng)用程序帶來了巨大的好處。深度學(xué)習(xí)嵌入式系統(tǒng)已經(jīng)改變了各個行業(yè)的企業(yè)和組織。
    發(fā)表于 10-27 06:34

    什么是深度學(xué)習(xí)?使用FPGA進行深度學(xué)習(xí)的好處?

    什么是深度學(xué)習(xí)為了解釋深度學(xué)習(xí),有必要了解神經(jīng)網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)是一種模擬人腦的神經(jīng)元和神經(jīng)網(wǎng)絡(luò)的計算模型
    發(fā)表于 02-17 16:56

    基于深度學(xué)習(xí)模型的點云目標檢測及ROS實現(xiàn)

    近年來,隨著深度學(xué)習(xí)在圖像視覺領(lǐng)域的發(fā)展,一類基于單純的深度學(xué)習(xí)模型的點云目標檢測方法被提出和應(yīng)用,本文將詳細介紹其中一種
    的頭像 發(fā)表于 11-05 16:47 ?1.8w次閱讀

    如何使用深度學(xué)習(xí)實現(xiàn)語音聲學(xué)模型的研究

    的分析識別更是研究的重中之重。近年來深 10 度學(xué)習(xí)模型的廣泛發(fā)展和計算能力的大幅提升對語音識別技術(shù)的提升起到了關(guān)鍵作用。本文立足于語音識別與深度學(xué)
    發(fā)表于 05-09 08:00 ?41次下載
    如何使用<b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>實現(xiàn)</b>語音聲學(xué)<b class='flag-5'>模型</b>的研究

    深度學(xué)習(xí)模型的對抗攻擊及防御措施

    深度學(xué)習(xí)作為人工智能技術(shù)的重要組成部分,被廣泛應(yīng)用于計算機視覺和自然語言處理等領(lǐng)域。盡管深度學(xué)習(xí)在圖像分類和目標檢測等任務(wù)中取得了較好性能,
    發(fā)表于 03-12 13:45 ?75次下載
    <b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>模型</b>的對抗攻擊及防御措施

    安全多方計算協(xié)議MASCOT協(xié)議的的參與方自適應(yīng)變體

    , Keller等提出安全多方計算協(xié)議- MASCOT,其預(yù)處理階段基于不經(jīng)意傳輸協(xié)議而不是類似經(jīng)典SPDZ
    發(fā)表于 04-26 11:37 ?1次下載
    <b class='flag-5'>安全</b><b class='flag-5'>多方</b><b class='flag-5'>計算</b><b class='flag-5'>協(xié)議</b>MASCOT<b class='flag-5'>協(xié)議</b>的的參與方自適應(yīng)變體

    基于曼哈頓距離的隱私安全計算協(xié)議綜述

    安全多方計算問題目前研究的結(jié)果很少,構(gòu)造曼哈頓距離的安全計算協(xié)議在密碼學(xué)中有著重要的理論意義,
    發(fā)表于 04-30 11:21 ?3次下載
    基于曼哈頓距離的隱私<b class='flag-5'>安全</b><b class='flag-5'>計算</b><b class='flag-5'>協(xié)議</b>綜述

    基于多比特全同態(tài)加密的安全多方計算綜述

    安全的三輪多方計算協(xié)議(MPC)。該安全多方計算
    發(fā)表于 06-02 14:16 ?13次下載

    模型為什么是深度學(xué)習(xí)的未來?

    與傳統(tǒng)機器學(xué)習(xí)相比,深度學(xué)習(xí)是從數(shù)據(jù)中學(xué)習(xí),而大模型則是通過使用大量的模型來訓(xùn)練數(shù)據(jù)。
    的頭像 發(fā)表于 02-16 11:32 ?2029次閱讀

    安全多方計算技術(shù)解析

    在討論安全多方計算(下文使用 MPC) 之前,我們先討論安全多方計算的設(shè)定,在MPC 的所有參與
    的頭像 發(fā)表于 12-06 10:58 ?895次閱讀
    <b class='flag-5'>安全</b><b class='flag-5'>多方</b><b class='flag-5'>計算</b>技術(shù)解析

    深度學(xué)習(xí)模型訓(xùn)練過程詳解

    深度學(xué)習(xí)模型訓(xùn)練是一個復(fù)雜且關(guān)鍵的過程,它涉及大量的數(shù)據(jù)、計算資源和精心設(shè)計的算法。訓(xùn)練一個深度學(xué)習(xí)
    的頭像 發(fā)表于 07-01 16:13 ?835次閱讀

    深度學(xué)習(xí)中的模型權(quán)重

    深度學(xué)習(xí)這一充滿無限可能性的領(lǐng)域中,模型權(quán)重(Weights)作為其核心組成部分,扮演著至關(guān)重要的角色。它們不僅是模型學(xué)習(xí)的基石,更是
    的頭像 發(fā)表于 07-04 11:49 ?639次閱讀

    AI大模型深度學(xué)習(xí)的關(guān)系

    人類的學(xué)習(xí)過程,實現(xiàn)對復(fù)雜數(shù)據(jù)的學(xué)習(xí)和識別。AI大模型則是指模型的參數(shù)數(shù)量巨大,需要龐大的計算
    的頭像 發(fā)表于 10-23 15:25 ?161次閱讀

    FPGA加速深度學(xué)習(xí)模型的案例

    FPGA(現(xiàn)場可編程門陣列)加速深度學(xué)習(xí)模型是當前硬件加速領(lǐng)域的一個熱門研究方向。以下是一些FPGA加速深度學(xué)習(xí)
    的頭像 發(fā)表于 10-25 09:22 ?57次閱讀