你能构建的最小大脑:Python中的感知机
摘要
感知机是最简单的神经网络构建块。本教程从零开始用Python实现一个感知机,通过清晰的示例解释权重、偏置和学习过程。
暂无内容
查看缓存全文
缓存时间: 2026/06/08 03:14
# 你能构建的最小大脑
来源:https://ranpara.net/posts/perceptron-explained-from-scratch/
感知机是你能构建的最小大脑。输入一个数字,输出一个“是”或“否”的答案。就这么简单。
听起来简单到不值一提。但这个微小的想法是今天所有神经网络的基础。在这篇文章中,我们将用 Python 从零开始构建一个感知机,并在浏览器里实时观察它的学习过程。没有沉重的数学,没有庞大的库。只有一个权重、一个偏置和一个循环。
我不是英语母语者,而且我自己也还在学习这个领域。所以我会用我希望别人向我解释的方式来讲解:缓慢地,从头开始。
### 什么是感知机?
1958 年,一位名叫弗兰克·罗森布拉特的研究员制造了一台他称之为感知机的机器。
它的灵感来源于一个单一的脑细胞——神经元。神经元接收信号,如果信号足够强,它就会触发。罗森布拉特用数学复制了这个想法:
```
output = 1 if (w · x + b) > 0
0 otherwise
```
这里的 `x` 是输入,`w` 是权重,`b` 是偏置。现在不用太在意这些术语,我们通过构建真实的东西来认识它们。
### 先用人脑思考
在机器做决定之前,我们先观察一个人如何决策。假设有个人叫张三,他有一份工作邀请,需要回答一个问题:他应该接受吗?
张三不会抛硬币。他会权衡利弊。某些因素对他更重要。
| 因素(输入) | 数值 | 张三的在意程度(权重) |
| ------------ | -------------------------- | ---------------------- |
| 额外薪酬 | 高 | 非常在意 |
| 留在同一个城市 | 不,他必须搬家 | 非常在意 |
张三把每个因素乘以他在意的程度,然后把所有结果加起来。如果总和足够高,他就说“是”,否则就说“否”。
这就是感知机。因素就是 **输入**,他在意的程度就是 **权重**,而“足够高”是他脑子里设定的一个阈值。记住这个阈值,稍后我们会给它一个名字:偏置。
```
w1
──→ ×
输入: 额外薪酬 │
├── Σ → 偏置 b → 是否>0? → 接受? Yes/No
输入: 同一个城市 │
──→ ×
w2
```
(示意图:两个输入,分别乘以权重,与偏置求和,最终输出一个“是/否”答案)
张三如何决定:每个输入乘以权重,结果加上偏置,总和变成一个“是/否”的答案。
### 最简单可能的判断:这个数是正数吗?
我们把问题缩小到几乎不能再小:一个输入,一个问题。
> 这个数是正数吗?
就这么简单。给机器一个数字,它应该为正数返回 True,为负数返回 False。
机器是这样猜测的:
```
prediction = (weight * value + bias) > 0
```
把输入乘以权重,加上偏置,然后检查结果是否大于 0。如果是,就预测 True;否则预测 False。这个小小的公式就是 **分类器**,也叫决策函数。
一开始,权重和偏置只是随机数。所以机器猜得很差。现在唯一巧妙的步骤来了:它从错误中学习。
```
if prediction != result:
error = result - prediction # True - False = 1, False - True = -1
weight += learning_rate * error * value
bias += learning_rate * error
```
当猜测错误时,我们朝正确的方向微调权重和偏置。**误差**告诉我们朝哪个方向调整,**学习率**决定每次调整的幅度。我们对每个样本都这样做,然后重复整个一轮。一轮完整的数据遍历称为一个 **epoch**。重复 epochs 就是 **训练**。
下面就是这样的机器。点击 **Train**,观察它学习。绿色圆点代表正数(True),红色圆点代表负数(False),蓝色虚线是它决定分割的位置。
epoch **0** weight **0** bias **0** boundary **–** accuracy **0%**
它几乎立即就位。观察读数:边界正好落在 **0** 附近,偏置也稳定在 **0** 附近。
这不是偶然。对于这个问题,我们根本不需要偏置。这有点奇怪,因为偏置按理说很重要。为什么它重要?我们需要一个更难的问题来回答。
### 什么是决策边界?
那条蓝线有个名字:**决策边界**。它是机器从输出 False 切换到输出 True 的确切点。
我们可以计算它。边界位于 `w · x + b = 0` 处。解出 `x`:
```
decision_boundary = -bias / weight
```
对于“这个数是正数吗?”这个问题,边界应该在 0 处。确实如此。现在看看当正确的答案不在 0 时会发生什么。
### 为什么需要偏置?学生及格的例子
新问题,同样的机器。我们给它 0 到 100 的考试分数,然后问:
> 学生及格了吗?
规则很简单:分数达到 50 分或以上就算及格。所以决策边界应该位于 **50**,而不是 0。
我们试试像解决前一个问题那样只用权重来解决。在下面的演示中,**关闭“Use bias”**,然后点击 **Train**。
epoch **0** weight **0** bias **0** boundary **–** accuracy **0%**
□ Use bias
观察准确率。它会爬到大约 50%,然后就卡住了。无论你训练多久,它都无法更好。
原因如下。没有偏置,公式只是 `weight * score`。每个考试分数都是正数。所以如果权重为正,机器会将 **所有** 学生判为及格;如果权重为负,则判为不及格。边界被固定在 0,无法移动。被迫通过零点的直线根本无法区分“低于 50”和“50 及以上”。
现在 **重新打开“Use bias”**,再按 **Train**。准确率一路爬到 100%,边界滑动到 50 附近。
这就是偏置的全部工作。权重决定斜率。**偏置** 将边界向左或向右移动,使其可以位于正确答案所在的位置。记住 `decision_boundary = -bias / weight`。有了偏置,边界可以是任何值。没有偏置,它就永远被卡在零点。
一句话总结:**当你的输入远离零时,你需要偏置将直线移动到它们所在的位置。**
### 感知机如何学习?Epochs 和学习率
你在训练时看到了两个旋钮:epochs 和学习率。
**Epoch** 是对所有数据的一次完整遍历。机器很少能在一次遍历中就全部正确,所以我们会一遍又一遍地重复。更多的 epochs 意味着有更多机会修正错误。这就是为什么准确率会随着持续训练而上升。
**学习率** 是每次修正的幅度。在代码中是 `learning_rate` 乘数:
```
weight += learning_rate * error * value
```
小步走小心但缓慢。大步走快速但可能过冲并来回震荡。选好学习率是一门手艺。这里我们用了 `0.1`,足够平缓以保持稳定。
### 为什么需要归一化数据?
在及格例子中隐藏着一个安静的问题。再看一下更新行:
```
weight += learning_rate * error * value
```
修正量乘以 `value`。对于考试分数,`value` 可以大到 100。所以一次错误的猜测就可能使权重发生巨大变化。机器虽然还能学习,但会踉踉跄跄,而不是平滑地收敛。
解决办法是 **归一化**:在训练之前将输入缩放到一个小的、整齐的范围。最简单的版本是将每个分数除以最大可能分数,这样 0 到 100 就变成了 0 到 1。
在下面的演示中,先关闭归一化按 **Train**,观察准确率曲线在上升过程中跳跃。然后 **打开“Normalize data”**,重置,再训练一次。同样的机器,同样的答案,但它只需很少的 epochs 就能到达,而且爬升很平滑。
epoch **0** weight **0** bias **0** boundary **–** accuracy **0%**
□ Normalize data
老实说,对于像这样的单一输入,归一化主要带来速度和稳定性。当你的输入量级差异很大时,归一化就变得至关重要。回想张三的例子:他的薪酬以千美元计,而“同一个城市”只是 0 或 1。如果不归一化,薪酬会淹没一切,机器基本上会忽略城市因素。把两者放在同一个量级上,每个因素才能得到公平的表达。(除以最大值是简单的版本;另一种常用的通用方法是减去均值并除以标准差,称为标准化。)
### Python 中的完整感知机
以下是“这个数是正数吗?”的完整程序,没有任何隐藏。它短到可以一口气读完。
```python
import random
learning_rate = 0.1
EPOCHS = 100
weight = random.uniform(-1, 1)
bias = random.uniform(-1, 1)
# 正数为 True,负数为 False
data = [(i * 0.1, True) for i in range(1, 501)]
data += [(i * 0.1, False) for i in range(-500, 0)]
random.shuffle(data)
for epoch in range(EPOCHS):
for value, result in data:
prediction = (weight * value + bias) > 0
if prediction != result:
error = result - prediction # +1 或 -1
weight += learning_rate * error * value
bias += learning_rate * error
decision_boundary = -bias / weight
print(f"weight = {weight:.3f}")
print(f"bias = {bias:.3f}")
print(f"decision boundary = {decision_boundary:.3f}")
```
要把它变成学生及格的机器,你只需要改两处:让数据变成考试分数,并设置 `result = score >= 50`;如果你想感受缺失偏置的痛苦,就把偏置冻结为 0。其余保持不变。
### 致谢
这篇文章的核心灵感来自 Welch Labs 的精彩视频 [ChatGPT is made from 100 million of these [The Perceptron]](https://www.youtube.com/watch?v=l-9ALe3U-Fg)。如果你是视觉学习者,想了解这些概念背后的丰富历史与硬件,我强烈推荐观看!
### 下一步是什么?
你刚刚构建了一个能工作的感知机。它接收输入,加权,加上偏置,然后做出判断。它从自己的错误中学习,一个 epoch 接着一个 epoch。
一个神经元只能画一条直线。真正的魔法从堆叠开始:一个神经元的输出成为下一个神经元的输入。足够多的层叠在一起,你就得到了一个神经网络,它可以学习远复杂于一条直线的形状。但其中的每个神经元都在做你刚才看到的事情:一个权重,一个偏置,一个决策。
如果你想了解我是如何最终在加拿大写代码的非技术故事,我在这篇文章中写了:[The Outsider Who Shipped Anyway](https://ranpara.net/posts/the-outsider-who-shipped-anyway/)。
谢谢你和我一起构建。现在去修改数字,把它弄坏吧——这是最快的学习方法。
相似文章
Age of Empires II 中的感知器
本文演示了在游戏 Age of Empires II 中构建一个感知器和与非门,认为改变 LLM 的基质会改变对属性的感知,并批评了关于 LLM 拟人化的研究。
Perceptron Mk1 震撼发布高性能视频分析AI模型,比Anthropic、OpenAI和Google便宜80-90%(8分钟阅读)
Perceptron公司发布了其旗舰视频分析模型Mk1,声称成本比竞争对手低80-90%,同时在空间和视频推理基准上表现出色。
[R] 我构建了一个像大脑一样学习的认知架构——无需反向传播、无需GPU、不会遗忘
介绍了一种新颖的认知架构,它无需反向传播、GPU或遗忘即可学习,模仿了生物学习方式。
@chessMan786: 如何在C++中从零开始构建神经网络你是否在寻找关于神经网络实际工作原理的清晰且实用的解释?
一条推文,推广从零开始在C++中构建神经网络的指南,旨在提供关于神经网络工作原理的清晰而实用的解释。
@tetsuoai: 神经网络的核心就在四张卡片上。神经元、前向传播、激活函数、反向传播。学会这四个概念,你就能……
一套覆盖神经网络核心概念的四张卡片:神经元、前向传播、激活函数和反向传播,旨在帮助学习者理解从感知机到Transformer等模型的工作原理。