修改神经网络隐藏层节点与层数后准确率不变,是什么原因?
问题排查结果
你观察到的准确率固定、仅随数据集shuffle变动的现象,是代码多处错误共同导致模型完全不拟合数据、始终输出多数类预测的结果,具体原因如下:
1. L2正则化计算逻辑错误
compute_cost函数中的正则项计算完全错误:
if self.lam != 0: reg = (self.lam / (2 * self.m)) for i in range(1, self.L + 1): reg += np.sum(np.dot(self.W[str(i)], self.W[str(i)].T)) self.cost += reg
L2正则的正确计算应为权重矩阵所有元素的平方和,上述代码中np.sum(np.dot(self.W[str(i)], self.W[str(i)].T))的计算结果是正确值的数倍,导致正则损失远大于交叉熵损失。模型优化时优先将所有权重压缩到接近0来降低正则损失,几乎不会拟合数据的分布规律。
2. 特征标准化逻辑错误
数据集预处理阶段的标准化操作错误:
X_train = np.divide((X_train - mean), variance)
标准Z-Score标准化应除以标准差(即方差的平方根),你直接除以方差会导致特征值被过度缩小,反向传播时梯度过小,参数更新几乎停滞,模型无法学习特征与标签的关联。
3. 所有模型均输出多数类预测
你使用的Haberman生存数据集本身存在类别不平衡,多数类(术后存活5年以上)占比约75%~79%。上述两个错误导致模型完全不学习,直接将所有样本预测为多数类,因此准确率等于测试集中多数类的占比:你固定测试集时,多数类样本数固定为44/56=0.7857,和你观察到的固定准确率完全一致;仅当你重新shuffle数据集,测试集的多数类占比发生变化,准确率才会对应变动,和模型结构完全无关。
修复方案
- 修正L2正则计算,将
np.sum(np.dot(self.W[str(i)], self.W[str(i)].T))替换为np.sum(np.square(self.W[str(i)])) - 修正特征标准化逻辑,将分母替换为
np.sqrt(variance) - 初始学习率0.9设置过高,建议调整为0.01~0.1区间
- 可先关闭正则(设置
lam=0)验证模型能否正常拟合训练集,再逐步调整正则参数
内容的提问来源于stack exchange,提问作者Warakorn
相关产品推荐
相关产品推荐

