[英]Error in backpropagation python neural net
該死的東西根本不會學。 有時權重似乎變得微不足道。
我沒有玩過不同數量的隱藏層/輸入/輸出,但是該錯誤在不同大小的隱藏層中看起來是一致的。
from __future__ import division
import numpy
import matplotlib
import random
class Net:
def __init__(self, *sizes):
sizes = list(sizes)
sizes[0] += 1
self.sizes = sizes
self.weights = [numpy.random.uniform(-1, 1, (sizes[i+1],sizes[i])) for i in range(len(sizes)-1)]
@staticmethod
def activate(x):
return 1/(1+numpy.exp(-x))
def y(self, x_):
x = numpy.concatenate(([1], numpy.atleast_1d(x_.copy())))
o = [x] #o[i] is the (activated) output of hidden layer i, "hidden layer 0" is inputs
for weight in self.weights[:-1]:
x = weight.dot(x)
x = Net.activate(x)
o.append(x)
o.append(self.weights[-1].dot(x))
return o
def __call__(self, x):
return self.y(x)[-1]
def delta(self, x, t):
o = self.y(x)
delta = [(o[-1]-t) * o[-1] * (1-o[-1])]
for i, weight in enumerate(reversed(self.weights)):
delta.append(weight.T.dot(delta[-1]) * o[-i-2] * (1-o[-i-2]))
delta.reverse()
return o, delta
def train(self, inputs, outputs, epochs=100, rate=.1):
for epoch in range(epochs):
pairs = zip(inputs, outputs)
random.shuffle(pairs)
for x, t in pairs: #shuffle? subset?
o, d = self.delta(x, t)
for layer in range(len(self.sizes)-1):
self.weights[layer] -= rate * numpy.outer(o[layer+1], d[layer])
n = Net(1, 4, 1)
x = numpy.linspace(0, 2*3.14, 10)
t = numpy.sin(x)
matplotlib.pyplot.plot(x, t, 'g')
matplotlib.pyplot.plot(x, map(n, x), 'r')
n.train(x, t)
print n.weights
matplotlib.pyplot.plot(x, map(n, x), 'b')
matplotlib.pyplot.show()
我沒有在您的代碼中尋找特定的錯誤,但是您可以嘗試以下方法來進一步縮小問題范圍嗎? 否則,在大海撈針中找針很麻煩。
1)請嘗試使用真實的數據集來了解預期的結果(例如MNIST)和/或標准化數據,因為如果權重太小,則權重可能會變為NaN。
2)嘗試不同的學習率,並繪制成本函數與時期的關系圖,以檢查您是否正在收斂。 它看起來應該像這樣(請注意,我使用了minibatch學習並對每個紀元平均了minibatch塊)。
3)我看到您使用的是S型激活,您的實現是正確的,但是要使其在數值上更穩定,請從scipy.special
expit(z)
替換為1.0 / (1.0 + np.exp(-z))
(相同功能,但效率更高)。
4)實施梯度檢查。 在這里,您可以將解析解與數值近似的梯度進行比較
或者,產生更精確的梯度近似值的更好方法是計算兩點公式給出的對稱(或居中)差商
PS:如果您有興趣並且發現它有用,那么我可以在此處實現一個有效的香草NumPy神經網絡。
我修好了它! 感謝所有的建議。 我計算出了數字偏式,發現我的o
和delta
正確,但是我乘錯了一些。 這就是為什么我現在使用numpy.outer(d[layer+1], o[layer])
而不是numpy.outer(d[layer], o[layer+1])
。
我也跳過了一層更新。 這就是為什么我將for layer in range(self.hidden_layers)
中for layer in range(self.hidden_layers+1)
更改for layer in range(self.hidden_layers)
for layer in range(self.hidden_layers+1)
。
我還要補充一點,就是我在最初發布之前發現了一個錯誤。 我的輸出層增量不正確,因為我的網絡(有意地)沒有激活最終輸出,但是我的增量卻像是在計算。
主要使用一個隱藏層,一個隱藏單位網進行調試,然后移至2個輸入,每個2個神經元的3個隱藏層,2個輸出模型。
from __future__ import division
import numpy
import scipy
import scipy.special
import matplotlib
#from pylab import *
#numpy.random.seed(23)
def nmap(f, x):
return numpy.array(map(f, x))
class Net:
def __init__(self, *sizes):
self.hidden_layers = len(sizes)-2
self.weights = [numpy.random.uniform(-1, 1, (sizes[i+1],sizes[i])) for i in range(self.hidden_layers+1)]
@staticmethod
def activate(x):
return scipy.special.expit(x)
#return 1/(1+numpy.exp(-x))
@staticmethod
def activate_(x):
s = scipy.special.expit(x)
return s*(1-s)
def y(self, x):
o = [numpy.array(x)] #o[i] is the (activated) output of hidden layer i, "hidden layer 0" is inputs and not activated
for weight in self.weights[:-1]:
o.append(Net.activate(weight.dot(o[-1])))
o.append(self.weights[-1].dot(o[-1]))
# for weight in self.weights:
# o.append(Net.activate(weight.dot(o[-1])))
return o
def __call__(self, x):
return self.y(x)[-1]
def delta(self, x, t):
x = numpy.array(x)
t = numpy.array(t)
o = self.y(x)
#delta = [(o[-1]-t) * o[-1] * (1-o[-1])]
delta = [o[-1]-t]
for i, weight in enumerate(reversed(self.weights)):
delta.append(weight.T.dot(delta[-1]) * o[-i-2] * (1-o[-i-2]))
delta.reverse() #surely i need this
return o, delta
def train(self, inputs, outputs, epochs=1000, rate=.1):
errors = []
for epoch in range(epochs):
for x, t in zip(inputs, outputs): #shuffle? subset?
o, d = self.delta(x, t)
for layer in range(self.hidden_layers+1):
grad = numpy.outer(d[layer+1], o[layer])
self.weights[layer] -= rate * grad
return errors
def rmse(self, inputs, outputs):
return ((outputs - nmap(self, inputs))**2).sum()**.5/len(inputs)
n = Net(1, 8, 1)
X = numpy.linspace(0, 2*3.1415, 10)
T = numpy.sin(X)
Y = map(n, X)
Y = numpy.array([y[0,0] for y in Y])
matplotlib.pyplot.plot(X, T, 'g')
matplotlib.pyplot.plot(X, Y, 'r')
print 'output successful'
print n.rmse(X, T)
errors = n.train(X, T)
print 'tried to train successfully'
print n.rmse(X, T)
Y = map(n, X)
Y = numpy.array([y[0,0] for y in Y])
matplotlib.pyplot.plot(x, Y, 'b')
matplotlib.pyplot.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.