Python实现神经网络训练损失不降反升,求排查代码或损失函数问题
问题核心原因
- 输出层设置与标签不匹配:你输出层用了
softmax,输出的是和为1的概率分布,但你的真实标签statsReal每个样本的数值总和为3,不属于合法概率分布,交叉熵损失的计算前提完全不成立,会导致梯度方向错误,损失反而上升。 - 输入未做归一化:输入特征数值范围在2~19之间,乘随机初始化的权重后很容易让
sigmoid激活函数进入饱和区,导数趋近于0,出现梯度消失,参数无法正常更新。 - 损失函数选择错误:你当前的任务本质是回归6个连续的0~1数值,不是多分类任务,用多分类交叉熵损失完全不合适,应该改用MSE(均方误差)损失。
- 训练数据集不合理:5个不同的输入样本对应完全相同的输出标签,数据本身不存在可学习的映射关系,即便其他配置正确也很难拟合出有效模型。
可运行的修改参考代码
import numpy as np # 输入数据做标准化处理 inputData = np.array([[10.0, 5.0, 15.0, 3.0], [9.0, 6.0, 16.0, 4.0], [8.0, 4.0, 17.0, 5.0], [7.0, 3.0, 18.0, 6.0], [6.0, 2.0, 19.0, 7.0]]) # 标准化:减均值除标准差 inputData = (inputData - inputData.mean(axis=0)) / inputData.std(axis=0) statsReal = np.array([[0.0, 0.2, 0.4, 0.6, 0.8, 1.0], [0.0, 0.2, 0.4, 0.6, 0.8, 1.0], [0.0, 0.2, 0.4, 0.6, 0.8, 1.0], [0.0, 0.2, 0.4, 0.6, 0.8, 1.0], [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]]) def sigmoid(x): return 1/(1 + np.exp(-x)) def sigmoid_d_dx(x): return sigmoid(x) * (1 - sigmoid(x)) instances = inputData.shape[0] attributes = inputData.shape[1] hidden_nodes = 4 output_nodes = 6 # 权重初始化改用Xavier,避免激活饱和 wh = np.random.randn(attributes,hidden_nodes) * np.sqrt(1/attributes) bh = np.zeros(hidden_nodes) wo = np.random.randn(hidden_nodes,output_nodes) * np.sqrt(1/hidden_nodes) bo = np.zeros(output_nodes) learningRate = 1e-2 error_cost = [] for epoch in range(2000): # 前向传播 zh = np.dot(inputData, wh) + bh ah = sigmoid(zh) zo = np.dot(ah, wo) + bo ao = sigmoid(zo) # 输出层用sigmoid输出0~1的独立数值 # 反向传播 用MSE损失 dcost_dzo = (ao - statsReal) * sigmoid_d_dx(zo) dcost_wo = np.dot(ah.T, dcost_dzo) dcost_bo = dcost_dzo dcost_dah = np.dot(dcost_dzo, wo.T) dah_dzh = sigmoid_d_dx(zh) dcost_wh = np.dot(inputData.T, dah_dzh * dcost_dah) dcost_bh = dcost_dah*dah_dzh # 参数更新 wh -= learningRate * dcost_wh bh -= learningRate * dcost_bh.sum(axis=0) wo -= learningRate * dcost_wo bo -= learningRate * dcost_bo.sum(axis=0) # MSE损失计算 loss = np.sum((ao - statsReal)**2) if epoch % 200 == 0: print(f"epoch {epoch}, loss: {loss:.4f}") error_cost.append(loss)
额外调整建议
- 如果你的任务确实是多分类任务,需要把真实标签改为one-hot编码,每个样本只有一个类别位置为1,其余为0,再搭配softmax输出和交叉熵损失使用。
- 建议补充更多有差异化的标注样本,当前5个输入对应完全相同输出的数据集无法支撑模型学习有效特征。
- 可以根据收敛情况适当调整学习率,避免步长过大震荡或者步长过小收敛慢。
内容的提问来源于stack exchange,提问作者RGBCoco
相关产品推荐
相关产品推荐

