numpy 结果是顺序依赖的,当它们不应该是

问题描述

我在 numpy 上实现了一个(玩具)密集神经网络。将三个向量通过 网络,如果我在输出之一的最低有效数字中看到增量 改变输入的顺序。例如,交换第二个和第三个输入:

xta = train_x[:,0:3]                                 # 1st 3 entries in my training set
xtb = np.array([xta[:,0],xta[:,2],1]]).T     # swap 2nd and 3rd entries
sameness = np.array_equal(xta[:,xtb[:,0]) and \
        np.array_equal(xta[:,1],2]) and \
        np.array_equal(xta[:,1])
print(f"Is xta the 'same' as xtb? {sameness}")
print("================================")
yha = nn.forward(xta)
for i in range(yha.shape[0]):
    for j in range(yha.shape[1]):
        print(f"\tyha[{i},{j}] = {yha[i,j]}")
yhb = nn.forward(xtb)
for i in range(yhb.shape[0]):
    for j in range(yhb.shape[1]):
        print(f"\tyhb[{i},{j}] = {yhb[i,j]}")
print("================================")

产生:

Is xta the 'same' as xtb? True
================================
yha[0,0] = 0.7205756079760192
yha[0,1] = 0.8095488210472898
yha[0,2] = 0.8604228442660007
yhb[0,0] = 0.7205756079760192
yhb[0,1] = 0.8604228442660007
yhb[0,2] = 0.8095488210472895
================================

yha[0,1] 的 LSB 不等于 yhb[0,2] 的 LSB。这是一个简单的 NN 实现。前三层是WX+b ==> RELU,最后一层是WX+b ==> SIGMOID,都是在numpy上实现,在GPU上执行。正向传递确实累积状态以用于反向传递,但累积状态不用于计算输出。 (而且,如果是这样,就会有更大的差异。)

所以...在我看来,最低有效位可能会根据执行操作的顺序而摆动。想法?

解决方法

我不熟悉这个库,你从哪里导入nn?也就是说,我认为它看起来完全没问题。我猜测权重有一些随机初始化器,因此切换顺序实际上就像更改随机种子一样。我实际上有点惊讶结果与它们一样接近。您可以通过在没有种子的情况下重新运行相同的代码进行验证,看看您是否看到类似的波动。

,

我喜欢 Frank Yellin 的假设,因此将其改写为答案:

虽然运算相同,运算的输入矩阵也相同,但运算可能会以不同的顺序处理矩阵元素,从而导致最低有效位上的舍入误差不同。