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)