Python手动实现两层神经网络报错求助:维度不匹配问题
错误根源
报错ValueError: shapes (4,2) and (4,1) not aligned: 2 (dim 1) != 4 (dim 0)源于矩阵乘法的维度不匹配,核心问题是输入数据维度定义、矩阵乘法顺序,以及反向传播中的导数计算均存在维度对齐问题。
具体修正步骤
对齐输入输出数据形状
你定义的输入X为(2,4)(2个样本,每个样本4个特征,对应输入层4个神经元),但输出y是(1,4),两者样本数不匹配。需将y调整为(2,1),与样本数对应;若实际需求是4个样本、每个样本2个特征,则调整X为(4,2)并将input_neurons改为2(按你描述输入层4个神经元,前者更合理)。修正前向传播矩阵乘法顺序
输入矩阵X形状为(样本数, 输入特征数),权重矩阵weights为(输入特征数, 输出特征数),正确点乘顺序是np.dot(X, weights),而非X.T。计算结果形状为(样本数, 输出特征数),加偏置时会自动广播,匹配样本输出维度。修正反向传播权重导数计算
权重导数应为输入矩阵转置乘以误差项delta,即np.dot(X.T, delta),得到的导数矩阵形状与weights完全一致,才能正常更新权重。修正偏置导数求和维度
偏置导数需对所有样本的误差项求和,应沿样本维度(axis=0)求和,而非axis=1,确保结果形状与biases一致。
修正后的完整代码
import numpy as np # Step 1: 定义输入输出数据(2个样本,每个样本4个特征) X = np.array([[0, 0, 1, 1], [0, 1, 0, 1]]) # 形状(2,4) y = np.array([[0], [1]]) # 形状(2,1),对应2个样本的输出 # Step 2: 定义神经元数量 input_neurons = 4 output_neurons = 1 # Step 3: 初始化权重和偏置 weights = np.random.rand(input_neurons, output_neurons) # 形状(4,1) biases = np.random.rand(output_neurons, 1) # 形状(1,1) # Step 4: sigmoid激活函数 def sigmoid(x): return 1 / (1 + np.exp(-x)) # Step 5: sigmoid导数 def sigmoid_derivative(x): return sigmoid(x) * (1 - sigmoid(x)) # Step 6: 前向传播 def forward_propagation(X, weights, biases): # X(2,4) * weights(4,1) → (2,1),加上biases(1,1)广播为(2,1) output = sigmoid(np.dot(X, weights) + biases) return output # Step 7: 反向传播 def backward_propagation(X, y, output, weights, biases): error = output - y # 形状(2,1) derivative = sigmoid_derivative(output) # 形状(2,1) delta = error * derivative # 形状(2,1) # X.T(4,2) * delta(2,1) → (4,1),和weights形状一致 weights_derivative = np.dot(X.T, delta) # 沿样本维度求和,得到(1,1),和biases形状一致 biases_derivative = np.sum(delta, axis=0, keepdims=True) return delta, weights_derivative, biases_derivative # Step 8: 训练函数 def train(X, y, weights, biases, epochs, learning_rate): for i in range(epochs): output = forward_propagation(X, weights, biases) delta, weights_derivative, biases_derivative = backward_propagation(X, y, output, weights, biases) weights -= learning_rate * weights_derivative biases -= learning_rate * biases_derivative error = np.mean(np.abs(delta)) print(f"Epoch {i} error: {error:.4f}") # Step 9: 训练网络 epochs = 5000 learning_rate = 0.1 train(X, y, weights, biases, epochs, learning_rate)
额外说明
若实际需求是4个样本(对应y的4个值),需调整X为(4,2)(4个样本,每个样本2个特征),同时将input_neurons改为2,代码逻辑同样适用,仅需修改输入输出数据定义即可。
内容的提问来源于stack exchange,提问作者Stetco Oana

