【问题标题】:ValueError: shapes (2,) and (5,) not aligned: 2 (dim 0) != 5 (dim 0)ValueError:形状(2,)和(5,)未对齐:2(dim 0)!= 5(dim 0)
【发布时间】:2019-06-08 21:01:00
【问题描述】:

在看到神经网络的 youtube 视频后,我尝试使用 numpy 从头开始​​创建一个,但它给了我一个错误,即尺寸错误。我对矩阵或 numpy 不太了解,这就是我无法得到答案的原因。如果有人可以帮助我建立我的网络,我会非常高兴。

import numpy as np

class NeuralNetwork:

    def __init__(self, input_size, hidden_size, output_size):
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size
        self.w1 = np.random.randn(self.input_size, self.hidden_size)
        self.w2 = np.random.randn(self.hidden_size, self.output_size)

    def sigmoid(self, n):
        return 1 / (1 + np.exp(-n))

    def sigmoid_prime(self, n):
        return self.sigmoid(n) * (1 - self.sigmoid(n))

    def propagation(self, x, y):
        # forward 
        hidden1 = np.dot(x, self.w1)
        hidden = self.sigmoid(hidden1)
        output1 = np.dot(hidden, self.w2)
        output = self.sigmoid(output1)
        # backward
        output_error = y - output
        output_delta = output_error * self.sigmoid_prime(output)
        hidden_error = output_delta.dot(self.w2.T)
        hidden_delta = hidden_error*self.sigmoid_prime(hidden)
        self.w1 += x.T.dot(hidden_delta)
        self.w2 += hidden.T.dot(output_delta)

    def predict(self, x):
        hidden1 = np.dot(x, self.w1)
        hidden = self.sigmoid(hidden1)
        output1 = np.dot(hidden, self.w2)
        output = self.sigmoid(output1)
        return(output)


MyNet = NeuralNetwork(2, 5, 1)

for _ in range(500):
    MyNet.propagation(
        np.array([0, 1]),
        np.array([1])
    )

print(MyNet.predict( np.array([0, 1])))

【问题讨论】:

  • 您的dot 呼叫的尺寸不对齐。如果两个参数都是 1d,它们必须匹配才能执行内积。查看dot 以及它如何处理不同的维度,

标签: python numpy matrix neural-network


【解决方案1】:

为方便帮助,请在帖子中指出错误发生在哪里以及是哪一个。

我可以看到您正在尝试执行以下操作(在数学公式中是正确的):

您遇到的问题是,当您的向量只有一个维度时,您正在尝试执行矩阵乘法。要解决这个问题,你应该简单地使用 reshape:

self.w1 + = x.T.reshape(-1, 1).dot(hidden_delta.reshape(1, -1))
self.w2 + = hidden.T.reshape(-1, 1).dot(output_delta.reshape(1, -1))

我建议你在使用 sigmoid 时不要使用 MSE 错误 (|| y - y_pred||^2),而是使用 cross entropy。当您处理概率时,这是一个更好的衡量标准。

交叉熵定义如下:

# cross_entropy = - y log(x) + (1 - y) log(1 - x)
# dcross_entropy/dx = - y / x + (1 - y) / (1 - x)
output_error = (-y / (output + 1e-10)) + ((1 - y) / ( (1 - output) + 1e-10))

编辑

import numpy as np

class NeuralNetwork:

    def __init__(self, input_size, hidden_size, output_size, lr=0.1):
        self.lr = lr
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size
        self.w1 = np.random.randn(self.input_size, self.hidden_size)
        self.w2 = np.random.randn(self.hidden_size, self.output_size)

    def sigmoid(self, n):
        return 1 / (1 + np.exp(-n))

    """def sigmoid_prime(self, n):
        return self.sigmoid(n) * (1 - self.sigmoid(n))"""

    def propagation(self, x, y):
        # forward 
        hidden1 = np.dot(x, self.w1)
        hidden = self.sigmoid(hidden1)
        output1 = np.dot(hidden, self.w2)
        output = self.sigmoid(output1)

        loss = -np.sum(y*np.log(output) + (1 - y)*np.log(1 - output), axis=-1)
        print('Loss:', np.mean(loss))

        # backward
        #output_error = (-y / (output + 1e-10)) + ((1 - y) / ( (1 - output) + 1e-10))
        #output_delta = output_error * output * (1 - output)
        # simplified
        output_delta = - y*(1 - output) + (1 - y)*output
        self.w2 += - self.lr*hidden.T.dot(output_delta) / x.shape[0]

        hidden_error = output_delta.dot(self.w2.T)
        hidden_delta = hidden_error* hidden * (1 - hidden)
        self.w1 += - self.lr*x.T.dot(hidden_delta) / x.shape[0]

    def predict(self, x):
        hidden1 = np.dot(x, self.w1)
        hidden = self.sigmoid(hidden1)
        output1 = np.dot(hidden, self.w2)
        output = self.sigmoid(output1)
        return(output)


MyNet = NeuralNetwork(2, 10, 1)

for _ in range(50000):
    MyNet.propagation(
        np.array([[0, 1], [1, 0], [1, 1], [0, 0]]),
        np.array([[1], [1], [0], [0]])
    )

print(MyNet.predict( np.array([0, 0]).reshape(1, -1)))
print(MyNet.predict( np.array([0, 1]).reshape(1, -1)))
print(MyNet.predict( np.array([1, 0]).reshape(1, -1)))
print(MyNet.predict( np.array([1, 1]).reshape(1, -1)))

【讨论】:

  • 天哪,谢谢。我还在学习矩阵、向量和所有这些微积分的东西,如果你以前从未这样做过,那真的很难:)
  • 别担心,我们都经历过这种情况。您的模型确实“有效”,但唯一失败的是形状。
  • 我讨厌形状 xd
  • 很抱歉打扰您,但您的代码出现了新错误。网络总是给我相同的输出。 pastebin.com/6qGNs7s6
  • 我已经更新了这个问题。我忘记了交叉熵的另一部分。此外,在如何执行 sigmoid 的导数方面存在错误。我还纠正了形状的问题。
猜你喜欢
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 2017-02-11
  • 2020-01-29
  • 2019-03-21
  • 2021-04-25
  • 1970-01-01
  • 2019-10-18
相关资源
最近更新 更多