想构建一个典型的XOR监督学习神经网络来帮助我学习。但是,我不想使用矩阵,因为那是每个教程所做的,并且我想确保我真的了解正在发生的事情,而不仅仅是复制和粘贴代码并欺骗自己以为自己理解了。
网络结构为3层。 2个输入,2个隐藏节点和1个输出。
nn = NeuralNet.NN(2, 2, 1)
print("Training: ")
nn.train([0, 0], 0) # (trainingData[0][0][0], trainingData[0][1][0])
for x in range(100):
randomChoice = random.randint(0, 3)
if randomChoice == 0:
nn.train([0, 0], 0)
if randomChoice == 1:
nn.train([0, 1], 1)
if randomChoice == 2:
nn.train([1, 0], 1)
if randomChoice == 3:
nn.train([1, 1], 0)
print("Final Test: ")
nn.inputNeurons = [0, 0]
finalOutput = nn.feedForward()
print(str(finalOutput))
nn.inputNeurons = [0, 1]
finalOutput = nn.feedForward()
print(str(finalOutput))
nn.inputNeurons = [1, 0]
finalOutput = nn.feedForward()
print(str(finalOutput))
nn.inputNeurons = [1, 1]
finalOutput = nn.feedForward()
print(str(finalOutput))
NN类:
inputNeurons = []
hiddenNeurons = []
inputWeights = None
hiddenWeights = None
def __init__(self, inputNeuronsSize, hiddenNeuronsSize, outputNeuronsSize):
for x in range(inputNeuronsSize):
self.inputNeurons.append(0) # initializing all weights to 0
for x in range(hiddenNeuronsSize):
self.hiddenNeurons.append(0) # initializing all weights to 0
self.inputWeights = [[0 for x in range(inputNeuronsSize)] for y in range(hiddenNeuronsSize)]
self.hiddenWeights = [0 for x in range(hiddenNeuronsSize)]
print("IN: "+str(self.inputNeurons))
print("HN: "+str(self.hiddenNeurons))
print("-Weights-")
print(str(self.inputWeights))
print(str(self.hiddenWeights))
def train(self, inputData, target):
learningRate = 0.01
self.inputNeurons = inputData
output = self.feedForward()
print("Training output: "+str(output))
hiddenLayerError = target - output # obtaining error
# print("THEE ERROR: "+str(hiddenLayerError)+" | "+str(output)+" | "+str(target))
hiddenLayerDelta = hiddenLayerError * self.dSigmoid(output) * learningRate # obtaining how much to change hidden layer by
#print("\tHLE: "+str(hiddenLayerError)+" | dSigmoid(output): "+str(self.dSigmoid(output)))
#print("\tHLD: "+str(hiddenLayerDelta))
inputLayerError = 0 # obtaining amount of error the input weights contributed
for i in range(len(self.inputWeights)):
for j in range(len(self.inputWeights[i])):
inputLayerError += hiddenLayerDelta * self.inputWeights[i][j]
inputLayerDot = 0 # dot product of inputs and their weights
for i in range(len(self.inputWeights)):
for j in range(len(self.inputWeights[i])):
inputLayerDot += inputData[i] * self.inputWeights[i][j]
#print(str("ILD: "+str(inputLayerDot)+" | sigmoid(ILD):"+str(self.sigmoid(inputLayerDot))))
#print("")
inputLayerDelta = inputLayerError * self.sigmoid(inputLayerDot) * learningRate # obtaining how much to change input layer
print("\tILE: "+str(inputLayerError)+" | sigmoid(ILD): "+str(self.sigmoid(inputLayerDot)))
#print("ILD: "+str(inputLayerDelta))
# changing input layer weights
for i in range(len(self.inputWeights)):
for j in range(len(self.inputWeights[i])):
self.inputWeights[i][j] += inputLayerDelta #* inputData[j]
# changing hidden layer weights
for i in range(len(self.hiddenWeights)):
self.hiddenWeights[i] += hiddenLayerDelta #* self.hiddenNeurons[i]
print("\tNew Input Weights: "+str(self.inputWeights))
print("\tNew Hidden Weights: "+str(self.hiddenWeights))
def feedForward(self):
#print("lenHN: "+str(len(self.hiddenNeurons)))
for i in range(len(self.hiddenNeurons)):
self.hiddenNeurons[i] = 0
for j in range(len(self.inputWeights[i])):
self.hiddenNeurons[i] += self.inputNeurons[j] * self.inputWeights[i][j]
#print("\t"+str(self.inputNeurons[j])+" | "+str(self.inputWeights[i][j]))
self.hiddenNeurons[i] = self.sigmoid(self.hiddenNeurons[i])
#print("Finished with hidden calcs")
output = 0
for i in range(len(self.hiddenWeights)):
output += self.hiddenNeurons[i] * self.hiddenWeights[i]
#print(str(self.hiddenNeurons[i])+" | "+str(self.hiddenWeights[i]))
def sigmoid(self, x):
return 1 / (1 + math.exp(-x))
def dSigmoid(self, y):
return y * (1 - y)
尽管我对其进行了多次训练,但最终还是得到了这样的输出:
Final Test:
0.5
0.9830156970671703
0.9830156970671703
0.9997015683209125
我几乎可以肯定我的错误在train()方法中,因为这是我不完全理解的唯一部分。
编辑: