近似神经网络中的激活函数时发生溢出

时间:2018-12-15 04:31:48

标签: python python-3.x precision approximation

几天来我遇到了一个问题,但尚未找到解决方案。为了进行加密(准确地说是同态加密),我需要在神经网络中使用激活函数的多项式近似。

由于我遇到了这个问题,我的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级)是否正常?那么,这个溢出问题将从何而来?

0 个答案:

没有答案