仅仅重塑和重塑以及获得转置之间的区别?

2024-09-27 23:21:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在学习CS231作业,我意识到一些令人困惑的事情。当计算梯度时,当我首先重塑x然后得到转置时,我得到了正确的结果

x_r=x.reshape(x.shape[0],-1)
dw= x_r.T.dot(dout)

enter image description here

但是,当我直接重塑为X.T形状时,它不会返回正确的结果

dw = x.reshape(-1,x.shape[0]).dot(dout)

enter image description here

有人能解释一下下面的问题吗

使用np.reforme()获取元素的顺序如何变化? 将(N,d1,d2..dn)形状的数组整形为N,D数组与通过转置获得(D,N)形状的数组的不同之处


Tags: np作业数组事情dot形状梯度shape
1条回答
网友
1楼 · 发布于 2024-09-27 23:21:38

虽然这两种方法都会产生相同形状的数组,但由于numpy读取/写入元素的方式不同,元素的顺序也会有所不同。默认情况下,reshape使用类似C的索引顺序,这意味着读取/写入元素时,最后一个轴索引变化最快,返回到第一个轴索引变化最慢(取自documentation

下面是一个例子,说明这在实践中意味着什么。让我们假设以下数组x

x = np.asarray([[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]])

print(x.shape) # (2, 3, 2)

print(x)
# output
[[[ 1  2]
  [ 3  4]
  [ 5  6]]

 [[ 7  8]
  [ 9 10]
  [11 12]]]

现在,让我们通过以下两种方式重塑此阵列:

opt1 = x.reshape(x.shape[0], -1)
opt2 = x.reshape(-1, x.shape[0])

print(opt1.shape) # outptu: (2, 6)
print(opt2.shape) # output: (6, 2)

print(opt1)
# output:
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]

print(opt2)
# output:
[[ 1  2]
 [ 3  4]
 [ 5  6]
 [ 7  8]
 [ 9 10]
 [11 12]]

reshape首先推断出新数组的形状,然后返回一个视图,在该视图中它以类似C的索引顺序读取元素

为了在opt1上举例说明这一点:由于原始数组x有12个元素,它推断新数组opt1必须具有(2, 6)的形状(因为2*6=12)。现在,reshape返回一个视图,其中:

opt1[0][0] == x[0][0][0] 
opt1[0][1] == x[0][0][1]
opt1[0][2] == x[0][1][0]
opt1[0][3] == x[0][1][1]
opt1[0][4] == x[0][2][0]
opt1[0][5] == x[0][2][1]
opt1[1][0] == x[1][0][0]
...
opt1[1][5] == x[1][2][1]

如上所述,最后一个轴索引变化最快,第一个轴索引变化最慢。同样,将计算opt2的输出

现在可以验证转置第一个选项将产生相同的形状,但元素顺序不同:

opt1 = opt1.T

print(opt1.shape) # output: (6, 2)

print(opt1)
# output: 
[[ 1  7]
 [ 2  8]
 [ 3  9]
 [ 4 10]
 [ 5 11]
 [ 6 12]]

显然,由于元素顺序,这两种方法不会产生相同的数组,即使它们具有相同的形状

相关问题 更多 >

    热门问题