【问题标题】:How to fix 'TypeError: Object arrays are not currently supported' error in numpy python 3 (matrix multiplication)如何修复 numpy python 3(矩阵乘法)中的“TypeError:当前不支持对象数组”错误
【发布时间】:2019-05-28 01:06:40
【问题描述】:

我正在尝试制作我自己的神经网络“库”(如果你可以这样称呼它的话)供自己使用,因为我正在学习它们。

我编写了这段代码,通过向其提供所需网络的结构来构建可传播的神经网络,并且运行良好。

但是然后当我尝试为模型提供不同数量的节点时,代码 BUGGED

我已经尝试编辑每一层中的节点数量,看看它会把我带到哪里,我发现只有当第一层和第二层的节点数量相同时才会出现这个错误它们,但输出层的数量不同。我还尝试对在纸上输出错误的结构进行矩阵乘法,它给了我一个实际结果(我已经多次检查其合法性)。所以现在我知道它与实践有关,而不是理论。 我认为矩阵乘法显然有问题。

脚本的功能

我必须在问题中包含这些函数,这样您才能更好地了解这段代码的工作原理。

is_iterable()

此函数返回一个布尔值,描述输入是否可迭代

    def is_iterable(x):
        try:
            x[0]
            return True
        except:
            return False

蓝图()

此函数返回输入数组的副本,但将不可迭代的元素更改为 0

    def blueprint(x):
        return [blueprint(e) if is_iterable(e) else 0 for e in x]

构建()

此函数将您所需的神经网络结构模型作为输入,并输出适合的随机偏差和权重,这些偏差和权重被分隔在两个不同的数组中 'randomize()' 函数返回输入数组的副本,但将不可迭代的元素更改为 -1 和 1 之间的随机浮点数。 “build-weights()”函数根据神经网络模型返回随机权重。

    def build(x):

        def randomize(x):
            return np.array([randomize(n) if type(n) is list else random.uniform(-1, 1) for n in x])

        def build_weighs(x):
            y = []
            for i, l in enumerate(x):
                if i == len(x) - 1:
                    break
                y.append([randomize(x[i + 1]) for n in l])
            return np.array(y)

        return (randomize(x), build_weighs(x))

apply_funcs()

此函数将函数列表应用于另一个函数列表,然后返回它们。如果函数列表包含 0,则位于同一位置的另一个列表中的元素将不会应用于任何函数。

    def apply_funcs(x, f):
        y = x
        i = 0
        for xj, fj in zip(x, f):
            if fj == 0:
                y[i] = xj
            else:
                y[i] = fj(xj)
            i += 1
        return y

nn()

这是用于制作神经网络的类。 你可以看到它有一个名为'prop'的函数,用于网络的前向传播。

    class nn:
        def __init__(self, structure, a_funcs=None):
            self.structure = structure
            self.b = np.array(structure[0])
            self.w = np.array(structure[1])
            if a_funcs == None:
                a_funcs = blueprint(self.b)
            self.a_funcs = np.array(a_funcs).

        def prop(self, x):
            y = np.array(x)
            if y.shape != self.b[0].shape:
                raise ValueError("The input needs to be intact with the Input Nodes\nInput: {} != Input Nodes: {}".format(blueprint(y), blueprint(self.b[0])))
            wi = 0
            # A loop through the layers of the neural network
            for i in range(len(self.b)):
                # This if statement is here so that the weights get applied in the right order
                if i != 0:
                    y = np.matmul(y, self.w[wi])
                    wi += 1
                # Applying the biases of layer i to the current information
                y = np.add(y, self.b[i])
                # Applying the activation functions to the current information
                y = apply_funcs(y, self.a_funcs[i])

            return y

定义神经网络结构并传播它

n 包含的结构是一个 3 层网络,分别包含 2 个节点、2 个节点和 3 个节点。

    n = [[0] * 2, [0] * 2, [0] * 3]
    bot = nn(build(n))
    print(bot.prop([1] * 2))

当我这样做时,我希望代码输出一个由三个半随机数组成的数组,如下所示:

    [-0.55889818  0.62762604  0.59222784]

但是我从 numpy 那里得到一个错误:

    File "C:\Users\Black\git\Changbot\oper.py.py", line 78, in prop
        y = np.matmul(y, self.w[wi])
    TypeError: Object arrays are not currently supported

最奇怪的是(正如我之前所说)当第一层和第二层的节点数量相同,但输出层的数量不同时,我才会收到此错误。所有其他时间我都得到了预期的输出......

我现在再次检查了导致此错误的值,除了列表之外我没有看到任何对象。不刷机的时候也是这样。。。 所以我添加了这个 try-except 语句:

    try:
        y = np.matmul(np.array(y), self.w[wi])
    except TypeError:
        print("y:{}\nself.w[wi]:{}".format(y, self.w[wi]))

然后输出:

    y:[1.6888437]
    self.w[wi]:[array([-0.19013173])]

应该有相乘的能力 我什至尝试将值复制粘贴到解释器中并在那里相乘,它在那里工作......

注意:这是一个非常糟糕的测试,因为复制粘贴数组与实际数组没有相同的 DTYPE

    np.matmul([1.6888437], [np.array([-0.19013173])])

上述输出:

    [-0.32110277]

查看答案后

好的。通过在脚本末尾执行此操作,我现在发现对象 dtype 数组位于神经网络的结构中:

    print("STRUCTURE:{}".format(n))

然后输出:

    STRUCTURE:(array([array([0.6888437]), array([ 0.51590881, -0.15885684]),
   array([-0.4821665 ,  0.02254944, -0.19013173])], dtype=object), array([list([array([ 0.56759718, -0.39337455])]),
   list([array([-0.04680609,  0.16676408,  0.81622577]), array([ 0.00937371, -0.43632431,  0.51160841])])],
  dtype=object))

解决错误

我可以从这篇文章的一个答案中了解到 np.array() 尝试创建尽可能高的维度数组,而失败则依赖于 object dtype(或某些输入组合引发错误)。

对象 dtype 是在 build() 函数中创建的,所以我尝试删除其中的所有 np.array() 函数。实际上我从整个脚本中删除了所有这些。 你猜怎么着? 成功了!感谢您的贡献者 1000 次!

顺便说一句新年快乐

【问题讨论】:

  • 似乎其中一个 numpy 数组不包含浮点数而是对象。从堆栈跟踪中找出哪一个并修复它。它还会使代码运行得更快。
  • 我已经检查了导致错误的值,但我似乎找不到它们有什么问题。不过谢谢你提醒我。我现在已将其添加到帖子的最后一部分。
  • 检查np.array(structure[1]) int他的构造函数,我认为它并没有像你想象的那样做,可能是因为structure[1]已经是一个numpy对象数组。
  • 您的复制粘贴测试没有创建对象 dtype 数组。
  • 我解决了!感谢 1000 次的帮助!

标签: python-3.x numpy neural-network matrix-multiplication


【解决方案1】:

关于您的复制粘贴测试:

In [55]: np.matmul([1.6888437], [np.array([-0.19013173])])
Out[55]: array([-0.32110277])

但这不是您的代码所使用的。相反,我们必须制作与 dtype 匹配的数组。

In [59]: x = np.array([1.6888437]); y = np.array([np.array([-0.19013173]),None])[:1]
In [60]: x
Out[60]: array([1.6888437])
In [61]: y
Out[61]: array([array([-0.19013173])], dtype=object)

我使用 None 有趣的业务来强制它创建一个包含数组的对象 dtype,它将 print 作为 [array([-0.19013173])]

现在我得到了你的错误:

In [62]: np.matmul(x,y)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-62-b6212b061655> in <module>()
----> 1 np.matmul(x,y)

TypeError: Object arrays are not currently supported

即使确实与 dot 一样工作

In [66]: np.dot(x,y)
Out[66]: array([-0.32110277])

对象 dtype 数组的计算速度较慢。

此时我不会试图弄清楚为什么你有一个对象 dtype 数组。但我认为你应该避免那些在代码中速度很重要的代码。

如果您从大小不同的数组或列表构造数组,则结果可能是具有较少维数的对象 dtype。 np.array 尝试创建尽可能高的维度数组,如果失败则依赖于 object dtype(或者对于某些输入组合会引发错误)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2015-10-12
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    相关资源
    最近更新 更多