你每天打开邮箱,几十封邮件里总能一眼挑出垃圾邮件。凭什么?你其实在大脑里飞速掂量几条线索:标题有没有「中奖」、发件人陌不陌生、是不是一堆感叹号。而这些线索在你心里的分量并不一样——「中奖」两个字一出现,基本就八九不离十了;感叹号多一点少一点,影响不大。
神经网络里的权重(weight),干的就是这件事:给每条线索标一个「该听多少」的数。
权重是什么
权重是连在每条输入线索上的一个数。它和线索的值相乘,决定这条线索对最终结果的影响力大小——数越大,这条线越「粗」,说明网络越看重它。
接着上面的垃圾邮件例子:「含『中奖』」这条线索的权重可能是 3.0(重),「感叹号多」这条只有 0.2(轻)。一个神经元(网络里最基本的计算单元)把所有「线索 × 权重」加起来,再加一个偏置
在 AI 体系里,权重和偏置合起来叫「参数」。一个神经网络可能有几亿、上百亿个参数——而所谓「训练一个模型」,本质就是把这些权重调到一组合适的值。
图 1:把两条线索各乘自己的权重、相加、再加偏置,算出一封邮件的总分
一个公式说清它
逐个符号的意思是:
—— 神经元算出的总分(还没经过最后一步的概率化,可正可负) —— 线索编号,从 1 数到 —— 线索总条数 —— 第 条线索的取值(比如「含中奖」这条,命中记 1、没命中记 0) —— 第 条线索的权重,即这条线索有多重要 —— 求和号,把每一条「线索 × 权重」都乘好,再统统加起来 —— 偏置,一个固定的基础分,和具体哪条线索无关
换成评委打分就好懂了:每个评委的打分(
代入垃圾邮件算一遍:线索「含中奖」
总分
自检:方向对得上 ✅——「中奖」命中 → 正 → 垃圾邮件;两条都不命中 → 负 → 正常邮件。
权重是怎么「学」出来的
关键问题来了:这些权重一开始从哪来?答案是——随机瞎设。刚起步的网络啥也不懂,只会乱猜。
所谓「学习」,就是一轮轮把这个乱猜的权重往准里调:
- 网络用当前的权重算出总分,给出判断;
- 拿这个判断和正确答案比,算出误差(这一步由损失函数负责);
- 用梯度(告诉你每个权重该往大调还是往小调、各调多少)反过来修正每一个权重,这步叫反向传播;
- 调完再来一轮,如此循环成千上万次。
练到最后,权重稳定在一组能让网络答对的值上。整个网络「学到的全部知识」,就编码在这几亿个调好的权重里——一张磁盘上的权重文件,就是一个训练好的模型。
图 2:训练让连线的粗细从「乱」变成「关键线索粗、次要线索细」——这就是权重被调准
不是什么
划两条边界,免得误会:
- 权重不是「要不要连接」——网络结构先定了哪些线相连,权重决定的是每根线连得多紧。
- 权重不是越大越好——它要调到「合适」。有时一个本该小的权重被调大,反而会让网络判错。
小结
权重是神经网络给每条输入线索分配的「重要程度」,靠加权求和得出总分来做判断。训练的全部意义,就是把几十亿个权重从随机调成刚好能让网络答对——所以两个 AI 模型的差别,本质上不在结构多花哨,而在那一堆调好的权重数值不同。回到开头那封垃圾邮件:网络能一眼挑出它,靠的就是练出来的权重把「中奖」这条线索顶得很高。所谓「AI 学到的知识」,说到底就是一堆调好的权重。
完整代码
下面用一个极小的例子,让读者亲眼看到「训练 = 把随机权重调成会判断的权重」。整体流程是这样的:先造一个网络大脑(里面权重是随机的),再备好 4 条带正确答案的邮件样本,然后反复练习(每一轮都「读一遍 → 算误差 → 反向求梯度 → 更新权重」),最后考试看它学到了什么。把这段代码复制到本地跑一下,你会看到网络把 4 条邮件全判对,而且学到的权重里「含『中奖』」那条明显比「感叹号」大得多。
import torch # torch 是 PyTorch 深度学习库:提供"张量"(多维数组)这种数据容器,还能自动算梯度
import torch.nn as nn # nn 是神经网络模块,Linear 等现成"零件"都在里面
# ===== 任务:教网络学会「垃圾邮件判断」=====
# 两条线索:x1=是否含「中奖」(0 或 1),x2=感叹号是否多(0 或 1)
# 正确规则:含「中奖」分量重、感叹号分量轻——这两条线索的权重就是网络要学回来的
X = torch.tensor([[1., 1.], # torch.tensor 把普通列表变成张量;带小数点的 1. 表示浮点数(网络只认小数)
[1., 0.],
[0., 1.],
[0., 0.]]) # 4 条样本:含中奖+感叹号 / 含中奖 / 感叹号 / 都没有
y = torch.tensor([[1.], [1.], [0.], [0.]]) # 正确答案:1=垃圾邮件,0=正常邮件
# ===== 定义网络(一个神经元,对应文章公式 z = w1·x1 + w2·x2 + b)=====
class SpamNet(nn.Module): # nn.Module 是所有网络的"模板",括号里写它表示"照这个模板造"
def __init__(self):
super().__init__() # 固定写法:让 PyTorch 先把模板该初始化的都初始化好,照抄即可
self.layer = nn.Linear(2, 1) # 一个神经元:2=收进 2 条线索(x1,x2),1=输出 1 个总分 z
# 里面的权重 w1、w2 和偏置 b 一开始是随机瞎设的
def forward(self, x): # forward 定义"前向传播":线索怎么一步步变成输出
return self.layer(x) # 加权求和(文章公式 z = Σ w_i·x_i + b),直接由 Linear 算出
# ===== 训练:反复看这 4 条样本,把权重调准 =====
torch.manual_seed(42) # 固定随机种子:初始权重是随机的,设种子后每次跑结果一样(可复现)
net = SpamNet() # 造出网络大脑
opt = torch.optim.SGD(net.parameters(), lr=0.1) # 优化器=按梯度调权重的工具;lr=学习率=每次调多大步子
loss_fn = nn.BCEWithLogitsLoss() # 损失函数=量"预测离正确答案多远"的尺子(专为 0/1 二分类设计)
for epoch in range(2000): # 一轮(epoch)=把 4 条样本完整看一遍;重复 2000 轮让网络反复练
z = net(X) # 前向:算每条邮件的总分 z
loss = loss_fn(z, y) # 算误差:预测的总分 vs 正确答案差多远
opt.zero_grad() # 清空旧梯度(避免上一轮的残留累积进来)
loss.backward() # 反向传播:自动算出每个权重(w1、w2、b)该往大调还是小调
opt.step() # 用梯度更新权重——backward 算方向、step 迈步子,合起来就是"训练"
# ===== 考试:看看网络学到了什么、判断得对不对 =====
with torch.no_grad(): # 这段只是检验、不再调权重,所以关掉梯度计算省内存
z = net(X) # 算每条邮件的总分
prob = torch.sigmoid(z) # sigmoid 把总分 z 压成 0~1 的概率(0.5 正好对应 z=0,所以 prob>0.5 和正文里的 z>0 是同一回事)
pred = (prob > 0.5).float() # 概率 >0.5 判 1(垃圾邮件),否则 0;.float() 把真假转成数字
for i in range(4): # 逐条打印检验结果(range(4) 依次取 0、1、2、3)
label = '垃圾邮件' if pred[i, 0] == 1 else '正常邮件' # pred[i, 0] = 第 i 条样本的第 0 个输出
print(f"线索{X[i].tolist()} → 网络判断:{label}")
w = net.layer.weight[0] # 取出学到的两条线索的权重 [w1, w2]
b = net.layer.bias # 取出学到的偏置 b
print(f"学到的权重:含「中奖」w1={w[0]:.3f},感叹号 w2={w[1]:.3f}") # :.3f = 保留 3 位小数
print(f"学到的偏置:b={b.item():.3f}") # .item() 把张量取出成普通小数
print(f"训练 loss:{loss.item():.4f}") # loss 越小说明预测越接近正确答案跑完你会看到:网络把 4 条邮件都判对了,而且学到的
参考资料
- But what is a Neural Network? - 3Blue1Brown https://www.3blue1brown.com/lessons/neural-networks
- 多层感知机 - 动手学深度学习 https://zh.d2l.ai/chapter_multilayer-perceptrons/mlp.html
- 权重和偏置:网络的参数 - ApXML Machine Learning https://apxml.com/zh/courses/introduction-to-neural-networks/chapter-1-neural-network-foundations/weights-and-biases