几天来我遇到了一个问题,但尚未找到解决方案。为了进行加密(准确地说是同态加密),我需要在神经网络中使用激活函数的多项式近似。
由于我遇到了这个问题,我的ANN到目前为止非常简单(只需学习XOR)。我尝试了不同的近似方法(泰勒,最小二乘法,...),但是无论度数(我一直到9级),我的结果都会失败,因为它们在计算过程中会急剧增加。
我的代码如下:
def sigmoid(x, deriv=False):
y = np.copy(x)
(m,n) = np.shape(y)
if (deriv):
for k in range(m):
for i in range(n):
y[k,i] *= (1-y[k,i])
else:
for k in range(m):
for i in range(n):
y[k, i] = (1. / (1 + math.exp(-y[k, i])))
return (y)
def approx(x, deriv=False):
y = np.copy(x)
(m,n) = np.shape(y)
if (deriv==True):
for k in range(m):
for i in range(n):
y[k,i] = (1-y[k,i])
else:
for k in range(m):
for i in range(n):
y[k, i] = (1 / 2) + 1.73496*(y[k, i]/8) - 4.19407*((y[k, i] /8)**3) + 5.43402*((y[k, i] /8)**5) - 2.50739*((y[k, i] /8)**7)
return (y)
################################
X = np.array([[0,0,1],
[0,1,1],
[1,0,1],
[1,1,1]])
y = np.array([[0],[1],[1],[0]])
np.random.seed(1)
syn0 = 2*np.random.random((3,4)) - 1
syn1 = 2*np.random.random((4,1)) - 1
for j in range(10000):
l0 = X
l1 = sigmoid(np.dot(l0,syn0))
l2 = sigmoid(np.dot(l1,syn1))
l2_error = y - l2
l2_delta = l2_error*sigmoid(l2,deriv=True)
l1_error = l2_delta.dot(syn1.T)
l1_delta = l1_error * sigmoid(l1,deriv=True)
syn1 += l1.T.dot(l2_delta)
syn0 += l0.T.dot(l1_delta)
根据该图,这些值似乎离0的距离不远,我的近似值似乎还可以: Least Squares Method approximation
您是否知道这些不断增长的错误(一直到NaN)的来源?
如果有帮助,可以使用最小二乘近似法的7次多项式(如图所示),l1_delta和l2在循环553次迭代后达到NaN(并在此之前展开两步)
编辑:
我刚刚发现了一些非常奇怪的东西。对于我的S形和近似值,当deriv==True
使用相同的定义时,基本上是x = x*(1-x)
。
但是,如果我对两个权重向量syn0和syn1应用近似值,但对前馈部分保留真正的S型(语法上是相同的),那么它将起作用!甚至更奇怪的是,我的近似值给出的结果比S形更好(按顺序:3级比S级好于7级)是否正常?那么,这个溢出问题将从何而来?