首页
/ Generative AI for Beginners 第 15 课知识语料解析:感知机——二分类模型、感知机准则与梯度下降训练

Generative AI for Beginners 第 15 课知识语料解析:感知机——二分类模型、感知机准则与梯度下降训练

2026-09-06 15:06:08作者:宣聪麟

本文以 generative-ai-for-beginners 课程第 15 课(RAG 与向量数据库)配套教学语料 perceptron.md 为主体,系统讲解感知机(Perceptron)的诞生背景、数学模型、感知机准则、梯度下降训练流程与 Python 实现,并结合该语料在 RAG 知识库流水线中的真实用法(分块、向量化、检索)做补充说明。读完后你将掌握感知机的完整训练原理,能看懂并修正课程代码中的实现细节,同时理解这份"神经网络入门语料"如何作为示例数据支撑 RAG 应用。

这份文档在课程仓库中的定位

perceptron.md 是第 15 课 RAG(Retrieval Augmented Generation)实战的三份知识语料之一,与 frameworks.mdown_framework.md 共同构成"AI for Beginners 神经网络课程"的本地知识库。课程说明文档 README 中明确写道,该课会把这些神经网络课程文档作为 LLM 应用的 grounding 数据。

在配套笔记本 notebook-rag-vector-databases.ipynb 中,可以看到它被完整读入并进入 RAG 流水线:

data_paths = ["data/frameworks.md", "data/own_framework.md", "data/perceptron.md"]
rows = []
for path in data_paths:
    with open(path, 'r', encoding='utf-8') as file:
        file_content = file.read()
    rows.append({'path': path, 'text': file_content})
df = pd.DataFrame(rows, columns=['path', 'text'])

后续流程将全文分块(chunking)、经嵌入模型转成向量并存入索引,最终用示例查询 what is a perceptron? 做语义检索——命中的正是本文件的内容。因此这份文档既是可独立学习的机器学习小课,也是 RAG 演示中被真实检索的语料,理解它有助于理解检索结果为什么与"感知机"相关。

仓库中还存在该文档的保加利亚语翻译版本 translations/bg/15-rag-and-vector-databases/data/perceptron.md,内容与英文原版一致,多语言版本用于课程的多语言站点;本文以英文原版结构为准进行讲解。

历史背景:1957 年的 Mark-1 硬件感知机

感知机由 Cornell Aeronautical Laboratory 的 Frank Rosenblatt 于 1957 年首次实现,这是最早接近现代神经网络雏形的尝试之一。Mark-1 是一台纯硬件设备,目标是识别三角形、正方形、圆等基础几何图形。原文档引用了维基百科的 Rosenblatt 肖像与 Mark-1 照片(对应 images/Rosenblatt-wikipedia.jpgimages/Mark_I_perceptron_wikipedia.jpg,当前仓库该目录未随附这两张图片,故此处仅引用文字描述)。

其关键硬件规格:

  • 输入:一张输入图像由 20×20 的光电元件阵列(photocell array)采集,因此网络共有 400 个输入1 个二值输出
  • 结构:整个"简单网络"只含一个神经元,也称为阈值逻辑单元(threshold logic unit)
  • 权重:神经网络权重表现为电位器(potentiometer),训练阶段需要人工手动调节。这里文档还补充了一个小常识:电位器是允许用户调节电路中电阻值的器件。

当时《纽约时报》对它的描述颇具时代色彩:一台电子计算机的胚胎,[美国海军]预计它能够行走、说话、看、书写、自我复制,并意识到自身的存在。 这段引文值得保留——它直观反映了上世纪 50 年代对神经计算能力边界的天真想象,而今天的课程正是从这台机器出发讲现代模型。

感知机的数学模型:一个二分类器

假设模型有 N 个特征,则输入向量 x 是 N 维向量。感知机是一个二分类(binary classification)模型,即只能在两个类别之间做区分。对任意输入向量 x,输出取 +1 或 -1,取决于所属类别,输出计算式为:

y(x) = f(wᵀx)

其中 f 是阶跃激活函数(step activation function):线性组合 wᵀx 经过阶跃函数后输出 +1 或 -1。从公式可以读出三个核心要素:

要素 含义 说明
x 输入特征向量,N 维 例如一张 2×2 图像的 4 个像素值
w 权重向量,N 维 决定每个特征对决策的贡献方向与强度
f 阶跃激活函数 将加权和映射为 +1 / -1 两个类

这个模型本质上是一条划分超平面 wᵀx = 0,落在哪一侧决定输出符号——这也是单层感知机只能处理线性可分问题的根源,后文会展开。

训练感知机:感知机准则与梯度下降

训练的目标是找到一个权重向量 w,使绝大多数样本被正确分类,即让错误最小。错误由**感知机准则(perceptron criterion)**定义:

E(w) = -Σ wᵀxᵢtᵢ

其中:

  • 求和只针对被错误分类的训练样本 i(分类正确的样本不产生误差项);
  • xᵢ 是输入数据,tᵢ 是标签:正样本取 +1,负样本取 -1。

把 E 视为权重 w 的函数,训练就是最小化 E(w)。常用方法是梯度下降(gradient descent):从某个初始权重 w⁽⁰⁾ 出发,每步按

w⁽ᵗ⁺¹⁾ = w⁽ᵗ⁾ - η∇E(w)

更新权重。其中 η 是学习率(learning rate),∇E(w) 是 E 对 w 的梯度。代入感知机准则的梯度后,得到文档给出的最终更新式:

w⁽ᵗ⁺¹⁾ = w⁽ᵗ⁾ + Σ η xᵢtᵢ

这条更新式有非常直观的几何含义:每个被分错的样本 xᵢ 都按自己的方向(正样本 +xᵢ、负样本 -xᵢ)把权重"推"过去一步,学习率 η 控制每次推动的幅度;只有分错的样本才参与修正,分对的样本不产生梯度贡献——这正是感知机准则把求和限制在误分类样本上的意义所在。

Python 实现:读懂原文代码,并修正其中的笔误

原文档给出的训练算法如下:

def train(positive_examples, negative_examples, num_iterations = 100, eta = 1):

    weights = [0,0,0] # Initialize weights (almost randomly :)

    for i in range(num_iterations):
        pos = random.choice(positive_examples)
        neg = random.choice(negative_examples)

        z = np.dot(pos, weights) # compute perceptron output
        if z < 0: # positive example classified as negative
            weights = weights + eta*weights.shape

        z  = np.dot(neg, weights)
        if z >= 0: # negative example classified as positive
            weights = weights - eta*weights.shape

    return weights

参数含义:num_iterations=100 为训练迭代轮数;eta=1 为学习率;weights=[0,0,0] 表示 2 维特征加 1 个偏置项(初始化为全零)。每一轮从正/负样本集中各随机抽一个样本,分别计算加权和 z,若正样本被判为负类(z < 0)则沿该样本方向修正权重,若负样本被判为正类(z ≥ 0)则反向修正。

但原代码有一处明显笔误eta*weights.shapeweights 是普通列表,weights.shape 会抛 AttributeError;即便换成 NumPy 数组,.shape 返回的也是元组而非样本向量,无法表达权重更新。对照上一节的数学更新式 w ← w + Σ η xᵢtᵢ,更新方向应该是误分类样本本身(正样本 +pos、负样本 -neg)。结合原文还省略了 import randomimport numpy as np,一个可直接运行的修正版本是:

import random
import numpy as np

def train(positive_examples, negative_examples, num_iterations=100, eta=1):
    # 2 个特征 + 1 个偏置项,初始化为零
    weights = [0.0, 0.0, 0.0]

    for _ in range(num_iterations):
        pos = random.choice(positive_examples)
        neg = random.choice(negative_examples)

        z = np.dot(pos, weights)   # 计算感知机输出(加权和)
        if z < 0:                  # 正样本被误判为负类
            weights = [w + eta * d for w, d in zip(weights, pos)]

        z = np.dot(neg, weights)
        if z >= 0:                 # 负样本被误判为正类
            weights = [w - eta * d for w, d in zip(weights, neg)]

    return weights

这个实现与文档的推导完全一致:每次迭代对误分类样本执行 w ← w ± ηxᵢ,学习率由 eta 控制,迭代 num_iterations 轮后返回学到的权重。样本集可以是任何"特征 + 偏置位 1"构成的向量列表,例如把手写数字降采样为 2×2 像素后构造正负样本对——这也对应文档结尾作业中"在手写数字之间做二分类"的场景。

局限与延伸:从单层感知机到多层网络

单层感知机的能力边界是明确的:它只能解决线性可分的二分类问题。文档同目录的姊妹语料 own_framework.md 正好承接这一点,指出单层感知机是"线性二分类模型",并将其扩展为多层感知机(MLP):

  • 引入非线性激活函数 α 与 softmax σ,使 f 可以逐层计算:z₁ = w₁x + b₁,z₂ = w₂α(z₁) + b₂,f = σ(z₂);
  • 借助链式法则逐层回传求导,即反向传播(backpropagation),从而支持多分类与回归任务、分离非线性可分的类别;
  • 优化上采用小批量随机梯度下降(SGD),每次只取随机采样的 minibatch 计算梯度。

也就是说,perceptron.md 讲的是"一个神经元 + 感知机准则"这一最简模型,own_framework.md 讲的是"堆叠成多层并用 backprop 训练",frameworks.md 则介绍现成的神经网络框架(TensorFlow、PyTorch、Keras)。三份语料恰好构成一条"从最简模型到工程框架"的学习路径——在 RAG 场景中,当用户问"what is a perceptron?"时,检索系统会命中 perceptron.md 的分块,而问"什么是反向传播"时则更可能命中 own_framework.md。

动手实践与延伸阅读

  • 作业(Assignment):文档要求把二分类感知机推广为完整的数字识别任务——给定一张图像,判断它最可能是哪个数字,即从"两类判断"升级到"十类分类"。
  • 挑战(Challenge):文档建议通过 Microsoft Learn 上基于 Azure ML Designer 的实验课动手搭建自己的感知机(此处按原文只保留文字指引,不附外部链接)。
  • 自学者路径:从 notebook-rag-vector-databases.ipynb 开始,完整走一遍"分块 → 嵌入 → 建索引 → 语义检索 → LLM 生成"的 RAG 流程,你会看到本文讲解的感知机语料是如何被 chunk、被嵌入、再被 what is a perceptron? 这一查询命中的,从而把本文的算法知识与第 15 课的向量检索实战真正串起来。

小结

本文围绕第 15 课的知识语料 perceptron.md 完成了以下主线:

  1. 历史:1957 年 Rosenblatt 的 Mark-1 硬件感知机——20×20 光电阵列(400 输入)、单一阈值逻辑单元、电位器手调权重;
  2. 模型:二分类器 y(x) = f(wᵀx),f 为阶跃函数,输出 +1 / -1;
  3. 训练:感知机准则 E(w) = -Σwᵀxᵢtᵢ(只对误分类样本求和),用梯度下降按 w⁽ᵗ⁺¹⁾ = w⁽ᵗ⁾ + Σηxᵢtᵢ 更新,η 为学习率;
  4. 实现:给出了参数注释完整的 Python 训练函数,并修正了原文档 weights.shape 的笔误,使代码可运行;
  5. 定位:该文档同时是 RAG 课被分块嵌入、被真实查询命中的知识库语料,与 own_framework.md(多层感知机与反向传播)、frameworks.md(神经网络框架)构成递进学习路径。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388