神经网络是怎么算出结果的:前向传播与反向传播原理拆解

神经网络之所以能“学会”东西,是因为它把输入经过一系列加权求和与非线性变换得到输出,再根据输出和正确答案的差距反向调整参数。
理解这条链路,比背公式更重要。
下面用一个单隐藏层网络的手算例子,把前向传播和反向传播拆开讲清楚,最后用 NumPy 跑一遍验证。

一个神经元到底在算什么

先看最基础的结构。
一个神经元接收若干输入,每个输入乘一个权重,加上偏置,再经过激活函数得到输出:

z = w1*x1 + w2*x2 + b
a = f(z)

其中 w 是权重,决定某个输入有多重要;b 是偏置,调整激活的阈值;f 是激活函数,常见的有 ReLU、Sigmoid、Tanh。
没有激活函数,多层网络叠加起来仍然等价于一个线性变换,表达能力有限。

举例:输入 x1=1.0, x2=2.0,权重 w1=0.5, w2=-0.3,偏置 b=0.1,则 z = 0.5*1.0 + (-0.3)*2.0 + 0.1 = 0。
若用 ReLU,输出 a = max(0, 0) = 0;
若用 Sigmoid,输出约 0.5。

前向传播:把输入一层层推到输出

前向传播就是按网络顺序做上面的计算。
以一个两层网络为例:输入层 2 个节点,隐藏层 2 个节点,输出层 1 个节点。

第一层隐藏层计算:

z1_1 = w11*x1 + w12*x2 + b1_1
a1_1 = relu(z1_1)
z1_2 = w21*x1 + w22*x2 + b1_2
a1_2 = relu(z1_2)

输出层计算:

z2 = v1*a1_1 + v2*a1_2 + b2
y_hat = sigmoid(z2)

y_hat 就是模型给出的预测值。
整个过程只有矩阵乘法和激活函数,计算量集中在矩阵乘法上,所以实际框架会用 GPU 加速。

反向传播:误差怎么传回每一层

训练时我们有一组带标签的数据,比如输入对应真实标签 y。
先定义损失函数,二分类常用交叉熵:

L = -[y*log(y_hat) + (1-y)*log(1-y_hat)]

反向传播的目标是求损失对每个权重和偏置的偏导数,也就是梯度。
核心是链式法则:输出层的误差先算出来,再乘上权重传回隐藏层。

对输出层:

dL/dz2 = y_hat - y
dL/dv1 = dL/dz2 * a1_1
dL/db2 = dL/dz2

对隐藏层,误差通过 v1、v2 回传,再乘激活函数的导数。
ReLU 的导数在 z>0 时为 1,否则为 0:

dL/da1_1 = dL/dz2 * v1
dL/dz1_1 = dL/da1_1 * (z1_1 > 0)
dL/dw11 = dL/dz1_1 * x1

得到梯度后,用梯度下降更新参数:

w = w - learning_rate * dL/dw

学习率太大会震荡甚至发散,太小则收敛慢。
常见做法是从 0.001 到 0.01 开始试,观察损失曲线。

用 NumPy 跑一遍并做梯度检查

下面代码实现一个单隐藏层网络的前向和反向传播,并用数值梯度检查解析梯度是否正确:

import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 输入、真实标签
x = np.array([1.0, 2.0])
y = 1.0

# 参数初始化
W1 = np.array([[0.1, 0.2], [0.3, 0.4]])
b1 = np.array([0.0, 0.1])
W2 = np.array([0.5, -0.2])
b2 = 0.3

# 前向
z1 = W1 @ x + b1
a1 = np.maximum(0, z1)
z2 = W2 @ a1 + b2
y_hat = sigmoid(z2)
loss = -(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))

# 反向
dz2 = y_hat - y
dW2 = dz2 * a1
db2_grad = dz2
da1 = dz2 * W2
dz1 = da1 * (z1 > 0)
dW1 = np.outer(dz1, x)
db1_grad = dz1

# 数值梯度检查(只检查 W2 第一个元素)
eps = 1e-6
W2_plus = W2.copy(); W2_plus[0] += eps
W2_minus = W2.copy(); W2_minus[0] -= eps

z2p = W2_plus @ a1 + b2
yp = sigmoid(z2p)
loss_p = -(y * np.log(yp) + (1 - y) * np.log(1 - yp))

z2m = W2_minus @ a1 + b2
ym = sigmoid(z2m)
loss_m = -(y * np.log(ym) + (1 - y) * np.log(1 - ym))

num_grad = (loss_p - loss_m) / (2 * eps)
print("解析梯度:", dW2[0], "数值梯度:", num_grad)

运行后两者应非常接近(差异在 1e-6 量级内)。
如果差距大,通常是链式法则漏乘了某一项,或者激活函数导数用错。

新手最容易卡住的几个地方

权重初始化不要全零。 全零会导致同一层所有神经元学到相同特征,对称性无法打破。
常用小随机数,如 np.random.randn(...) * 0.01。

损失不下降先查学习率和数据。 学习率过大时损失可能变成 nan,过小则几乎不动。
确认输入数据已归一化,标签编码正确。

ReLU 死亡问题。 如果某个神经元的 z 长期为负,梯度恒为 0,参数不再更新。
可以换 Leaky ReLU 或调小学习率。

矩阵维度对不上。 报错 shapes not aligned 时检查 W1 @ x 中 W1 的列数是否等于 x 的长度,反向传播时转置是否用对。

验证理解是否到位

能独立回答这三个问题,说明原理已经通了:给定一组权重和输入,能否手算出输出;
能否写出交叉熵对输出层输入的导数;
能否解释为什么反向传播要从后往前算。
再用上面的梯度检查代码跑一次,观察解析梯度和数值梯度是否一致,比反复看公式更有效。

分享到:
上一篇
AI深度学习入门教程:用PyTorch跑通MNIST手写数字识别
下一篇
AI Transformer架构详解:从自注意力到完整工作流程
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意