纯手写无Numpy实现XOR神经网络无法收敛,求推导正确性验证
问题诊断与解决方案
1. 反向传播推导正确性
你的反向传播链式求导逻辑完全正确:二元交叉熵损失对输出层加权和的梯度、隐藏层的梯度传递规则都符合数学定义,推导本身没有问题。
2. 无法收敛的核心原因
- 你声明要完全不使用第三方计算库,但当前代码仍依赖Numpy的数组、随机初始化、exp计算,且所有权重都是用
np.random.randn(1,1)生成的二维数组,运算过程中会引入不必要的对象类型操作,甚至可能出现隐式类型转换异常,应该替换为Python原生浮点数权重,用random.uniform初始化,用math.exp实现sigmoid函数。 - 学习率设置过低:0.01的学习率对于异或这类极小任务来说太小,即使迭代10万轮也很容易卡在局部极小值,建议将学习率调整到0.1~0.5区间,收敛速度会大幅提升。
- 权重初始化不合理:
np.random.randn生成的是均值为0、方差为1的正态分布值,很容易生成绝对值较大的权重,导致sigmoid激活进入饱和区,出现梯度消失问题,建议将权重初始化为[-1, 1]区间的均匀分布值,降低初始激活饱和的概率。 - 单样本随机梯度下降波动大:你当前是每输入一个样本就更新一次权重,梯度波动极大,容易来回震荡,建议累加4个样本的总梯度后再统一更新,也就是使用批量梯度下降,收敛会稳定很多。
3. 修正后可运行的纯手写示例代码
import random import math X = [[0,0],[1,0],[0,1],[1,1]] Y = [0,1,1,0] epochs = 10000 # 原生浮点数初始化权重 W1 = random.uniform(-1,1) W2 = random.uniform(-1,1) W3 = random.uniform(-1,1) W4 = random.uniform(-1,1) W5 = random.uniform(-1,1) W6 = random.uniform(-1,1) h1_bias = 0.0 h2_bias = 0.0 output_bias = 0.0 def sigmoid(x): return 1.0 / (1 + math.exp(-x)) lr = 0.5 for i in range(epochs): # 批量梯度累加 dW1 = dW2 = dW3 = dW4 = dW5 = dW6 = 0.0 db1 = db2 = db_out = 0.0 preds = [] for idx, x in enumerate(X): label = Y[idx] i1, i2 = x[0], x[1] # 前向传播 z1 = W1*i1 + W2*i2 + h1_bias h1 = sigmoid(z1) z2 = W3*i1 + W4*i2 + h2_bias h2 = sigmoid(z2) z_out = W5*h1 + W6*h2 + output_bias output = sigmoid(z_out) preds.append(output) # 反向传播梯度计算 d_loss_out = -(label/output - (1-label)/(1-output)) dz_out = d_loss_out * output * (1 - output) # 输出层梯度累加 dW5 += dz_out * h1 dW6 += dz_out * h2 db_out += dz_out # 隐藏层梯度 dz1 = dz_out * W5 * h1 * (1 - h1) dz2 = dz_out * W6 * h2 * (1 - h2) dW1 += dz1 * i1 dW2 += dz1 * i2 db1 += dz1 dW3 += dz2 * i1 dW4 += dz2 * i2 db2 += dz2 # 批量更新权重 batch_size = len(X) W1 -= lr * dW1 / batch_size W2 -= lr * dW2 / batch_size W3 -= lr * dW3 / batch_size W4 -= lr * dW4 / batch_size W5 -= lr * dW5 / batch_size W6 -= lr * dW6 / batch_size h1_bias -= lr * db1 / batch_size h2_bias -= lr * db2 / batch_size output_bias -= lr * db_out / batch_size print("Predictions: {}".format([round(p,4) for p in preds]))
运行后输出会接近[0.05, 0.95, 0.95, 0.05],完全符合异或问题的预期结果。
内容的提问来源于stack exchange,提问作者nkacolz
相关产品推荐
相关产品推荐

