基于Numpy的感知器实现与列表实现结果差异过大问题排查
问题根源:在线更新 vs 批量更新
你的Numpy实现和循环版本的核心差异在于参数更新的时机:
- 循环版本是在线学习模式:每处理一个样本,就立刻用该样本的误差更新一次W和b,后续样本的预测和更新都是基于前一个样本修改后的参数。
- 原Numpy实现是批量更新模式:先计算所有样本的误差,把所有样本的更新量累加后一次性应用到参数上,所有样本的预测都是基于初始参数,完全不符合感知器的标准更新规则。
这种逻辑差异会导致参数的迭代路径完全不同,尤其是在多轮训练后,差异会被不断放大,最终表现为Numpy版本无法收敛、边界混乱。
修正后的Numpy实现
要让Numpy版本和循环版逻辑对齐,只需保持逐个样本更新参数的逻辑,用Numpy操作单个样本即可:
def np_perceptronStep(X, y, W, b, learn_rate = 0.01): diff = [] for i in range(X.shape[0]): # 取单个样本(保持二维数组格式,匹配prediction函数输入) x_i = X[i:i+1] y_hat = np.squeeze(prediction(x_i, W, b)) dif = y[i] - y_hat diff.append(dif) # 用当前样本的误差更新W和b,和循环版逻辑完全一致 W += learn_rate * dif * x_i.T b += learn_rate * dif return W, b, np.array(diff)
关键细节说明
- 原Numpy版本中,
sumX = np.sum(X * diff[..., np.newaxis], axis=0)是把所有样本的x_i * dif_i累加,一次性加到W上,这等价于把所有样本的更新量叠加后应用,而不是逐个样本依次更新。 - 感知器的标准更新规则明确要求每个样本处理后立即更新参数,因为后续样本的预测依赖于更新后的参数,批量更新会破坏这种迭代逻辑。
- 初始的1e-16级差异是浮点数精度误差,但后续因为参数更新逻辑不同,导致预测结果的误差差异越来越大,最终参数差异达到数量级级别。
内容的提问来源于stack exchange,提问作者Skopyk
相关产品推荐
相关产品推荐

