Python 反向传播和向量形状不匹配
这可能是个愚蠢的问题,但我有点卡住了。我正在尝试用Python编写一个简单的前馈神经网络。我的输入、权重和输出层声明如下:Python 反向传播和向量形状不匹配,python,vector,neural-network,backpropagation,Python,Vector,Neural Network,Backpropagation,这可能是个愚蠢的问题,但我有点卡住了。我正在尝试用Python编写一个简单的前馈神经网络。我的输入、权重和输出层声明如下: self.inp = np.zeros(21) self.weights1 = np.random.rand(self.inp.shape[0],15) self.weights2 = np.random.rand(15, 15) self.layer1 = self.sigmoid(np.dot(self.inp, self.weights1)) self.output
self.inp = np.zeros(21)
self.weights1 = np.random.rand(self.inp.shape[0],15)
self.weights2 = np.random.rand(15, 15)
self.layer1 = self.sigmoid(np.dot(self.inp, self.weights1))
self.output = self.sigmoid(np.dot(self.layer1, self.weights2))
inp = np.zeros((1, 21))
现在我尝试反向传播,但是向量的大小不合适。这是我的反向传播函数:
def backpropagate(self, dice, board):
y = argmax(dice, self.moves)
d_weights2 = np.dot(self.layer1.T, (2*(y - self.output) * self.sigmoidDerivative(self.output)))
d_weights1 = np.dot(self.inp.T, (np.dot(2*(y - self.output) * self.sigmoidDerivative(self.output), self.weights2.T) * self.sigmoidDerivative(self.layer1)))
self.weights1 += d_weights1
self.weights2 += d_weights2
我在计算d_权重1时出错。错误是
ValueError: shapes (21,) and (15,) not aligned: 21 (dim 0) != 15 (dim 0)
我怎样才能使我的向量适合
提前谢谢
编辑:
根据要求,以下是整个课程:
import numpy as np
from TestValues import argmax, testfunctions, zero
class AI:
def __init__(self):
self.moves = []
self.inp = np.zeros(21)
self.weights1 = np.random.rand(self.inp.shape[0],21)
self.weights2 = np.random.rand(21, 15)
self.output = np.zeros(15)
def getPlacement(self, dice, board):
self.feedforward(dice, board)
self.backpropagate(dice, board)
result = self.output
for x in self.moves:
result[x] = -1.
move = np.argmax(result)
self.moves.append(move)
return move
def feedforward(self, dice, board):
i = 0
for x in dice:
self.inp[i] = x
i += 1
for x in board:
self.inp[i] = x
i += 1
self.layer1 = self.sigmoid(np.dot(self.inp, self.weights1))
self.output = self.sigmoid(np.dot(self.layer1, self.weights2))
def backpropagate(self, dice, board):
y = argmax(dice, self.moves)
d_weights2 = np.dot(self.layer1.T, np.dot(2*(y - self.output), self.sigmoidDerivative(self.output)))
d_weights1 = np.dot(self.inp.T, (np.dot(2*(y - self.output) * self.sigmoidDerivative(self.output), self.weights2.T) * self.sigmoidDerivative(self.layer1)))
print(self.weights2.shape)
self.weights1 += d_weights1
self.weights2 += d_weights2
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def sigmoidDerivative(self, x):
return self.sigmoid(x) * (1 - self.sigmoid(x))
问题似乎在于您初始化输入的方式。您正在生成形状数组
(21,)
,而不是(1,21)
。如果您计划一次反向传播多个培训示例,那么在某个时候这可能会变得很明显。此外,尝试调试这些结果矩阵的形状通常是有益的。例如,我的d_权重2
是单个标量。如果你不熟悉矩阵代数,这对理解点积和应该得到的结果很有帮助
简单地说,就是这样初始化:
self.inp = np.zeros(21)
self.weights1 = np.random.rand(self.inp.shape[0],15)
self.weights2 = np.random.rand(15, 15)
self.layer1 = self.sigmoid(np.dot(self.inp, self.weights1))
self.output = self.sigmoid(np.dot(self.layer1, self.weights2))
inp = np.zeros((1, 21))
这为我创造了合理的形状
另外,即使不是CodeReview,我也不得不说一些关于您的代码的事情。不要重复你自己。反向传播时,可以首先计算某个层上的错误,并在两次更新中使用该错误
error=2*(output-y)*d_logistic(output)
如果您计划将网络扩展为任意大小,而不仅仅是两层,那么这也会简化一些事情
还有一件事,您的函数
sigmoid
和sigmoidevirative
在类中没有用处。考虑使它们成为纯函数,而不是类方法。有一个完整的例子是方便的,而不是仅仅从一些被使用但从未显示的类和函数复制粘贴。尽管sigmoidevirative
,这些都是不言自明的。谢谢@Felix。我已经在这里编辑了整个课程。我可以补充一下:一个简单的例子。看游戏位不关心任何问题。谢谢。我删掉了不必要的部分。我想我解决这个问题的方法是点而不是乘以d_权重2。然而,现在我在尝试将d_权重2添加到self.weights 2时遇到了问题。我发布了我的答案,尝试了一下,并让我知道它是如何进行的,我不太理解你所说的乘法。但是我会非常小心地用点积代替乘法,没有好的理由。非常感谢你的回答,以及更好的代码提示。我设法让它工作起来,我的AI现在正忙着玩Yatzy:)@HenrikHillestadLøvold很高兴能帮上忙!