python - 没有矩阵的神经网络训练异或
问题描述
想建立一个典型的 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() 方法,因为它是我觉得我不完全理解的唯一部分。
编辑:
解决方案
推荐阅读
- html - 活动时删除选择选项中的边框
- javascript - 单击表单提交按钮后,我想显示加载 gif
- string - 如何访问视图持有者中文本视图的值并将其转换为字符串并在 if else 语句中使用以进行比较
- tensorflow - BatchNormalization 如何处理示例?
- maven - 计算有效 POM 时如何防止出现未知打包“捆绑”错误
- arrays - 阵列图案问题以保持一致性
- python - kivy 中的 Play Again 功能
- ios - 从 Swift 或 Objective-C 中的字符串中删除确切的词组
- r - 如何通过grepl根据值提取子集
- django - 使用完成的模板