Python 反向传播算法的收敛性:有多少次迭代?
我是神经网络的新手,这很有趣。我编写了多层神经网络的反向传播基本算法来解决小问题。Python 反向传播算法的收敛性:有多少次迭代?,python,neural-network,Python,Neural Network,我是神经网络的新手,这很有趣。我编写了多层神经网络的反向传播基本算法来解决小问题。 我使用激活函数sigmoid(我想和你们大多数人一样)(x->1/(1+exp(-x))。 我在几个问题上尝试了我的程序: 第一个是异或问题。我取了一个大小为[2,2,1]的三层网络,在前两层中有一个偏置神经元(因此实际上大小更大[3,3,1])。 它尝试了1000组数据(即一对(0/1,0/1)及其XOR作为输出),算法似乎收敛到了0.5的误差:(我发现这很奇怪,所以我把数字提高到10000,因为它没有改变任
我使用激活函数sigmoid(我想和你们大多数人一样)(x->1/(1+exp(-x))。
我在几个问题上尝试了我的程序:
- 第一个是异或问题。我取了一个大小为[2,2,1]的三层网络,在前两层中有一个偏置神经元(因此实际上大小更大[3,3,1])。 它尝试了1000组数据(即一对(0/1,0/1)及其XOR作为输出),算法似乎收敛到了0.5的误差:(我发现这很奇怪,所以我把数字提高到10000,因为它没有改变任何东西,所以它的值为100000(绝望中:p)它是有效的!平均误差降到了0.02以下。有人知道为什么它需要这么多数据才能工作吗
- 第二个是两个数字之间的求和问题(比如4+8=?)。我随机选取了一个[2,5,5,1]网络,在前三层中有一个偏置神经元(因此实际上大小更大[3,6,6,1])。我将100000对数字的训练数据集放在100及其和之下。这一次,错误根本不会收敛,而网络的输出总是返回数字1。您是否已经看到这种情况?这是错误代码吗?(我检查了很多次,但可能是)
随机输入
输入数学
班级网络:
def初始数据(自身):
#权重初始化
self.weights.append([])
self.threshold.append([])
对于范围内的l(1,len(自层)):
n=自身层[l]
阈值L=[]
weightsl=[]
对于范围(n)中的i:
thresholdl.append(-random.random())
权重sli=[]
对于范围内的j(自分层[l-1]):
weightsli.append(random.random()*2-1)
#添加偏向神经元
weightsli.append(thresholdl[-1])
weightsl.append(weightsli)
self.weights.append(weightsl)
self.threshold.append(thresholdl)
定义初始化(自,层):
self.layers=层
自重=[]
self.threshold=[]
self.initdata()
def激活功能(自身,x):
返回1/(1+数学表达式(-x))
def输出层(自身、输入、l):
如果l==0:
返回[输入]
输出=[]
prevoutput=self.outputlayer(输入,l-1)
对于范围内的i(自层[l]):
f=0
对于范围内的k(len(prevoutput[-1]):
f+=自身权重[l][i][k]*输出[-1][k]
f+=自身重量[l][i][1]#偏差重量!
输出追加(自激活函数(f))
返回输出+[输出]
def图层输出(自身、输入):
返回self.outputlayer(输入,len(self.layers)-1)
def最终输出(自身,输入):
返回self.layersoutput(输入)[-1]
def序列(自身、数据、nu):
对于数据中的(输入,最终输出):
输出=自。图层输出(输入)
err=self.errorvector(最终输出,输出[-1])
自调整权重(错误、输出、nu)
def可变权重(自身、错误、输出、nu):
三角洲=[]
对于范围内的i(len(self.layers)):
delta.append([])
tempweights=self.weights.copy()
def changeweightslayer(层):
如果层!=len(自层)-1:
changeweightslayer(层+1)
对于范围内的i(self.layers[layer]):
增量=0
如果层!=len(自层)-1:
增量=输出[层][i]*(1-输出[层][i])*总和([增量[层+1][l]*自权重[层+1][l][i]用于范围内的l(自层[层+1]))
其他:
delta=输出[层][i]*(1-输出[层][i])*err[i]
增量[图层].追加(增量)
对于范围内的k(len(自重[层][i])-1):
tempweights[layer][i][k]+=nu*输出[layer-1][k]*增量
tempweights[layer][i][1]+=nu*delta
变重杀手(1)
self.weights=tempweights
def方形错误(自身、a、b):
返回和([(a[i]-b[i])**2表示范围(len(a))]内的i)
def错误向量(自身、a、b):
返回[a[i]-b[i]表示范围内的i(len(a))]
网络=网络([2,5,5,1])
打印(网络重量)
数据=[]
对于范围内的i(1000000):
比特1=随机。随机范围(100)
比特2=随机。随机范围(100)
data.append(([float(bit1)、float(bit2)]、[float(bit1+bit2)])
网络列车(数据,0.1)
打印(网络重量)
1)如果你发布了你的代码就好了,2)也许这应该发布在代码审查上?请显示你的代码。已添加。感谢各位,我对StackOverflow这个求和问题不太熟悉,这可能是因为您对输出应用了激活函数1/(1+math.exp(-x))?它不能超过1.0,所以最好在输出上有一个线性激活函数。是的,我没有注意到。实际上,求和问题似乎不适合这种神经网络,即使在改变激活函数时也是如此。如果有人对这个问题了解更多?(适应的神经网络类型?)
import random
import math
class Network:
def initdata(self):
#weights initialization
self.weights.append([])
self.threshold.append([])
for l in range(1,len(self.layers)):
n = self.layers[l]
thresholdl = []
weightsl = []
for i in range(n):
thresholdl.append(-random.random())
weightsli = []
for j in range(self.layers[l-1]):
weightsli.append(random.random()*2-1)
#adding bias neurons
weightsli.append(thresholdl[-1])
weightsl.append(weightsli)
self.weights.append(weightsl)
self.threshold.append(thresholdl)
def __init__(self, layers):
self.layers = layers
self.weights = []
self.threshold = []
self.initdata()
def activation_function(self, x):
return 1/(1+math.exp(-x))
def outputlayer(self, input, l):
if l==0:
return [input]
output = []
prevoutput = self.outputlayer(input, l-1)
for i in range(self.layers[l]):
f = 0
for k in range(len(prevoutput[-1])):
f += self.weights[l][i][k]*prevoutput[-1][k]
f += self.weights[l][i][-1] #bias weight !
output.append(self.activation_function(f))
return prevoutput+[output]
def layersoutput(self, input):
return self.outputlayer(input, len(self.layers)-1)
def finaloutput(self, input):
return self.layersoutput(input)[-1]
def train(self, data, nu):
for (input, finaloutput) in data:
output = self.layersoutput(input)
err = self.errorvector(finaloutput, output[-1])
self.changeweights(err, output, nu)
def changeweights(self, err, output, nu):
deltas = []
for i in range(len(self.layers)):
deltas.append([])
tempweights = self.weights.copy()
def changeweightslayer(layer):
if layer != len(self.layers)-1:
changeweightslayer(layer+1)
for i in range(self.layers[layer]):
delta = 0
if layer != len(self.layers)-1:
delta = output[layer][i]*(1-output[layer][i])*sum([deltas[layer+1][l]*self.weights[layer+1][l][i] for l in range(self.layers[layer+1])])
else:
delta = output[layer][i]*(1-output[layer][i])*err[i]
deltas[layer].append(delta)
for k in range(len(self.weights[layer][i])-1):
tempweights[layer][i][k] += nu*output[layer-1][k]*delta
tempweights[layer][i][-1] += nu*delta
changeweightslayer(1)
self.weights = tempweights
def quadraticerror(self, a, b):
return sum([(a[i]-b[i])**2 for i in range(len(a))])
def errorvector(self, a, b):
return [a[i]-b[i] for i in range(len(a))]
network = Network([2, 5, 5, 1])
print(network.weights)
data = []
for i in range(1000000):
bit1 = random.randrange(100)
bit2 = random.randrange(100)
data.append(([float(bit1), float(bit2)], [float(bit1+bit2)]))
network.train(data, 0.1)
print(network.weights)