2017-10-04 98 views
2

我试图用python从零开始实现一个简单的神经网络。这个神经网络只有两个神经元,任务是将输入与输出进行匹配。 (即x = 0→输出= 0,x = 1→输出= 1)具有两个神经元的神经网络

我已经使用了偏导数并尝试使用梯度上升来最大化负损失。 (完整代码如下所示)即使经过超过10000次迭代的训练,输出也不够好。 (我想也许这种损失可能会停留在本地的最大值)。谁能帮我弄清楚我的实现有什么问题吗?

import random 
import numpy as np 
import math 

def sigmoid(x): 
    return 1/(1 + np.exp(-x)) 

def error(d,z): 
    return -0.5 * np.sum(np.power(d-z, 2)) 

# x = input 
##x = np.random.choice((0,1),10000) 
x = np.array([0, 1]) 
# y = desired output 
d = np.copy(x) 

# weights of two neurons 
w = np.random.rand(2) 

# now training using backprop 
gradient = np.random.rand(2) 

iterations = 800 
rate = 5 

k = 1 
for i in xrange(1, iterations + 1): 
    y = sigmoid(w[0] * x) 
    z = sigmoid(w[1] * y) 

    gradient[0] = np.sum(z * w[1] * y * x * (d-z) * (1-y) * (1-z)) 
    gradient[1] = np.sum(y * z * (d-z) * (1-z)) 

    w[0] += gradient[0] * rate 
    w[1] += gradient[1] * rate 

    print "Iteration %d, Error %f, Change %f" % (i, error(d,z), ((gradient[0] * rate) ** 2 + (gradient[1] * rate) ** 2)**0.5) 

    change = ((gradient[0] * rate) ** 2 + (gradient[1] * rate) ** 2)**0.5 

    if change < 0.00001: 
     break 

## now test 
print "1", 
x = 1 
y = sigmoid(w[0]*x) 
z = sigmoid(w[1]*y) 
print z 

print "0", 
x = 0 
y = sigmoid(w[0]*x) 
z = sigmoid(w[1]*y) 
print z 

回答

1

您的简单网络无法学习此功能。

问题是缺乏神经元的偏见。如果我们打电话给你的两个权重W1和W2,你可以看到这个问题:

  • 如果输入为0,然后W1没有什么区别,第一层的输出为0.5和第二层的输出将是sigmoid(0.5 * W2)。要学会输出0值,那么网络必须使W2变大而消极。

  • 如果输入是1,然后调用第一层的输出为N,它必须是0和1之间,第二层的输出将是sigmoid(N * W2)。如果W2大而负,那么最好的网络可以做的是为W1学习一个大的负权重,使得N接近于零。但那最多还是学会输出< 0.5,因为sigmoid(0)0.5

无论选择什么权重,都无法接近[0,1]输入的[0,1]输出。解决方法是在第二层添加至少一个偏倚项,尽管在每个神经元上存在偏倚会更加正常。

+0

谢谢!非常好的解释。 – smb564

1

请参阅在执行反向传播之前对数据进行规范化。可能是帮助..!

+0

感谢您的回复。但我不明白你的意思。我只是使用x = 0和x = 1作为训练数据。 – smb564

+0

对不起..我没有注意到..我的错误... – Devi