Backpropagation实现问题:神经网络无法正确训练XOR任务
反向传播神经网络代码问题排查与论坛推荐
代码错误分析与修正
你提供的代码无法训练XOR问题,核心存在以下几个逻辑错误:
1. 标签值错误
XOR真值表中[1,1]的正确输出是0,但你代码里的Y标签写为1,这会让网络学习错误的目标,直接导致训练失效。
2. 权重初始化逻辑混乱
原代码中中间层权重矩阵错误地包含了下一层的偏置列,但后续forward传播未对应处理,导致层间维度匹配异常。正确的方式是:每一层权重矩阵维度设为(输入维度+1) × 输出维度,偏置通过给输入添加全1列实现。
3. Forward传播循环重复计算
手动计算第一个隐藏层激活后,又从第0个权重开始遍历所有权重,导致输入层到隐藏层的计算重复,输出层的激活值完全错误。
4. 反向传播误差项维度不匹配
由于forward阶段激活值存储逻辑错误,反向传播时调用的激活值与对应层级不匹配,梯度计算完全失效,权重更新无意义。
修正后的完整代码
import numpy as np class neural_network: def __init__(self, layers, alpha = 0.01): self.alpha = alpha # Sigmoid激活函数 self.activate = lambda x: 1.0 / (1.0 + np.exp(-x)) # Sigmoid导数 self.rate = lambda x: x * (1.0 - x) self.W = [] # 初始化每一层权重:(输入维度+1) × 输出维度,+1对应偏置项 for i in range(len(layers)-1): self.W.append(np.random.randn(layers[i] + 1, layers[i + 1])) def forward(self, I): I = np.atleast_2d(I) self.A = [] # 输入层添加偏置,存入激活列表 current_input = np.c_[I, np.ones(I.shape[0])] self.A.append(current_input) # 处理隐藏层 for w in self.W[:-1]: z = np.matmul(current_input, w) activation = self.activate(z) self.A.append(activation) # 给下一层输入添加偏置 current_input = np.c_[activation, np.ones(activation.shape[0])] # 处理输出层 z = np.matmul(current_input, self.W[-1]) output = self.activate(z) self.A.append(output) return output def error(self, O, Y): return (1 / 2) * np.mean((O - Y) ** 2) def backward(self, I, Y): O = self.forward(I) # 输出层误差 error = O - Y # 输出层误差项:误差 × 激活函数导数 D = [error * self.rate(self.A[-1])] # 反向计算隐藏层误差项 for i in range(len(self.W)-1, 0, -1): # 误差项 = 上一层误差项 × 权重转置 × 当前层激活导数,去掉偏置对应的误差项 d = np.matmul(D[-1], self.W[i].T)[:, :-1] d *= self.rate(self.A[i]) D.append(d) # 反转误差项列表,匹配权重顺序 D = D[::-1] # 更新权重 for i in range(len(self.W)): # 权重更新:-学习率 × (上一层激活的转置 × 当前层误差项) self.W[i] -= self.alpha * np.matmul(self.A[i].T, D[i]) if __name__ == '__main__': # 构建2输入-2隐藏-1输出的网络,适当提高学习率加速收敛 nn = neural_network([2, 2, 1], alpha=0.1) # 正确的XOR真值表标签 I = np.array([[0, 1], [1, 0], [1, 1], [0, 0]]) Y = np.array([[1], [1], [0], [0]]) print("初始误差:", nn.error(nn.forward(I), Y)) for i in range(10000): nn.backward(I, Y) # 每1000轮打印一次误差 if i % 1000 == 0: print(f"第{i}轮误差:", nn.error(nn.forward(I), Y)) O = nn.forward(I) print("\n最终输出:") print(O) print("最终误差:", nn.error(O, Y))
AI专业论坛推荐
- Reddit Machine Learning板块:覆盖基础算法、深度学习框架、行业应用等全领域,用户群体包含学生、研究员和工程师,能获得多元解答。
- 机器学习中文社区:国内专注AI技术的论坛,有大量中文资源和本土化实践经验,适合中文用户交流。
- AI研习社:聚焦AI技术落地与实战项目,提供丰富教程、竞赛和技术讨论,适合偏向实践的开发者。
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

