2017-10-04 91 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