Numpy数组与向量点积后加法异常:为何得到4x4矩阵而非4x1向量?
问题分析:为什么y + b得到4x4矩阵而非预期的4x1向量?
问题重现
给定以下代码:
import numpy as np def create_weight_matrix(nrows, ncols): """Create a weight matrix with normally distributed random elements.""" return np.random.default_rng().normal(loc=0, scale=1/(nrows*ncols), size=(nrows, ncols)) def create_bias_vector(length): """Create a bias vector with normally distributed random elements.""" return create_weight_matrix(length,1) if __name__ == "__main__": num_samples = 100 num_features = 5 W = create_weight_matrix(4, num_features) b = create_bias_vector(4) x = np.random.rand(num_samples, num_features) y = W.dot(x[1]) print(y.shape) # 输出(4,) t = y + b print(t.shape) # 输出(4,4),不符合预期
核心原因:Numpy广播机制的触发
y是(4,)的一维数组(秩1数组):W形状为(4,5),x[1]是(5,)的一维数组,点积后得到(4,)的一维数组。b是(4,1)的二维数组:create_bias_vector调用create_weight_matrix(length,1),返回形状为(length,1)的二维数组。
当Numpy对形状不匹配的数组执行加法时,会触发广播规则:
(4,)的y会被广播为(4,4)(在第二个维度复制4次)(4,1)的b会被广播为(4,4)(在第一个维度复制4次)
两者相加后就得到了(4,4)的矩阵。
解决方法
有三种常见的修正方式,任选其一即可:
方式1:将y转换为二维数组(保持b的形状不变)
修改y的计算代码,通过reshape或newaxis将其转为(4,1)的二维数组:
y = W.dot(x[1]).reshape(-1, 1) # 或者 y = W.dot(x[1])[:, np.newaxis] t = y + b print(t.shape) # 输出(4,1),符合预期
方式2:将b转换为一维数组(保持y的形状不变)
通过squeeze()或flatten()将b转为(4,)的一维数组:
b = create_bias_vector(4).squeeze() t = y + b print(t.shape) # 输出(4,),若需要(4,1)可再执行t.reshape(-1,1)
方式3:修改create_bias_vector函数,直接返回一维数组
调整函数逻辑,让其生成一维数组而非二维数组:
def create_bias_vector(length): """Create a bias vector with normally distributed random elements.""" return np.random.default_rng().normal(loc=0, scale=1/(length*1), size=length)
此时b为(4,)的一维数组,与y直接相加会得到(4,)的结果,若需要(4,1)可自行转换。
内容的提问来源于stack exchange,提问作者Jimakos
相关产品推荐
相关产品推荐

