从零编写无训练函数的神经网络类 预测结果始终接近1是什么原因
问题原因
你现在的输出恒大于0.7甚至接近1,主要有以下几个错误:
- bias设置过大且逻辑错误
你测试时传入的bias是5.3,而sigmoid函数输入为5的时候,输出就已经达到0.993了。另外你predict函数里的逻辑存在问题:每一轮线性计算后只把加bias的结果存到last_result,但下一轮传入矩阵乘法的还是没加bias的last_inputs,等于所有中间层的bias都没生效,只有最后一层直接加了5.3的bias,导致sigmoid输入值普遍偏大,输出自然接近1。 - 缺少层间激活函数
神经网络的核心就是层间加入非线性激活函数,你现在所有层只有线性变换(矩阵乘+加bias),多层叠加的效果和单层线性模型完全等价,失去了多层网络的表达能力。而且你没有在中间层加类似sigmoid、ReLU之类的激活限制数值范围,多层矩阵乘之后数值会不断累积变大,进一步推高最后sigmoid的输入值。 - 权重初始化不合理
你用np.random.rand初始化权重,生成的是[0,1)区间的全正数值,没有正负分布,也没有做归一化缩放,输入经过多层全正权重相乘后数值会越来越大,进一步加剧了sigmoid输出饱和的问题。 - 仅使用随机权重未训练
你还没有实现训练逻辑,随机初始化的权重本身就没有拟合任何任务逻辑,输出分布异常是正常现象。
修复建议
你可以先做以下修改快速验证效果:
- 先把测试用的bias调整到0或者接近0的小数值,比如0.1
- 修复predict的逻辑,加完bias后赋值给
last_inputs,再给中间层加激活函数,参考代码如下:
def predict(self, inputs): last_inputs = np.array(inputs) for layer_c in range(len(self.layer_schema)): # 线性变换 last_inputs = np.dot(last_inputs, self.weights[layer_c]) + self.bias # 中间层加非线性激活,最后一层如果是分类任务再加sigmoid if layer_c != len(self.layer_schema)-1: # 示例用ReLU激活 last_inputs = np.maximum(last_inputs, 0) return 1 / (1 + np.exp(-last_inputs))
- 权重初始化改成均值为0的分布,比如用
np.random.randn生成标准正态分布,再乘以0.01这类小缩放系数,避免初始数值过大:
self.weights.append((np.random.randn(inputs_count, layers_counts[0]) * 0.01).tolist())
修改后再测试,输出就不会全部集中在0.9以上的区间了。
内容的提问来源于stack exchange,提问作者KiarashRzg
相关产品推荐
相关产品推荐

