我最近开始跟随Siraj Raval在YouTube上的深度学习教程进行学习,但在尝试运行我的代码时出现了一个错误。这段代码来自于他系列的第二集,如何制作一个神经网络。当我运行代码时,出现了以下错误:
Traceback (most recent call last):File "C:\Users\dpopp\Documents\Machine Learning\first_neural_net.py", line 66, in <module>neural_network.train(training_set_inputs, training_set_outputs, 10000)File "C:\Users\dpopp\Documents\Machine Learning\first_neural_net.py", line 44, in trainself.synaptic_weights += adjustmentValueError: non-broadcastable output operand with shape (3,1) doesn't match the broadcast shape (3,4)
我多次检查了他的代码,找不到任何差异,甚至尝试从GitHub链接中复制粘贴他的代码。这是我目前的代码:
from numpy import exp, array, random, dotclass NeuralNetwork(): def __init__(self): # 初始化随机数生成器,以便每次运行程序时生成相同的数字 random.seed(1) # 我们模型化一个单一神经元,具有3个输入连接和1个输出连接。 # 我们为3 x 1的矩阵分配随机权重,值在-1到1之间,平均值为0。 self.synaptic_weights = 2 * random.random((3, 1)) - 1 # Sigmoid函数,描述一个S形曲线。 # 我们通过这个函数传递输入的加权和,以将它们归一化为0到1之间。 def __sigmoid(self, x): return 1 / (1 + exp(-x)) # Sigmoid函数的导数。 # 这是Sigmoid曲线的梯度。 # 它表示我们对现有权重的信心程度。 def __sigmoid_derivative(self, x): return x * (1 - x) # 我们通过反复试错来训练神经网络。 # 每次调整突触权重。 def train(self, training_set_inputs, training_set_outputs, number_of_training_iterations): for iteration in range(number_of_training_iterations): # 将训练集通过我们的神经网络(单个神经元)。 output = self.think(training_set_inputs) # 计算误差(期望输出与预测输出之间的差异)。 error = training_set_outputs - output # 将误差乘以输入,再次乘以Sigmoid曲线的梯度。 # 这意味着信心较低的权重会进行更多的调整。 # 这意味着输入为零时,不会导致权重变化。 adjustment = dot(training_set_inputs.T, error * self.__sigmoid_derivative(output)) # 调整权重。 self.synaptic_weights += adjustment # 神经网络思考。 def think(self, inputs): # 将输入通过我们的神经网络(我们的单个神经元)。 return self.__sigmoid(dot(inputs, self.synaptic_weights))if __name__ == '__main__': # 初始化一个单神经元神经网络 neural_network = NeuralNetwork() print("随机初始突触权重:") print(neural_network.synaptic_weights) # 训练集。我们有4个例子,每个例子由3个输入值和1个输出值组成。 training_set_inputs = array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]]) training_set_outputs = array([[0, 1, 1, 0]]) # 使用训练集训练神经网络 # 进行10,000次训练,每次进行小的调整 neural_network.train(training_set_inputs, training_set_outputs, 10000) print("训练后的新突触权重:") print(neural_network.synaptic_weights) # 使用新情况测试神经网络 print("考虑新情况 [1, 0, 0] -> ?:") print(neural_network.think(array([[1, 0, 0]])))
即使我复制粘贴了Siraj那一集中运行正常的相同代码,我仍然得到相同的错误。
我刚刚开始研究人工智能,不明白这个错误的含义。能有人解释一下它是什么意思以及如何修复吗?谢谢!
回答:
将 self.synaptic_weights += adjustment
更改为
self.synaptic_weights = self.synaptic_weights + adjustment
self.synaptic_weights
必须具有形状(3,1),而 adjustment
必须具有形状(3,4)。虽然这些形状是可广播的,但numpy似乎不喜欢尝试将形状为(3,4)的结果赋值给形状为(3,1)的数组
a = np.ones((3,1))b = np.random.randint(1,10, (3,4))>>> aarray([[1], [1], [1]])>>> barray([[8, 2, 5, 7], [2, 5, 4, 8], [7, 7, 6, 6]])>>> a + barray([[9, 3, 6, 8], [3, 6, 5, 9], [8, 8, 7, 7]])>>> b += a>>> barray([[9, 3, 6, 8], [3, 6, 5, 9], [8, 8, 7, 7]])>>> aarray([[1], [1], [1]])>>> a += bTraceback (most recent call last): File "<pyshell#24>", line 1, in <module> a += bValueError: non-broadcastable output operand with shape (3,1) doesn't match the broadcast shape (3,4)
使用numpy.add并指定a
作为输出数组时,也会发生相同的错误
>>> np.add(a,b, out = a)Traceback (most recent call last): File "<pyshell#31>", line 1, in <module> np.add(a,b, out = a)ValueError: non-broadcastable output operand with shape (3,1) doesn't match the broadcast shape (3,4)>>>
需要创建一个新的a
>>> a = a + b>>> aarray([[10, 4, 7, 9], [ 4, 7, 6, 10], [ 9, 9, 8, 8]])>>>