自实现前馈神经网络求解XOR时输出相近随机值,照搬参考代码仍训练失效
训练异常的核心根因
- 反向传播循环边界错误,隐藏层权重从未更新。以2-2-1结构的XOR网络为例,整个网络一共仅2组可训练权重(输入层→隐藏层、隐藏层→输出层),原代码写的循环为
for i in range(2, len(self.weights))。由于range函数是左闭右开区间,这个循环的实际执行范围是空集——代码仅能更新输出层的权重和偏置,所有隐藏层、输入层连接的权重从初始化完成后就从未发生过任何变化。这直接解释了你观察到的所有共性现象:不同随机初始化下输出高度相似、权重更新幅度极小、无论调整多少训练轮次都无法学到非线性边界、简单线性分类任务也无法收敛。 - 梯度更新方向完全写反。原代码计算得到损失对权重的梯度后,使用
+=执行权重更新。而梯度下降算法需要沿着损失减小的方向调整参数,也就是需要用当前权重减去“梯度值*学习率”,原写法实际是朝着增大损失的方向调整参数,会直接导致网络要么在最优点附近来回振荡(对应你观察到的误差曲线无明显下降、整体振荡的特征),要么直接跑到sigmoid激活函数的饱和区,把所有输出压到接近0或1的固定值(比如学习率设为100时输出全为e-20级别的极小值,就是权重被反方向调整到让sigmoid输入达到极大值、触发饱和的典型表现)。 - 前向传播存储逻辑冗余。代码前向传播过程仅存储了各层的加权和
z,没有存储各层的激活输出a,导致梯度计算时需要重复调用激活函数,既增加了冗余计算,也提高了逻辑出错的概率。
代码修正方案
- 修正反向传播的循环边界:将原循环代码
for i in range(2, len(self.weights))改为for i in range(2, len(self.weights)+1),确保所有隐藏层的连接权重都能被遍历更新。以2-5-5-1结构的三层权重网络为例,修正后循环会依次遍历更新倒数第二层、最靠近输入层的权重,完成全网络的梯度回传。 - 修正梯度更新的方向符号:将原代码中所有针对权重、偏置的
+=更新逻辑改为-=,确保参数沿着减小损失的方向调整。 - 优化前向传播的存储逻辑:新增激活值列表存储每层的输出,避免重复计算激活函数。在
backprop方法开头初始化激活值集合self.aCollection = [a],每计算完一层的激活值后将其追加到集合中,后续计算权重梯度时直接从集合中取对应层的激活值即可,无需重复调用激活函数计算。 - 合理配置超参数:修正逻辑后,2-2-1结构的网络使用学习率
0.5~1,训练500~1000轮即可稳定收敛到XOR的正确分类结果,无需设置过高的学习率(如学习率100极易触发sigmoid的饱和区,导致训练发散)。 - 优化激活函数的实现:将原
activationPrime中重复定义的lambda逻辑替换为直接复用静态的activation方法,减少重复代码。
参考修正后的核心反向传播片段:
def backprop(self, a, o): o = np.array(o) self.zCollection = [] self.aCollection = [a] # 存储各层激活值,首元素为原始输入 # 前向传播 for w,b in zip(self.weights, self.biases): z = np.matmul(w, a) + b self.zCollection.append(z) a = self.activation(z) self.aCollection.append(a) # 计算输出层误差并更新参数 error = (a - o) * self.activationPrime(self.zCollection[-1]) self.weights[-1] -= np.matmul(error, self.aCollection[-2].T) * self.rate self.biases[-1] -= error * self.rate # 回传更新隐藏层参数 for i in range(2, len(self.weights)+1): error = np.multiply(self.weights[-i+1].T * error, self.activationPrime(self.zCollection[-i])) self.weights[-i] -= np.matmul(error, self.aCollection[-i-1].T) * self.rate self.biases[-i] -= error * self.rate @staticmethod def activationPrime(x): s = NeuralNetwork.activation(x) return s * (1 - s)
内容的提问来源于stack exchange,提问作者Nicojwn
相关产品推荐
相关产品推荐

