Python无隐藏层双输出XOR神经网络权重矩阵收缩问题求助
问题修复:双输出XOR神经网络权重矩阵收缩问题
错误原因
核心问题出在权重更新的代码行:
w = w[:, i]-np.transpose(dw)
这行代码直接将整个权重矩阵w替换成了第i列的向量减去dw,导致原本(3,2)的矩阵变成一维数组,后续迭代自然无法正常进行。正确的做法应该是只更新权重矩阵的第i列,而不是替换整个矩阵。
此外还有两处次要问题:
- sigmoid函数的导数计算重复计算了
sigmoid(x),可以直接用已计算的结果简化。 - 训练循环中的前向传播和误差计算维度需要调整,确保和目标值维度匹配。
修复后的完整代码
import numpy as np data = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) data = np.transpose(data) print("Data:") print(data) # 双输出XOR目标:[第一个输出, 第二个输出] target = np.array([[0, 1], [1, 0], [1, 0], [0, 1]]) print("Targets:") print(target) numberOfColumns = data.shape[1] print('Number of columns', numberOfColumns) inputSize = data.shape[0] print('Number of rows', inputSize) # 添加偏置项(全1行) data = np.r_[data, np.ones((1, numberOfColumns), int)] # 修正后的sigmoid函数,导数计算更高效 def sigmoid(x, derivative=False): v = 1 / (1 + np.exp(-x)) if derivative: # 直接用已计算的v,避免重复计算sigmoid v = v * (1 - v) return v def linear(x, derivative=False): v = x if derivative: v = np.ones(x.shape) return v eta = 0.1 # 学习率 epochs = 10000 # 增加迭代次数,确保收敛 afun = sigmoid # 初始权重矩阵(3,2):3个输入(含偏置),2个输出 w = np.array([[0.01, 0.2], [0.1, 0.1], [0.2, 0.01]]) # 训练前的预测与误差计算 y = afun(np.dot(w.T, data)).T e = np.mean(0.5 * np.power(y - target, 2)) print("\nBefore training") print("Weights:") print(w) print("Y:") print(y) print("Error:") print(e) print("\nData after polarization:") print(data) print("\nLearning") for epoch in range(epochs): total_error = 0 for j in range(numberOfColumns): # 当前样本:(3,) 维度 x_sample = data[:, j] # 前向传播:计算两个输出值,(2,) 维度 y_pred = afun(np.dot(x_sample, w)) # 计算误差:(2,) 维度 error = y_pred - target[j] total_error += np.sum(0.5 * np.power(error, 2)) # 遍历每个输出,更新对应权重列 for i in range(error.shape[0]): # 计算梯度:(3,) 维度 dw = eta * error[i] * afun(np.dot(x_sample, w[:, i]), derivative=True) * x_sample # 关键修复:只更新第i列权重,不替换整个矩阵 w[:, i] -= dw # 每1000轮打印一次误差,监控训练进度 if epoch % 1000 == 0: print(f"Epoch {epoch}, Mean Error: {total_error / numberOfColumns:.4f}") # 训练后的预测与误差计算 y = afun(np.dot(w.T, data)).T e = np.mean(0.5 * np.power(y - target, 2)) print("\nAfter training") print("Weights:") print(w) print("Net output:") print(y) print("Error:") print(e)
关键修改点说明
- 权重更新逻辑:将
w = w[:, i]-np.transpose(dw)改为w[:, i] -= dw,确保只修改权重矩阵的指定列,保留矩阵结构。 - sigmoid导数优化:直接使用已计算的
sigmoid(x)值计算导数,避免重复计算提升效率。 - 训练监控:添加每1000轮打印一次误差的逻辑,方便观察训练收敛情况。
- 迭代次数调整:将
epochs从1000增加到10000,确保双输出XOR任务的收敛。 - 代码简化:合并训练前的预测循环,用矩阵运算替代逐样本循环,提升可读性。
内容的提问来源于stack exchange,提问作者Karolina Olszewska
相关产品推荐
相关产品推荐

