np.reshape后转置与直接reshape为转置形状的结果差异原因是什么?
问题1:np.reshape()读取数组元素的顺序是怎样变化的?
NumPy的reshape默认采用**C风格(行优先)**的元素读取/填充顺序:会从数组的最后一个维度开始遍历,依次向前遍历所有维度,把所有元素展开成1维序列后,再按目标形状的同样行优先规则填充成新数组。
你可以通过指定order参数修改顺序,order='F'为列优先(Fortran风格),从第一个维度开始遍历。我们用简单例子验证默认逻辑:
import numpy as np # 形状为(N=2, d1=2, d2=2)的测试数组 x = np.array([[[1,2],[3,4]], [[5,6],[7,8]]]) # 按行优先拉平的结果是 [1,2,3,4,5,6,7,8]
问题2:先reshape为N×D数组再转置,和直接reshape为D×N数组的区别是什么?
首先明确D的定义:对于形状为(N, d1, d2...dn)的数组,D = d1*d2*...*dn,是单样本展开后的特征总数。
两种操作的核心差异是元素的排列逻辑完全不同,我们用上面的测试数组举例说明:
操作1:先reshape(N, D)再转置(你的正确写法)
x_r = x.reshape(x.shape[0], -1) # 得到形状(2,4),值为 [[1,2,3,4], [5,6,7,8]] x_oper1 = x_r.T # 转置后形状(4,2),值为 [[1,5], [2,6], [3,7], [4,8]]
这个操作的逻辑是:先把每个样本的所有特征单独拉平成一行,保证同一行的元素都属于同一个样本;转置后同一列的元素属于同一个样本,同一行的元素是所有样本的同一位置特征,刚好符合全连接层权重梯度的计算要求,所以结果正确。
操作2:直接reshape(D, N)(你的错误写法)
x_oper2 = x.reshape(-1, x.shape[0]) # 得到形状(4,2),值为 [[1,2], [3,4], [5,6], [7,8]]
这个操作是把整个数组的所有元素直接拉平后,按D行N列逐行填充,会把不同样本的元素混到同一行里,完全破坏了「样本-特征」的对应关系,所以计算出来的梯度肯定错误。
内容的提问来源于stack exchange,提问作者Hakan Akgün
相关产品推荐
相关产品推荐

