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
相关产品推荐
相关产品推荐

