由于我正在学习有关它们的信息,因此我试图将自己的神经网络“库”(如果可以这样称呼)供自己使用。
我编写了这段代码,通过为它提供所需网络的结构来构成可传播的神经网络,并且效果很好。
但是然后,当我尝试给模型提供不同数量的节点时,代码 BUGGED
我已经尝试编辑每一层中的节点数量,并查看将我带到何处,并且我发现,只有当第一层和第二层中的节点数量相同时,我才会收到此错误它们,但输出层的数量不同。我还尝试对输出错误的结构进行矩阵乘法,这给了我一个实际的结果(我已经多次检查了合法性)。所以现在我知道这与实践有关,与理论无关。 我认为矩阵乘法显然存在问题。
我必须在问题中包括这些功能,因此您可以更好地了解此代码的工作方式。
此函数返回一个布尔值,该布尔值描述输入是否可迭代
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))
此函数将一个函数列表应用于另一个函数列表,然后返回它们。如果功能列表包含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
这是制作神经网络的类。 您可以看到它具有一个名为“ 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 包含一个三层网络结构,该网络分别包含 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()试图创建尽可能高的维数组,但失败的原因在于对象dtype(或某些输入组合)引发错误)。
对象dtype在 build()函数中创建,因此我尝试删除其中的所有 np.array()函数。实际上,我从整个脚本中删除了所有这些内容。 您猜怎么着? 它奏效了!感谢您的贡献者一千次!
顺便说一句 新年快乐
答案 0 :(得分:0)
关于复制粘贴测试:
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
尝试创建尽可能高的维度数组,失败的原因在于对象dtype(或者对于某些输入组合会产生错误)。