NumPy中矩阵形状异常问题:双层神经网络训练时w0形状突变
问题分析与解决方案
你遇到的问题根源在于权重更新步骤中错误地对d_l1进行了转置,导致矩阵乘法维度不匹配,进而让w0的形状在循环中逐渐偏离预期,最终变成异常的(4,4)。
具体原因拆解
我们一步步梳理维度变化:
- 初始状态:
X是(4,3),w0是(3,1),正向传播np.dot(X,w0)得到(4,1)的结果,这部分完全正确。 - 反向传播阶段,
d_l1的形状是(4,1)(和l1、error的形状一致)。 - 你写的更新代码是:
这里w0 = w0 + np.dot(np.transpose(X), d_l1.T)X.T是(3,4),d_l1.T是(1,4)——这两个矩阵无法进行合法的矩阵乘法(矩阵乘法要求第一个矩阵的列数等于第二个矩阵的行数)。NumPy在这种情况下会触发非预期的广播行为,导致第一次更新后w0的形状就偏离了初始的(3,1),后续循环中每次矩阵乘法都会基于错误形状继续计算,最终让w0变成了(4,4)。
修正方案
正确的权重更新应该使用d_l1本身而非其转置,X.T(3,4)和d_l1(4,1)的矩阵乘法结果正好是(3,1),和w0的初始形状完全匹配:
w0 = w0 + np.dot(np.transpose(X), d_l1) # 或者更简洁的写法:w0 += X.T @ d_l1
修正后的完整代码
import numpy as np def sigmoid(x, deriv=False): if deriv == True: return x*(1-x) return 1/(1+np.exp(-x)) X = np.array([[0,0,1], [0,1,1], [1,0,1], [1,1,1]]) y = np.array([0,0,1,1]).T w0 = np.random.normal(0,0.1,(3,1)) print(f"初始w0形状: {w0.shape}") for iter in range(10000): # 前向传播 multiply = np.dot(X,w0) l1 = sigmoid(multiply) # 计算误差 error = y-l1 # 反向传播计算梯度 d_l1 = error * sigmoid(l1, True) # 更新权重:(3,4) @ (4,1) = (3,1),和w0形状一致 w0 += np.dot(X.T, d_l1) print ('训练结果:') print (l1) print(f"最终w0形状: {w0.shape}")
补充说明
你提到使用np.dot(w0.T,X.T)时没有问题,这是因为这个操作得到的是(1,4)的结果(和np.dot(X,w0)的转置一致),对应的权重更新需要调整为w0 += (d_l1.T @ X).T,本质上和上面的正确写法是等价的,只是转置顺序不同而已。
内容的提问来源于stack exchange,提问作者Pratyush Kumar
相关产品推荐
相关产品推荐

