You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复无类实现神经网络作业训练时权重更新输出NaN的问题

代码问题排查方向(按影响优先级排序)

1. 反向传播逻辑和网络结构不匹配

你当前实现的是没有隐藏层的单神经元全连接网络,前向计算链路为:
输入形状(5,3)的x → 点乘形状(3,1)的w得到预激活z(5,1) → 对z做sigmoid得到输出yhat(5,1)
整条链路没有中间隐藏层,完全不需要做跨层的误差传递计算,但你在反向传播中套用了多层网络的逻辑,写了const = np.dot(dz, w.T) 这一步(该步骤是带隐藏层网络计算隐藏层误差时才需要的操作),这是后续所有异常的起点。

2. 激活函数导数的入参错误,直接触发数值溢出

你定义的deriv(x)是sigmoid的导数实现,其推导公式为h*(1-h),入参应该是sigmoid激活后的输出值h,但你全程把未经过激活的预激活值z直接传入了deriv函数。
随着迭代推进,一旦z的绝对值超过1,z*(1-z) 就会变成绝对值持续增大的数,顺着计算链路不断扩散,最终触发数值溢出为inf,后续权重更新的运算就会把溢出值变成nan。

3. 隐式广播导致的形状错位不会直接报错,但会持续放大数值偏差

按你当前代码的计算逻辑,最终算出来的梯度dJdw 形状是(3,3),但初始权重w的形状是(3,1)。NumPy执行减法运算时不会直接抛出形状不匹配的错误,而是会自动把w广播成(3,3)的矩阵参与计算:

  • 每一轮迭代后w的形状都会偏离初始设定,下一次前向计算的输出维度跟着错乱,误差值不受控放大,最终直接触发数值崩溃。

4. 冗余计算

前向计算里你写了h = sig(z) 之后又写了yhat = sig(z),两个变量算的是完全一样的值,属于无意义的重复计算,不影响结果但会增加不必要的运算开销。

5. 打印环节的变量名笔误(不影响nan生成,但会导致程序运行报错)

  • 循环内定义的输出变量是yhat,但最后打印时写的是带下划线的y_hat,会触发变量未定义错误
  • 循环内定义的误差变量是deltay,但最后打印时写的是带下划线的delta_y,同样会触发变量未定义错误

单层无隐藏层网络的正确梯度推导逻辑(供核对参考,不需要直接照抄实现):
对平方损失J = 1/2*(yhat - y)^2,权重梯度的计算不需要多余的跨层步骤:

# 前向计算
z = np.dot(x, w)
yhat = sig(z)
# 反向计算梯度
error = yhat - y
sig_deriv = yhat * (1 - yhat) # 用激活输出计算导数,避免直接传入z
dJdw = np.dot(x.T, error * sig_deriv)
# 更新权重
w = w - alpha * dJdw

内容的提问来源于stack exchange,提问作者becky.rrr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 05:15:05