You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XOR门预测神经网络训练异常:损失值居高不下求原因排查

嘿,我帮你排查出几个关键问题,正是这些问题导致你的loss一直卡在0.6左右(这个数值其实是随机猜测的交叉熵损失,相当于模型根本没学到东西)。咱们一步步来看:

核心问题分析

1. 交叉熵损失函数的符号错误

这是最致命的问题!你写的损失计算代码:

J = np.sum(-train_Y * np.log(A2) + (train_Y-1) * np.log(1-A2)) / m

这里的(train_Y-1)应该改成(1 - train_Y)。正确的二分类交叉熵损失公式是:
$$J = -\frac{1}{m}\sum\left[Y\log(A) + (1-Y)\log(1-A)\right]$$
你现在的写法把后半部分的符号完全搞反了,这会导致梯度更新的方向彻底错误——模型不仅不会朝着降低loss的方向学习,反而可能在往错误的方向优化,自然loss一直降不下来。

2. 学习率的混乱使用

你明明定义了learning_rate = 0.1,但实际更新参数时却用了硬编码的0.03。虽然0.03本身不是不能用,但这种不一致很容易混淆。更重要的是,对于XOR这种简单任务,0.03的学习率偏慢,换成你定义的0.1甚至0.5,配合正确的损失函数,训练速度会快很多。

3. 不必要的超大迭代次数

你设置了1000000次迭代,但其实如果前面的问题修正了,几千次迭代就能让loss降到接近0。这么大的迭代次数不仅浪费资源,还可能导致后期模型出现震荡。

4. 无关但需要注意的小问题

  • matplotlib导入错误:import matplotlib as plt应该改成import matplotlib.pyplot as plt,不然之后想画图会报错。
  • 变量S定义了但没用到,可以直接删掉。
修正后的完整代码
import numpy as np
import matplotlib.pyplot as plt

# 数据集(维度保持正确:(特征数, 样本数))
train_X = np.array([[0,0],[0,1],[1,0],[1,1]]).T
train_Y = np.array([[0,1,1,0]])
test_X = np.array([[0,0],[0,1],[1,0],[1,1]]).T
test_Y = np.array([[0,1,1,0]])

learning_rate = 0.1
S0, S1, S2 = 2, 5, 1
m = 4  # 样本数量

# 参数初始化
w1 = np.random.randn(S1, S0) * 0.01
b1 = np.zeros((S1, 1))
w2 = np.random.randn(S2, S1) * 0.01
b2 = np.zeros((S2, 1))

def sigmoid(z):
    return 1/(1+np.exp(-z))

def sigmoid_derivative(z):
    return sigmoid(z)*(1-sigmoid(z))

# 训练循环(减少迭代次数)
loss_history = []
for i in range(10000):
    # 前向传播
    Z1 = np.dot(w1, train_X) + b1
    A1 = sigmoid(Z1)
    Z2 = np.dot(w2, A1) + b2
    A2 = sigmoid(Z2)
    
    # 修正后的损失计算
    J = -np.sum(train_Y * np.log(A2) + (1 - train_Y) * np.log(1 - A2)) / m
    loss_history.append(J)
    
    # 反向传播
    dZ2 = A2 - train_Y
    dW2 = np.dot(dZ2, A1.T) / m
    dB2 = np.sum(dZ2, axis=1, keepdims=True) / m
    
    dZ1 = np.dot(w2.T, dZ2) * sigmoid_derivative(Z1)
    dW1 = np.dot(dZ1, train_X.T) / m
    dB1 = np.sum(dZ1, axis=1, keepdims=True) / m
    
    # 参数更新(使用定义好的learning_rate)
    w1 -= learning_rate * dW1
    w2 -= learning_rate * dW2
    b1 -= learning_rate * dB1
    b2 -= learning_rate * dB2
    
    # 每1000次打印一次loss
    if i % 1000 == 0:
        print(f"Iteration {i}, Loss: {J:.4f}")

# 测试模型效果
predictions = (sigmoid(np.dot(w2, sigmoid(np.dot(w1, test_X) + b1)) + b2) > 0.5).astype(int)
print("\n测试结果:")
print("输入:\n", test_X.T)
print("预测输出:\n", predictions.T)
print("真实输出:\n", test_Y.T)

# 绘制loss变化曲线
plt.plot(loss_history)
plt.xlabel("Iteration")
plt.ylabel("Loss")
plt.title("Training Loss Curve")
plt.show()

修正后你会看到loss快速下降,最终接近0,模型也能完美预测XOR的四个样本。

内容的提问来源于stack exchange,提问作者user9761720

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:28:03