# 13.1 人工智能概论

~~以下全是废话，这里才是人工智能与大模型的精髓：超级无敌大开门. 什么萝卜纸巾？\[EB/OL]. (2025-12-21)\[2026-05-11].~~ [~~https://www.bilibili.com/video/BV1Kvq2BiEqT/~~](https://www.bilibili.com/video/BV1Kvq2BiEqT/)~~.~~

## 人工智能术语

人工智能（Artificial Intelligence，AI）研究机器人、语言识别、图像识别、自然语言处理（Natural Language Processing，NLP）和专家系统等领域，既是计算机科学的分支，也是人文科学的研究对象。1956 年达特茅斯会议上，约翰·麦卡锡首次提出“人工智能”这一概念。

强人工智能（Strong Artificial Intelligence）指能够实现人类全部认知能力的智能机器：它可以真正推理和解决问题，具备知觉与自我意识（Self-awareness）。弱人工智能（Weak Artificial Intelligence）则相反，它依赖人类干预来设定学习算法参数、提供训练数据以确保准确性，只是“看起来”智能，并不真正拥有知觉与自我意识。

自动机（Automaton）是对人类计算行为的模仿，属于语言识别器，用于判定一个对象是否属于某个集合、一个字符串是否属于某种语言。最简单的自动机由一条输入带和一个有限状态控制器组成，有时还会附加一个辅助存储器。

图灵机（Turing Machine）是自动机的增强形式，由一个有限控制器和一条可无限延伸的读写带组成。可计算性理论的基本论题是丘奇-图灵论题（Church-Turing Thesis）：如果一个函数能够通过某种算法人工计算，则它在图灵机上必然也是可计算的。

机器学习（Machine Learning，ML）是人工智能的子集。计算机自动分析与综合数据、事实或自身经验以获取知识，其算法专注于从训练数据中学习模式，进而对新数据做出准确 **推断**（Inference）。机器学习，尤其是深度学习（Deep Learning，DL），是现代 AI 系统的核心技术。

* 监督学习（Supervised Learning）中，训练样本的期望输出已知，学习目标是预测新样本的输出，典型任务包括分类（Classification）与回归（Regression）。
* 半监督学习（Semi-supervised Learning）中，学习器自行利用少量带标记样本和大量未标记样本进行学习。
* 无监督学习（Unsupervised Learning）指学习没有类别标记的样本，旨在发现数据的内在结构，典型任务包括聚类（Clustering）与降维（Dimensionality Reduction）：
  * 聚类将未标记样本集合划分为若干簇，使簇内数据比簇间数据更相似；
  * 降维减少所考虑的变量数量，涵盖特征提取（Feature Extraction）与特征选择（Feature Selection）等策略。

自监督学习（Self-supervised Learning）用无监督方法完成通常依赖监督学习的任务。自监督模型不依赖人工标记的数据集，而是从非结构化数据（Unstructured Data）中生成隐式标签。自监督学习包含两类任务：**前置任务**（Pretext Task）与**下游任务**（Downstream Task）。在前置任务中，模型学习非结构化数据的有意义表示；这些表示随后可用作下游任务（如监督学习或强化学习（Reinforcement Learning，RL）任务）的输入。将在新任务上重用预训练模型的做法称为“迁移学习（Transfer Learning）”。

自监督学习在计算机视觉（Computer Vision，CV）和自然语言处理等领域尤为有用，后者涵盖自然语言理解（Natural Language Understanding，NLU）、生成及其衍生技术。这些领域需要海量标注数据来训练人工智能模型，而标注数据集需人工耗费大量时间标注，收集充足数据极为困难。自监督方法更省时、更具成本效益，可部分或全部取代人工标注训练数据的环节。

要训练深度学习模型执行分类或回归等高精度任务，必须比较模型对给定输入的输出 **预测** 与该输入的“正确” **标注**，即通常所说的标准答案（Ground Truth）。人工标注的训练数据充当标准答案：这种方法需要直接的人工干预，因此称为“监督”学习。在自监督学习中，任务设计为能够从未标记数据中推断出标准答案。

强化学习是一种将环境状态映射为动作的学习过程，其目标是使动作从环境中获得的累积奖励值最大化。人类反馈强化学习（Reinforcement Learning from Human Feedback，RLHF）进一步引入人类偏好信号来引导学习方向。强化学习将学习转化为行动：它假设输入数据是相互依赖的元组（Tuple），即有序数据序列，并以“状态-动作-奖励”的形式组织数据。强化学习通过反复试错和奖励函数学习，其诸多应用旨在以正强化模仿现实中的生物学习方式。

与监督学习不同，强化学习不使用标注示例说明何为正确或错误行为：监督学习使用人工标注数据生成 **预测** 或分类。强化学习也有别于无监督学习：无监督学习从无标记数据中发现隐藏模式，而强化学习以动作为导向。自监督学习从未标记训练数据中导出伪标签（Pseudo Label）作为衡量模型准确性的依据；但强化学习既不产生伪标签，也不依据标准答案进行度量，因为它不是分类方法，而是行动学习方法。

深度学习是一种机器学习方法，也是现代 AI 系统的核心技术。它由 Hinton 等人提出，旨在研究信息的最佳表示及其获取方式。在神经网络与信念网络（Belief Network）中，深度学习基于深层结构或网络表示来学习输入-输出映射。

神经网络（Neural Network，NN）是一种模拟人脑结构的非线性系统，由大量人工神经元（Artificial Neuron，即生物神经元的抽象与简化）按照由线路与数学模型定义的拓扑结构互联而成。与传统机器学习中明确定义的数学逻辑不同，深度学习模型的神经网络由多个相互连接的“神经元”层组成，每个神经元执行特定的数学运算。调整相邻层神经元之间的连接强度（权重，Weight，与偏置，Bias），网络得以逐步优化并输出更精确的结果。神经网络直到 2000 年代末至 2010 年代初才取得突破性进展。

Transformer 模型擅长处理序列数据。Vaswani 等人 2017 年发表的《Attention is All You Need》首次提出了这一架构。基于 Transformer 的模型源自为机器翻译（Machine Translation，MT）设计的循环神经网络（Recurrent Neural Network，RNN）序列到序列（Sequence-to-Sequence，Seq2Seq）模型。此后，Transformer 在机器学习各细分领域均取得了显著进展。

注意力机制（Attention Mechanism）是一种机器学习技术，引导深度学习模型优先关注输入数据中最相关的部分。从数学上看，注意力机制计算出的注意力权重反映了输入序列中每个片段对当前任务的相对重要程度。Transformer 的核心价值在于，自注意力机制（Self-Attention Mechanism）使模型能够在不同时刻“关注”不同词元（Token）。由于能够计算词元之间的关系与依赖（尤其是文本中相距较远的词元之间的关系），自注意力机制才如此强大。此外，Transformer 架构支持并行化处理，效率远超早期方法。这些特性使 LLM 得以处理前所未有规模的庞大数据集。

**生成式人工智能**（Generative Artificial Intelligence，GenAI）指具备文本、图像、音频、视频等内容生成能力的模型及相关技术。生成式人工智能依赖复杂的机器学习模型（即深度学习模型，模拟人脑学习和决策过程的算法）。这些模型的工作方式是：识别并编码海量数据中的模式与关系，再利用这些信息理解用户的自然语言请求或问题，生成相关的新内容作为响应。语言模型（Language Model，LM）是自然语言句子或词串的 **概率**（Probability）分布，依据语言样本 **估计**（Estimation）得出。

大语言模型（Large Language Model，LLM）是一类经过海量数据训练的基础模型，能够理解和生成自然语言及其他类型的内容以执行各类任务。LLM 的初始训练采用自监督学习。其中，仅使用自回归解码器（Autoregressive Decoder）的大语言模型推动了生成式人工智能的现代发展，典型代表是促成 OpenAI 发布 ChatGPT 的 GPT-3（生成式预训练 Transformer 的缩写）模型。上下文窗口（Context Window）指模型生成文本时能一次性使用的最大词元数：早期 LLM 的窗口较短，新一代 LLM 已具备数百万词元的上下文窗口。

## 人工智能的数学基础

2017 年，Vaswani 等人提出了一种完全基于注意力机制、舍弃循环和卷积的序列转换模型——Transformer。本节严格依据该论文原文，重构其全部数学基础，并补充必要的背景知识。

许多核心机器学习模型从根本上依靠线性代数（Linear Algebra）原理来表达和求解。实践中，数据很少以简单的单一数值形式出现，通常表现为数据集，即大量数据点的集合。线性代数提供了有效整理、操作和分析这些数据的工具，使从业者得以通过向量（Vector）、矩阵（Matrix）和张量（Tensor）等对象来表示结构化数据（Structured Data），如表格数据，以及非结构化数据，如图像或视频。

不确定性量化（Uncertainty Quantification，UQ）旨在量化并降低物理系统建模与模拟中的不确定性；在系统某些因素未知的情况下，它试图给出研究结果的置信度。

统计学家乔治·伯克斯（George Box）曾言：“所有的模型都是错误的，但有些模型是有用的。”

### 定义

Google 提出的 Attention 机制的数学定义，其核心是**加权求和（weighted sum）**，通过查询（Query）、键（Key）和值（Value）矩阵实现。注意力标准定义如下：

$$
\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\Biggl(\frac{Q K^\top}{\sqrt{d\_k}}\Biggr) V
$$

其中：

$$
\begin{array}{rl}
Q \in \mathbb{R}^{n \times d\_k}, & \text{查询矩阵} \\
K \in \mathbb{R}^{m \times d\_k}, & \text{键矩阵} \\
V \in \mathbb{R}^{m \times d\_v}, & \text{值矩阵} \\
d\_k, & \text{键向量的维度，用于缩放} \\
\mathrm{softmax}(\cdot), & \text{对每行归一化得到权重} \\
\text{计算相似度矩阵: } S = Q K^\top, & \\
\text{缩放: } S\_\mathrm{scaled} = \frac{S}{\sqrt{d\_k}}, & \\
\text{权重矩阵: } A = \mathrm{softmax}(S\_\mathrm{scaled}), & \\
\text{输出: } \mathrm{Attention}(Q,K,V) = A V &
\end{array}
$$

### 向量的定义

在数学上，向量（vector）是一个 **有序数组**，表示一个具有大小和方向的量。例如，二维向量可以写作：

$$
\mathbf{v} = \begin{bmatrix} v\_1 \ v\_2 \end{bmatrix}, \quad v\_1, v\_2 \in \mathbb{R}
$$

一般来说，长度为 d 的向量：

$$
\mathbf{v} = \begin{bmatrix} v\_1 \ v\_2 \ \vdots \ v\_d \end{bmatrix} \in \mathbb{R}^d
$$

向量之间有以下基本运算：

* **加法**：逐元素相加

$$
\mathbf{u} + \mathbf{v} = \begin{bmatrix} u\_1 + v\_1 \ u\_2 + v\_2 \ \vdots \ u\_d + v\_d \end{bmatrix}
$$

* **数乘**（标量乘法）：向量每个分量乘以一个标量

$$
c \mathbf{v} = \begin{bmatrix} c v\_1 \ c v\_2 \ \vdots \ c v\_d \end{bmatrix}
$$

* **内积**（dot product）：衡量两个向量的相似度

$$
\mathbf{u} \cdot \mathbf{v} = \sum\_{i=1}^{d} u\_i v\_i
$$

### 权重加权求和

设有向量 v₁,…,vₘ 和对应权重 α₁,…,αₘ，权重非负且和为 1，则输出向量 o 为它们的加权求和。

$$
\mathbf{o} = \sum\_{i=1}^{m} \alpha\_i v\_i, \quad \alpha\_i \ge 0, \quad \sum\_{i=1}^{m} \alpha\_i = 1
$$

这就是 **从多组向量中选择性地聚合信息** 的基本操作。Attention 正是执行这种加权求和，但权重由查询向量决定。

### 查询、键、值向量

$$
\begin{array}{rl}
\text{查询向量: } & q \in \mathbb{R}^{d\_k} \\
\text{键向量集合: } & k\_1, k\_2, \dots, k\_m \in \mathbb{R}^{d\_k} \\
\text{值向量集合: } & v\_1, v\_2, \dots, v\_m \in \mathbb{R}^{d\_v} \\
\text{相似度: } & s\_i = q \cdot k\_i, \quad i = 1, \dots, m \\
\text{权重: } & \alpha\_i = \frac{\exp(s\_i)}{\sum\_{j=1}^{m} \exp(s\_j)}, \quad i = 1, \dots, m \\
\text{输出向量: } & \text{output} = \sum\_{i=1}^{m} \alpha\_i v\_i
\end{array}
$$

### 相似度与 softmax

以内积衡量查询与键的相似度：

$$
s\_i = q \cdot k\_i
$$

然后将这些相似度转换为概率：

$$
\alpha\_i = \frac{\exp(s\_i)}{\sum\_{j=1}^{m} \exp(s\_j)}
$$

由此，最相关的键所对应的值获得更大权重。

### 向量矩阵形式

将 m 个值向量堆成矩阵 V，键矩阵 K，查询矩阵 Q，可以得到矩阵形式的 Attention：

$$
\begin{array}{rl}
V \in \mathbb{R}^{m \times d\_v}, \quad K \in \mathbb{R}^{m \times d\_k}, \quad Q \in \mathbb{R}^{n \times d\_k} & \\
S = Q K^\top & \\
S\_\mathrm{scaled} = \frac{S}{\sqrt{d\_k}} & \\
A = \mathrm{softmax}(S\_\mathrm{scaled}) & \\
\mathrm{Attention}(Q,K,V) = A V &
\end{array}
$$

## 程序示例

以下示例在连续向量空间中通过注意力机制学习字符序列的动态关联，完成“你好世界”序列的自回归生成。

```python
# 导入 PyTorch 核心库
import torch                               # 深度学习框架：提供张量运算与自动求导
import torch.nn as nn                      # 神经网络模块：Linear、Embedding、LayerNorm、ModuleList 等
import torch.nn.functional as F            # 函数式接口：提供 softmax 等无状态操作
import torch.optim as optim                # 优化器模块：提供 Adam 等参数更新算法
import math                                # 数学库：用于 sqrt 计算缩放因子

# ============================================================
# 0. vocab — 词表定义
# ============================================================
# 示例仅使用 4 个汉字作为最小词表，便于理解注意力机制每一步的计算
chars = ["你", "好", "世", "界"]            # 词表：4 个字符
vocab_size = len(chars)                     # 词表大小 = 4

# 正向映射：字符 → 整数索引，供模型输入使用
char2idx = {c: i for i, c in enumerate(chars)}
# 反向映射：整数索引 → 字符，供推理阶段还原汉字显示
idx2char = {i: c for c, i in char2idx.items()}

# ============================================================
# 1. Transformer 超参数（标准 Transformer 风格）
# ============================================================
d_model = 512                               # 模型隐藏维度（嵌入维度），Transformer 经典配置
n_heads = 8                                 # 多头注意力头数
n_layers = 6                                # Transformer 块堆叠层数
d_ff = 2048                                 # 前馈网络中间层维度（通常为 d_model 的 4 倍）

# 确保 d_model 可被 n_heads 整除，每头维度为整数
assert d_model % n_heads == 0
d_head = d_model // n_heads                 # 每个注意力头的维度 = 512 / 8 = 64

# ============================================================
# 2. 训练数据 — 自回归序列构造
# ============================================================
# Transformer 自动学习 token → embedding → attention → output logits 的完整流程，
# 无需手动指定 target_vectors。
#
# 输入序列:  [你, 好, 世, 界]   →  索引 [0, 1, 2, 3]
# 目标序列:  [好, 世, 界, 你]   →  索引 [1, 2, 3, 0]
# 这就是“自回归”: 给定前 t 个字符，预测第 t+1 个字符

data = torch.tensor([[0, 1, 2, 3]])         # 输入张量，形状 (batch=1, seq_len=4)
target = torch.tensor([[1, 2, 3, 0]])       # 目标张量，形状 (batch=1, seq_len=4)

# ============================================================
# 3. Multi-Head Attention — 多头注意力层
# ============================================================
class MultiHeadAttention(nn.Module):
    """
    标准缩放点积多头自注意力（Scaled Dot-Product Multi-Head Self-Attention）。

    数学定义:
        Attention(Q, K, V) = softmax(Q·Kᵀ / √d_k) · V

    流程: 输入 x → 线性投影得到 Q/K/V → 拆分为多头 → 计算注意力得分 →
          缩放 → 因果掩码 → softmax → 加权求和 V → 合并多头 → 输出投影
    """

    def __init__(self, d_model, n_heads):
        """
        参数:
            d_model: 模型总维度，同时作为 Q/K/V 的投影维度
            n_heads: 注意力头数
        """
        super().__init__()

        self.d_model = d_model              # 模型维度，例如 512
        self.n_heads = n_heads              # 注意力头数，例如 8
        self.d_head = d_model // n_heads    # 每头维度 = 512 / 8 = 64

        # 四个无偏置线性投影矩阵（形状均为 d_model × d_model）:
        self.W_Q = nn.Linear(d_model, d_model, bias=False)   # 查询投影: x → Q
        self.W_K = nn.Linear(d_model, d_model, bias=False)   # 键投影:   x → K
        self.W_V = nn.Linear(d_model, d_model, bias=False)   # 值投影:   x → V
        self.W_O = nn.Linear(d_model, d_model, bias=False)   # 输出投影: 拼接后融合

    def forward(self, x, return_attention=False):
        """
        前向传播。

        参数:
            x:               输入张量，形状 (B, T, D)
            return_attention: 是否返回中间计算结果（Q/K/V/scores/alpha）供可解释性分析

        返回:
            if return_attention=False: out, 形状 (B, T, D)
            if return_attention=True:  (out, Q, K, V, scores, scores_scaled, alpha)
        """
        B, T, D = x.shape                   # B=批次大小, T=序列长度, D=d_model

        # ---------- 第 1 步：线性投影 x → Q, K, V ----------
        Q = self.W_Q(x)                     # (B, T, D) → (B, T, D)，每个 token 的查询向量
        K = self.W_K(x)                     # (B, T, D) → (B, T, D)，每个 token 的键向量
        V = self.W_V(x)                     # (B, T, D) → (B, T, D)，每个 token 的值向量

        # ---------- 第 2 步：拆分为多头 ----------
        # view:   (B, T, D) → (B, T, n_heads, d_head)
        # transpose: 交换维度 1 和 2 → (B, n_heads, T, d_head)
        # 此后每个头独立拥有 T × d_head 的 Q/K/V 子空间
        Q = Q.view(B, T, self.n_heads, self.d_head).transpose(1, 2)
        K = K.view(B, T, self.n_heads, self.d_head).transpose(1, 2)
        V = V.view(B, T, self.n_heads, self.d_head).transpose(1, 2)

        # ---------- 第 3 步：计算注意力得分 S = Q · Kᵀ ----------
        # Q: (B, n_heads, T, d_head), Kᵀ: (B, n_heads, d_head, T)
        # scores: (B, n_heads, T, T) — 位置 i 和位置 j 之间的原始相似度
        scores = Q @ K.transpose(-2, -1)

        # ---------- 第 4 步：缩放 S / √d_k ----------
        # 除以 √d_k 防止点积值过大，避免 softmax 进入梯度饱和区
        # 在标准配置下 d_head = 64，因此缩放因子 = 8
        scores_scaled = scores / math.sqrt(self.d_head)

        # ---------- 第 5 步：因果掩码（Causal Mask）----------
        # 自回归语言模型要求位置 i 只能看到 ≤ i 的 token（不可预先获取未来信息）
        # torch.triu(..., diagonal=1) 生成上三角矩阵（对角线以上为 True）
        # 例如 T=4 时:
        #   [[F, T, T, T],
        #    [F, F, T, T],
        #    [F, F, F, T],
        #    [F, F, F, F]]
        mask = torch.triu(torch.ones(T, T), diagonal=1).bool()
        # 掩码位置填充 -inf，经 softmax 后权重≈0，即“禁止关注”
        scores_scaled = scores_scaled.masked_fill(mask, float("-inf"))

        # ---------- 第 6 步：Softmax 归一化 ----------
        # 沿最后一维（key 方向）做 softmax，得到注意力权重分布 α
        # 每行权重之和 = 1
        alpha = F.softmax(scores_scaled, dim=-1)

        # ---------- 第 7 步：加权求和 output = α · V ----------
        # α:  (B, n_heads, T, T)     — 注意力权重
        # V:  (B, n_heads, T, d_head) — 值向量
        # out: (B, n_heads, T, d_head) — 加权后的上下文表示
        out = alpha @ V

        # ---------- 第 8 步：合并多头 ----------
        # transpose: (B, n_heads, T, d_head) → (B, T, n_heads, d_head)
        # contiguous + view: 展平为 (B, T, n_heads * d_head) = (B, T, D)
        out = out.transpose(1, 2).contiguous()
        out = out.view(B, T, D)

        # ---------- 第 9 步：输出投影 ----------
        out = self.W_O(out)                # W_O 融合来自不同头的信息

        # 根据 return_attention 标志决定返回内容
        if return_attention:
            return out, Q, K, V, scores, scores_scaled, alpha

        return out


# ============================================================
# 4. FeedForward — 前馈网络
# ============================================================
class FeedForward(nn.Module):
    """
    位置式前馈网络（Position-wise Feed-Forward Network）。
    对每个位置的表示独立应用两层全连接 + ReLU 激活:
        FFN(x) = ReLU(x·W₁ + b₁)·W₂ + b₂
    中间维度 d_ff 通常为 d_model 的 4 倍 (512 → 2048)，扩展后压缩回原维度。
    """

    def __init__(self, d_model, d_ff):
        """
        参数:
            d_model: 输入/输出维度
            d_ff:    中间隐藏层维度（通常是 d_model 的 4 倍）
        """
        super().__init__()

        self.net = nn.Sequential(
            nn.Linear(d_model, d_ff),      # 升维：d_model → d_ff (512 → 2048)
            nn.ReLU(),                      # 非线性激活函数，引入非线性
            nn.Linear(d_ff, d_model)        # 降维：d_ff → d_model (2048 → 512)
        )

    def forward(self, x):
        return self.net(x)


# ============================================================
# 5. TransformerBlock — Transformer 块
# ============================================================
class TransformerBlock(nn.Module):
    """
    一个完整的 Transformer 块，采用 Pre-Norm 残差结构：

        x  →  LayerNorm  →  MultiHeadAttention  →  +  →  x'
        x' →  LayerNorm  →  FeedForward         →  +  →  x"

    Pre-Norm（先归一化再子层）相比 Post-Norm 训练更稳定。
    """

    def __init__(self, d_model, n_heads, d_ff):
        """
        参数:
            d_model: 模型隐藏维度
            n_heads: 注意力头数
            d_ff:    前馈网络中间层维度
        """
        super().__init__()

        # 第一个 Pre-Norm 子层: LayerNorm + MultiHeadAttention
        self.ln1 = nn.LayerNorm(d_model)     # 层归一化，沿最后一维标准化
        self.attn = MultiHeadAttention(d_model, n_heads)

        # 第二个 Pre-Norm 子层: LayerNorm + FeedForward
        self.ln2 = nn.LayerNorm(d_model)
        self.ffn = FeedForward(d_model, d_ff)

    def forward(self, x, return_attention=False):
        """
        前向传播。

        参数:
            x:                输入张量 (B, T, D)
            return_attention: 是否传递至注意力层以捕获中间值

        返回:
            普通模式: 输出张量 (B, T, D)
            注意力模式: (输出, Q, K, V, scores, scores_scaled, alpha)
        """
        if return_attention:
            # 需要捕获注意力中间值:
            #   先 LayerNorm，再注意力（同时返回注意力中间值），最后残差连接
            attn_out, Q, K, V, scores, scores_scaled, alpha = \
                self.attn(self.ln1(x), return_attention=True)

            x = x + attn_out                # 残差连接 1: x + Attention(LayerNorm(x))
            x = x + self.ffn(self.ln2(x))  # 残差连接 2: x + FFN(LayerNorm(x))

            return x, Q, K, V, scores, scores_scaled, alpha

        else:
            # 普通前向: 不捕获中间值
            x = x + self.attn(self.ln1(x))  # 残差连接 1
            x = x + self.ffn(self.ln2(x))   # 残差连接 2

            return x


# ============================================================
# 6. GPT — 自回归语言模型
# ============================================================
class GPT(nn.Module):
    """
    微型 GPT（Generative Pre-trained Transformer）模型。

    架构组成:
        Token Embedding → 与 Position Embedding 相加
        → N 层 TransformerBlock
        → 最终 LayerNorm
        → 线性投影头（输出词表维度 logits）

    通过 return_attention=True 可以捕获第一层 TransformerBlock 的注意力中间值，
    用于可视化分析和教学演示。
    """

    def __init__(
        self,
        vocab_size,                         # 词表大小，此处为 4
        d_model=512,                        # 隐藏维度
        n_heads=8,                          # 注意力头数
        n_layers=6,                         # Transformer 块数
        d_ff=2048,                          # FFN 中间维度
        max_len=128                         # 支持的最大序列长度
    ):
        super().__init__()

        # Token Embedding: 将字符索引映射为 d_model 维稠密向量
        self.token_embedding = nn.Embedding(vocab_size, d_model)
        # Position Embedding: 为位置 0~max_len-1 各分配一个可学习的嵌入向量
        # 使模型感知 token 的相对/绝对位置（Transformer 本身无序列感知能力）
        self.position_embedding = nn.Embedding(max_len, d_model)

        # 用 ModuleList 而非 Sequential，以便按索引遍历并取出特定层输出
        self.blocks = nn.ModuleList([
            TransformerBlock(d_model, n_heads, d_ff)
            for _ in range(n_layers)        # 堆叠 n_layers=6 个 Transformer 块
        ])

        # 最终层归一化：在所有 Transformer 块之后、输出投影之前稳定分布
        self.ln_f = nn.LayerNorm(d_model)
        # 输出投影头：将 d_model 维隐藏状态映射回 vocab_size 维，得到每个 token 的 logits
        self.head = nn.Linear(d_model, vocab_size)

    def forward(self, idx, return_attention=False):
        """
        前向传播。

        参数:
            idx:              输入 token 索引，形状 (B, T)
            return_attention: 是否返回第一层 TransformerBlock 的注意力中间值

        返回:
            if return_attention=False: logits, 形状 (B, T, vocab_size)
            if return_attention=True:  (logits, (Q, K, V, scores, scores_scaled, alpha))
        """
        B, T = idx.shape                    # B=批次大小, T=序列长度

        # 生成位置索引 [0, 1, 2, ..., T-1]，形状 (1, T)，移至与 idx 相同设备
        positions = torch.arange(T).unsqueeze(0).to(idx.device)

        # Token 嵌入 + 位置嵌入（逐元素相加）
        token_emb = self.token_embedding(idx)       # (B, T) → (B, T, d_model)
        pos_emb = self.position_embedding(positions)  # (1, T) → (1, T, d_model) → 广播
        x = token_emb + pos_emb                       # 嵌入融合: (B, T, d_model)

        saved = None                         # 用于保存第一层注意力的中间结果

        for i, block in enumerate(self.blocks):
            # 遍历每一层 TransformerBlock
            if return_attention and i == 0:
                # 仅在第一层 (i==0) 捕获注意力中间值供分析
                x, Q, K, V, scores, scores_scaled, alpha = \
                    block(x, return_attention=True)
                saved = (Q, K, V, scores, scores_scaled, alpha)
            else:
                x = block(x)                # 其余层正常前向

        x = self.ln_f(x)                    # 最终 LayerNorm

        logits = self.head(x)               # (B, T, d_model) → (B, T, vocab_size)

        if return_attention:
            return logits, saved            # 返回预测值 + 第一层注意力数据

        return logits


# ============================================================
# 7. 模型实例化与优化器/损失函数配置
# ============================================================
model = GPT(                                # 实例化 GPT 模型
    vocab_size=vocab_size,                  # 词表大小 = 4
    d_model=d_model,                        # 维度 = 512
    n_heads=n_heads,                        # 8 个注意力头
    n_layers=n_layers,                      # 6 层 Transformer
    d_ff=d_ff                               # FFN 中间维度 = 2048
)

optimizer = optim.Adam(model.parameters(), lr=1e-4)  # Adam 优化器，学习率 0.0001
loss_fn = nn.CrossEntropyLoss()                      # 交叉熵损失：衡量 logits 与目标分布的差距

# ============================================================
# 8. 训练循环
# ============================================================
for epoch in range(1000):                  # 训练 1000 个 epoch

    optimizer.zero_grad()                   # 清空上一轮的梯度缓存

    logits = model(data)                    # 前向传播：输入 [0,1,2,3] → logits (1,4,4)

    # 计算交叉熵损失
    # logits.view(-1, vocab_size): (1*4, 4) = (4, 4)  — 展平为 4 个样本，每个 4 类
    # target.view(-1):            (1*4,)  = (4,)      — 展平为 4 个目标标签
    loss = loss_fn(
        logits.view(-1, vocab_size),
        target.view(-1)
    )

    loss.backward()                         # 反向传播：计算所有参数的梯度
    optimizer.step()                        # 参数更新：沿梯度方向优化

    if epoch % 100 == 0:                   # 每 100 轮输出一次当前损失
        print(f"\nEpoch {epoch}, loss={loss.item():.6f}")

# ============================================================
# 9. 推理与注意力可视化
# ============================================================
with torch.no_grad():                       # 推理阶段禁用梯度计算，节省显存

    # 推理时设置 return_attention=True，捕获第一层注意力的中间值
    logits, saved = model(data, return_attention=True)

    # argmax 取每个位置 logits 最大的索引，即模型预测的下一个字符
    pred = torch.argmax(logits, dim=-1)    # (1, 4, 4) → (1, 4)

    # 解包保存的注意力中间值
    Q, K, V, scores, scores_scaled, alpha = saved

    # ---------- 打印输入/输出 ----------
    print("\n==============================")
    print("输入")
    print("==============================")
    print([idx2char[i.item()] for i in data[0]])   # 索引还原为汉字

    print("\n==============================")
    print("预测")
    print("==============================")
    print([idx2char[i.item()] for i in pred[0]])

    # ---------- 可视化第一层注意力 ----------
    # 以下取 batch=0, head=0 的数据展示注意力计算全过程

    print("\n==============================")
    print("Q")
    print("==============================")
    print(Q[0, 0].detach().numpy().round(3))       # 第 0 个 batch 第 0 个头: (T, d_head)

    print("\n==============================")
    print("K")
    print("==============================")
    print(K[0, 0].detach().numpy().round(3))

    print("\n==============================")
    print("V")
    print("==============================")
    print(V[0, 0].detach().numpy().round(3))

    print("\n==============================")
    print("scores = QK^T")                          # S = Q · Kᵀ，原始相似度
    print("==============================")
    print(scores[0, 0].detach().numpy().round(3))   # (T, T) 矩阵，每行是查询对各键的得分

    print("\n==============================")
    print("scores_scaled")                          # S / √d_k，缩放后
    print("==============================")
    print(scores_scaled[0, 0].detach().numpy().round(3))

    print("\n==============================")
    print("softmax alpha")                          # α = softmax(S_scaled)
    print("==============================")
    print(alpha[0, 0].detach().numpy().round(3))    # 每行和≈1，因果掩码使 α[i][j>i]=0
```

程序输出结果示例：

```python
Epoch 0, loss=2.033882

Epoch 100, loss=0.000004

Epoch 200, loss=0.000001

Epoch 300, loss=0.000001

Epoch 400, loss=0.000001

Epoch 500, loss=0.000001

Epoch 600, loss=0.000001

Epoch 700, loss=0.000001

Epoch 800, loss=0.000001

Epoch 900, loss=0.000001

==============================
输入
==============================
['你', '好', '世', '界']

==============================
预测
==============================
['好', '世', '界', '你']

==============================
Q
==============================
[[-0.35  -0.407 -0.483  0.202 -1.21   0.052 -0.176 -0.561 -0.954  0.093
  -0.656  0.312 -0.605  0.628 -0.073 -0.659 -0.658 -0.503  0.324  0.06
  -0.949  0.006 -0.826 -0.279 -0.249 -0.938  0.166 -1.03  -0.397 -0.074
  -0.224 -0.779  0.28  -0.599 -0.993 -1.21  -1.172  0.522  0.781  0.627
   0.02   0.964  0.134  0.466 -0.597 -0.354  1.265  0.147  0.153 -0.168
  -0.758 -1.047 -0.158 -0.468  0.3   -0.336 -0.627  0.59  -0.605  0.138
   0.853 -0.566  0.453  1.011]
 [ 0.27  -0.235 -1.544 -0.038 -0.234  0.129 -0.311 -0.97  -0.243  0.366
   0.974 -0.945  1.132 -0.288  0.058  0.435 -1.075  0.144 -0.33   0.04
   0.292  0.917  0.534  0.309  0.005  1.361 -0.053  1.036  0.357  0.03
  -1.367  1.261  0.283 -1.16   0.064  0.076  0.333 -0.472  0.25   0.676
   0.645 -0.466 -0.35   0.288 -0.622 -0.433  0.905 -0.78  -0.267  0.335
  -0.605  1.117  1.436 -0.976  0.721 -0.072 -0.166  0.609  0.454 -0.149
  -0.154 -0.668  0.161 -0.913]
 [ 0.581  0.029 -0.121  0.056 -0.817  0.408  0.55   0.592  0.344  0.392
  -0.727  0.332 -0.747  0.111  0.192 -0.743  0.444  0.83   0.271  0.468
  -0.137 -0.249  0.421 -0.437 -0.49   0.057  1.117  0.208 -0.024  0.32
  -0.607 -1.125 -0.129  0.433 -0.024  0.241 -0.815 -0.317 -0.91  -0.111
   1.066  0.623 -0.157 -0.078  0.192  0.671 -0.932  0.325 -0.445  0.267
  -0.302 -0.772 -0.207  0.422 -0.264  0.245 -0.51   0.083 -0.671  0.297
  -0.732 -0.329  0.484  0.396]
 [-0.164 -0.309  0.665  0.228  0.476  0.356  0.508 -0.426  0.738 -1.743
   0.765 -1.036  0.976  0.177  0.305 -0.756 -0.159 -0.67   0.28  -0.417
   0.269 -1.157  0.675  0.042 -0.181  0.131  0.475  0.959 -0.266 -0.379
  -0.019  0.514 -0.391  0.601 -0.263  0.054  0.207  0.211 -0.374  1.04
  -0.138  0.116 -0.39   0.163 -0.706 -0.45  -0.003 -0.221 -0.198 -0.205
   0.011 -0.605  0.984 -0.19   0.639 -0.172  0.391  0.23  -0.836  0.388
  -0.843  0.875  1.419  1.416]]

==============================
K
==============================
[[-0.758  0.836  1.233 -0.518  1.507 -0.171  0.372  1.24  -0.012  0.445
  -0.646  0.797 -1.395 -0.258 -0.864  1.3    0.911  0.249  0.716  0.063
  -0.287  0.377 -0.545 -0.265  0.266 -1.027 -0.283 -0.82  -1.036 -0.487
   0.696  0.463 -0.023 -0.2    0.003 -0.34   0.028 -0.417 -0.254  0.457
  -0.762  0.02   0.358 -0.576  0.728 -0.    -0.277  0.591  0.231 -0.004
   0.678  0.182 -0.355  0.832 -0.75  -0.295  0.176 -0.704  0.651 -0.327
  -0.286 -0.435 -0.667 -0.421]
 [-0.367  0.32  -0.186 -0.378 -0.099  0.194  0.173 -0.819 -0.245  0.213
   0.657  0.48  -0.556 -0.199  0.147  0.707 -0.712 -0.05  -0.426 -0.776
  -0.975 -0.009  1.464 -0.459  0.894 -0.531  0.331  0.945 -0.772 -0.308
  -1.053  0.235 -0.061 -0.689  0.808  1.045 -1.145 -0.563  0.35   0.508
   0.531 -0.083 -1.198 -0.17   0.603 -0.352  0.115 -0.765 -0.331 -0.01
  -0.155 -0.298  0.175 -0.224  0.238 -0.13  -0.169  0.69  -1.039 -0.211
  -0.962 -0.051  0.119  0.095]
 [-1.209 -0.033  0.01   0.999 -0.245 -0.039  0.07  -0.573 -0.168 -0.506
   0.262 -0.775  0.129  0.323 -0.973 -0.38  -0.042 -0.542 -0.859  0.274
   0.533 -0.437 -0.169 -0.279 -0.091 -0.663  0.257 -0.414 -0.418  0.152
   0.11   0.647 -0.328 -0.307  0.3   -0.767 -0.319  0.01  -0.304  0.964
   0.459 -0.167  0.375 -0.713 -0.56  -0.774  0.093  0.444  0.294 -0.894
  -0.624 -0.389  0.906 -0.127  0.104 -0.849  0.852 -0.373  0.257 -0.362
  -0.849 -0.226 -0.101  0.524]
 [-0.113  0.098 -1.399 -0.02  -0.138 -0.146 -0.012  0.238 -0.635  0.471
  -0.496  0.014  0.286 -0.013 -0.101  0.229 -1.211 -0.011  0.656  0.288
   0.015  1.026 -0.975 -0.086  0.849 -0.453 -0.008 -0.421  0.008  0.809
   0.159  0.371 -0.331 -0.861  0.488 -0.312  0.251 -0.362 -0.15   0.226
  -0.11  -1.087  0.258 -0.936  1.026 -0.263 -0.249 -0.646  0.053  0.126
   0.028  0.064 -0.741  0.314  0.544 -0.04  -0.123  0.305 -0.596 -0.908
  -0.176 -0.341 -0.923  0.163]]

==============================
V
==============================
[[-0.67  -0.117 -1.085 -0.536  1.016  0.047  0.154 -0.087  0.926 -0.14
   0.781 -0.443  0.172 -0.433 -0.567  0.666 -0.321  0.173 -0.428 -0.357
  -0.559 -0.221  0.138 -0.469  0.326 -0.691  0.647  0.108  0.062 -0.926
  -0.424 -0.87   0.053 -1.048  0.652 -0.798 -0.27   0.211 -0.281 -0.317
   0.637 -0.954 -0.274 -0.991  0.6    0.093  0.044 -1.527 -0.575 -0.087
   0.494 -0.896  0.691 -1.437 -0.675 -0.253 -0.193 -0.758 -0.29  -1.044
  -0.631 -0.194  0.17   0.962]
 [-0.193  0.785  0.281  1.047 -0.778 -0.042  0.493 -0.989 -0.119  0.309
  -0.724 -0.085 -0.068 -0.205  0.213  1.236  0.288  1.454 -0.181 -0.452
   0.334  0.37  -0.163  0.507  0.01   0.317  0.442  0.108  0.258 -0.605
   0.597  0.36  -0.311  0.552 -0.37   0.423  1.258 -0.014  0.607  0.109
   0.078 -0.015 -0.743  0.727  0.526  0.137  0.076  0.581 -0.797 -0.633
  -1.153  0.331 -0.329  0.178 -0.325 -1.605  0.141  0.207  1.123 -0.171
  -0.499  0.082 -0.06  -0.245]
 [-0.05   0.524 -0.457 -0.141 -0.514 -0.749  0.284 -0.071  0.072 -0.255
  -0.066 -0.178  0.629  0.028  0.027 -0.088 -0.594  0.894 -0.834  0.163
  -0.85  -0.203  0.152 -0.006 -0.053  0.338 -0.117  0.177 -0.059 -0.246
   0.522 -0.267  0.842  0.308 -0.153  0.036 -0.091  0.693  0.592  0.425
   0.679  0.323  0.123 -0.902  0.734  0.215 -0.396 -0.322  0.013  0.511
   0.352 -0.016 -0.481  0.078  0.021 -0.197  0.624 -0.753 -0.083  0.389
   0.226  0.331  0.727 -0.86 ]
 [-0.219  0.152 -0.382  0.197 -0.753 -0.36  -0.544 -0.78   0.7   -0.306
  -0.269  0.145 -0.222  0.287 -0.851 -0.078 -0.227  0.145 -0.272  0.687
   0.432  0.179 -1.144  0.775 -1.057 -0.776  0.556  0.788  0.059  1.002
  -1.004 -0.037 -0.441 -0.011  0.488 -0.348 -0.531  0.883  0.063 -0.765
  -0.091  0.13  -0.484 -1.145  0.331  0.787  0.875 -0.226  0.819 -0.523
  -1.217 -0.296 -0.068 -0.378  0.773  0.452 -0.011 -0.157  0.278 -0.372
  -0.036  0.179 -0.251  0.309]]

==============================
scores = QK^T
==============================
[[ -4.192   0.67    3.931   1.269]
 [-13.375   6.972   1.766   3.113]
 [ -2.067   2.363  -2.743  -2.388]
 [ -9.26    3.297   6.765  -7.769]]

==============================
scores_scaled
==============================
[[-0.524   -inf   -inf   -inf]
 [-1.672  0.871   -inf   -inf]
 [-0.258  0.295 -0.343   -inf]
 [-1.158  0.412  0.846 -0.971]]

==============================
softmax alpha
==============================
[[1.    0.    0.    0.   ]
 [0.073 0.927 0.    0.   ]
 [0.273 0.475 0.251 0.   ]
 [0.069 0.333 0.514 0.084]]
```

上述代码实现了微型 **GPT（自回归语言模型）**：给定“你”预测“好”，给定“你好”预测“世”，依此类推。经过 1000 轮训练，交叉熵损失从 2.033882 降至 0.000001，模型精确习得了序列 `['你', '好', '世', '界']` → `['好', '世', '界', '你']` 的移位关系。

模型严格符合标准 **缩放点积注意力**（Scaled Dot-Product Attention）的数学定义：

$$
\mathrm{Attention}(Q,K,V) =
\mathrm{softmax}\left( \frac{Q K^\top}{\sqrt{d\_k}} \right) V
$$

在代码中的对应关系如下。

**Q、K、V 生成**

$$
Q = W\_Q , x,\quad K = W\_K , x,\quad V = W\_V , x
$$

源代码中 `Q = self.W_Q(x)`、`K = self.W_K(x)`、`V = self.W_V(x)` —— 三者从同一输入 `x` 经线性投影得到，即自注意力。由于：

$$
d\_{\mathrm{model}} = 512, \quad n\_{\mathrm{heads}} = 8
$$

$$
d\_k = d\_{\mathrm{head}} = \frac{d\_{\mathrm{model}}}{n\_{\mathrm{heads}}} = \frac{512}{8} = 64
$$

投影结果被拆分为 8 头，每头维度

$$
d\_k = 64
$$

（代码 `Q.view(B, T, self.n_heads, self.d_head).transpose(1, 2)`）。

输出仅展示了第一个注意力头（`head=0`）的 Q、K、V、scores 和 alpha，便于读者追溯完整的计算链路。

**相似度与缩放**

$$
S = Q K^\top, \qquad S\_\mathrm{scaled} = \frac{S}{\sqrt{d\_k}}
$$

对应源代码 `scores = Q @ K.transpose(-2, -1)` 与 `scores_scaled = scores / math.sqrt(self.d_head)`。

**因果掩码（Causal Mask）**

```python
mask = torch.triu(torch.ones(T, T), diagonal=1).bool()
scores_scaled = scores_scaled.masked_fill(mask, float("-inf"))
```

上三角置 `-∞`，迫使位置 `i` 只能关注位置 `0,…,i`：这是自回归模型的根本约束——预测下一个词元时不可预先获取未来信息。scaled 矩阵中的 `-inf` 正是这一约束的直观体现。

**Softmax 归一化**

$$
A = \mathrm{softmax}(S\_\mathrm{scaled})
$$

对应 `alpha = F.softmax(scores_scaled, dim=-1)`。由于

$$
e^{-\infty} = 0
$$

mask 位置权重为零；其余位置非负且和为 1，构成合法概率分布：

$$
\begin{array}{rl}
\text{位置 0（你）} &: \[1.000,, 0,, 0,, 0] \\
\text{位置 1（好）} &: \[0.073,, 0.927,, 0,, 0] \\
\text{位置 2（世）} &: \[0.273,, 0.475,, 0.251,, 0] \\
\text{位置 3（界）} &: \[0.069,, 0.333,, 0.514,, 0.084]
\end{array}
$$

**加权求和输出**

$$
\mathrm{output} = A V
$$

对应 `out = alpha @ V`，随后合并多头、经 `W_O` 投影输出。

**前馈网络（FFN）**

```python
nn.Linear(512, 2048), nn.ReLU(), nn.Linear(2048, 512)
```

$$
d\_\mathrm{ff} = 4 \times d\_\mathrm{model} = 2048
$$

与原始论文一致。

**残差连接与层归一化**

```python
x = x + self.attn(self.ln1(x))   # Pre-LayerNorm
x = x + self.ffn(self.ln2(x))
```

等同于

$$
\mathrm{LayerNorm}(x + \mathrm{Sublayer}(x))
$$

的 Pre-LN 变体。

**规模对比**

本例仅 4 个词元

$$
d\_\mathrm{model} = 512, \quad n\_\mathrm{layers} = 6, \quad n\_\mathrm{heads} = 8
$$

与原始 Transformer 论文的 base 配置完全一致，证明即便是极小规模的序列，只要数学结构正确，Transformer 同样能够完美收敛。

## 人工智能哲学

以下摘录与该主题相关的哲学原著原文。

### 人类理智研究

休谟. 人类理智研究\[M]. 吕大吉, 译. 北京: 商务印书馆, 1999. ISBN 978-7-10002-618-5.

#### 第四章第一节二十三

如果我们要想使自己满意于那种使我们确信实际的事情的确实性的本质，我们就必须研究，我们究竟是怎样得到关于原因与结果的知识的。

我要大胆地提出一个没有例外的一般命题：我们关于因果关系的知识，在任何情况下都不是从 **先验** 的推理获得的，而是完全产生于经验，即产生于当我们看到一切特殊的对象恒常地彼此联结在一起的那种经验。一个人不管他有多么强烈的自然理性和才能，如果在他面前的对象对他说来完全是新的，那末，即使他极其精细地考察它的可感性质，他也不能发现出关于这个对象的任何原因和结果。即使我们假定亚当的理性官能一开始就是十分完美的，他也不能根据水的流动性和透明性而推论出水会把他窒息，或者根据火的光明和温暖就推论出火会把他化为灰烬。任何对象都不能借其呈现于感官的性质，显露其所由产生的原因或由之而生的结果。我们的理性如果离开经验的帮助，也不能作出关于真实的存在和事实的任何推论。

#### 第四章第二节二十八

对于我们第一次提出的问题，我们至今尚未得到任何差强人意的解答。每一个解答都仍然会产生一个与过去的问题同样困难的新问题，引导我们作更进一步的研究。如果有人问：**我们关于实际事情的一切推论的本性是什么？** 适当的答复似乎是，这些推论是建立在因果关系之上的。如果再问：**我们关于因果关系的一切推论和结论的基础是什么？** 就可以用一个词来回答：“经验”。但是如果我们再进一步追根究底地问：**由经验得来的一切结论的基础是什么？** 这就包含了一个新问题，这个问题可能更难以解决和解释。

……

#### 第四章第二节二十九

下面两个命题绝不是一样的：

> **我曾经见到这样一个事物总是有这样一个结果跟随着。**
>
> **我预先见到别的表面上相似的事物也会有相似的结果跟随着。**

#### 第五章第一节三十六

因此，习惯是人类生活中的伟大指南。只有这个原则才能使我们的经验对我们有用，使我们能期待将来出现一连串事件，与过去出现的事件相似。如果没有习惯的影响，我们除了直接呈现于记忆和感觉的东西而外，对于其它的事实就会一无所知；我们就会根本不知道如何使手段适应目的，或者运用我们的自然能力来产生任何效果；一切行动都会立刻终止，思辩的主要部分也会终止了。

#### 第七章第二节六十

……

因此，根据这个经验我们就可以将“原因”恰当地定义为：\*\*原因是一种有另一种对象随之而来的对象，并且在所有类似于第一种对象的地方，都有类似于第二种的对象随之而来。\*\*换句话说，如果第一个对象不存在，第二个对象也一定不存在。一种原因的出现，总是凭借习惯性的推移，使心灵转到结果的观念上。对于这一点我们也是有经验的。因此，根据这个经验我们可以给原因再下一个定义：**所谓原因就是一种有另一对象随之而来的对象，它的出现总是使思想转到那另一对象上面。**

……

例如，我们说，这条琴弦的振动，是这个特殊的声音的原因。可是我们下的这个断言是什么意思呢？我们的意思或者是说：\*\*这个振动是有这个声音随之而来的、而且凡是类似的振动都有类似的声音随之而来；或者是说：这个振动有这个声音随之而来，而且振动一出现，心灵就预期着感觉，并且立刻形成声音的观念。\*\*我们可以根据这两点观点中的任一种观点来考察因果关系，除此之外，我们对于因果关系没有任何观念

### 人是机器

心灵的一切作用既然是这样地依赖着脑子和整个身体的组织，那么很显然，这些作用不是别的，就是这个组织本身：这是一架多么聪明的机器！因为即使唯有人才分享自然的法则，难道人因此便不是一架机器么？比最完善的动物再多几个齿轮，再多几条弹簧，脑子和心脏的距离成比例地更接近一些，因此所接受的血液更充足一些，于是那个理性就产生了；难道还有什么别的不成？有一些不知道的原因，总是会产生出那种精致的、非常容易受损伤的良知来，会产生出那种羞恶之感来，而后者距离物质还没有思想距离物质远，总之，会产生出人们在这里所假定的一切差别。那么组织便足以说明一切么？是的，我再说一遍，组织足以说明一切。因为既然思想是很明显地随着器官的发展而发展起来的，那么，那造成器官的物质当随着时间的进展而一旦获得了感觉的功能的时候，为什么不同样可以感受羞恶的感情呢？

——拉·梅特里. 人是机器\[M]. 顾寿观译. 北京: 商务印书馆, 2011-7. 54-55. ISBN 978-7-1000-7896-2.

### 图灵测试

问题的新形式可以用一种我们称之为“模仿游戏”的游戏来描述。游戏由三个人参与：一名男性（A）、一名女性（B）以及一名审问者（C），审问者可以是任何性别。审问者与另外两人待在不同的房间中。审问者在游戏中的目标是判断哪一个是男性，哪一个是女性。他通过 X 和 Y 这两个标签标记他们，并在游戏结束时说出“X 是 A（男），Y 是 B（女）”或“X 是 B（女），Y 是 A（男）”。审问者可以向 A 和 B 提出如下问题：

C：请 X 告诉我他（她）的头发长度？

假设 X 实际上是 A（男），那么 A（男）也必须回答。在游戏中，A（男）的目标是让 C 做出错误的判断。因此他的回答可能是：

“我的头发层叠式修剪，最长的发丝大约有九英寸长。”

为了避免语音语调帮助审问者判断，应当以书面形式给出答案，最好是打字形式。理想的安排是两个房间之间通过电传打字机通信。或者问题和答案也可以由中间人传递。第三名玩家（B，女）在游戏中的目标是帮助审问者。她的最佳策略很可能是给出真实的答案。她也可以在回答中添加诸如“我是女性，不要听他的！”之类的话，但这没有作用，因为男性也可以做出类似的说法。

现在我们提出问题：“当机器在这个游戏中扮演男性（A）的角色时，会发生什么？”当游戏这样进行时，审问者会像在男女之间进行游戏时一样经常做出错误判断吗？这些问题取代了我们原先的问题：“机器能思考吗？”

——Turing A. M. Computing Machinery and Intelligence\[J]. Mind, 1950, LIX(236): 433–460. DOI: 10.1093/mind/LIX.236.433.

### 中文房间

测试任何心智理论的一种方法是问自己，如果我的心智真的按照该理论所说的原则运作，会是什么样子。让我们用以下思想实验将这个测试应用到 Schank 程序上。假设我被关在一个房间里，得到一大批中文书写材料。进一步假设（事实上确实如此）我既不懂中文书写，也不懂中文口语，甚至不确定自己能否将中文书写识别为中文，而不是日文书写或毫无意义的符号。对我而言，中文书写只是许多毫无意义的符号。

现在假设，在得到第一批中文书写后，我又得到第二批中文材料，以及一套将第二批与第一批关联的规则。这些规则用英文写成，我像任何其他母语英语者一样理解它们。它们使我能够将一组形式符号与另一组形式符号相关联，这里的“形式”仅指我可以完全根据符号形状来识别它们。

再假设我还得到第三批中文符号，以及一些英文说明，使我能够将第三批元素与前两批关联，并指导我如何根据第三批中给出的某些符号形状返回具有特定形状的中文符号。我并不知道，给我这些符号的人将第一批称为“脚本”，第二批称为“故事”，第三批称为“问题”。此外，他们将我根据第三批返回的符号称为“问题答案”，而他们给我的那套英文规则则称为“程序”。

为了让情境更复杂，想象这些人还给我英文故事，我能理解，然后他们用英文就这些故事向我提问，我用英文回答他们。假设随着时间推移，我在遵循操作中文符号的指令上越来越熟练，程序员在编写程序上也越来越熟练，以至于从外部观察者角度——即关着我的房间外的人来看——我对中文问题的回答与母语中文使用者完全无法区分。仅凭我的回答，没有人能判断我一句中文都不会。

同样，我对英文问题的回答，也如预期，与其他母语英语者无异，原因很简单，因为我是英语母语者。从外部观察者的角度来看，我对中文问题和英文问题的回答同样出色。但在中文的情况下，与英文不同，我是通过操作未解释的形式符号生成答案的。就中文而言，我完全像计算机一样运作；我对形式化指定的元素执行计算操作。对于中文问题，我只是计算机程序的具体化实例。

——Searle J. R. Minds, brains, and programs\[J]. Behavioral and Brain Sciences, 1980, 3: 417–457.

### 哲学研究

维特根斯坦. 哲学研究\[M]. 楼巍, 译. 上海: 上海人民出版社, 2019. ISBN: 978-7-208-15748-4.

#### §7

在语言的使用实践中，一方喊出那个词，另一方依照它来行动。然而，在语言教学中也会出现这样的事：学习者说出这些对象的名称。换言之就是：当老师指向一种石料的时候，他说出那个词。——确实，这里还会有更简单的练习：学生跟着老师念一个词——这两者都是与说话相类似的事情。

我们也可以设想中使用语言的整件事是某些游戏中的一种，孩子就是通过这些游戏来学习母语的。我想把这些游戏称为“语言游戏”，有时我也将一种原始的语言称为一种语言游戏。

说出石料的名称，跟着念一些词，这些事情也可以被称为语言游戏。想一想词语在跳圈圈游戏中的一些用法吧。

我也会把那个由语言以及与语言交织在一起的那些行为构成的整体称为“语言游戏”。

#### §219

“所有的过渡事实上都已经完成”的意思是：我已经没有选择。这个规则一旦被标上了某种特定的意义，就在整个空间中划定了一条遵循规则的线路。——但是就算某个东西真的是这样的，它对我又有什么帮 助呢？

不，我的描述只有被理解为某种象征，才有意义。——我应该说：在我看来是这样的。

当我遵从规则的时候，我并不选择。

我盲目地遵从规则。

#### §359

一台机器会思考吗？——它能够有疼痛吗？——好吧，该不该把人体称为这样的一台机器呢？它的确十分接近于这样的一台机器。

#### §360

但一台机器肯定是不会思考的！——这是一个经验命题吗？不。只有说到人，以及与人相类似的东西，我们才说他思考。我们也这样说洋娃娃，也许也这样说精灵。请把“思考”一词当作工具！

### 机器人的权利

机器人是否应与我们一样拥有权利？人类具备智慧与自我意识，因而享有权利。如果机器人同样具备这些特质，是否也应享有类似的权利？这些问题相当复杂，但在不久的将来必然会对现实中的机器人产生实际影响。如果机器人确实具备自我意识，并展现出真正的智能，就必须将其视为有感知的存在，尊重其愿望与需求，正如尊重人类的权利一般。

如果不承认这些非人类智能的权利，就如同早期西方社会没有承认非欧洲人的人性和权利一样。外表的差异绝不能影响我们对有自我意识、会思考的生命的伦理对待。

然而，即便在今天，这种情况仍然存在。仍有一些人否认某些民族的基本权利——生命、自由和追求幸福。那么，有智慧的机器能否有机会争取这些权利？

美国防止机器人虐待协会（American Society for the Prevention of Cruelty to Robots, ASPCR）的目标就是让人们意识到智能、自我意识，以及与之相关的伦理问题，这些问题是智能生命不可分割的一部分。

为此，ASPCR 希望提出《机器人权利法案》，并最终建立一个游说团队，让这些权利在社会中得到推动和保护。

如果认为这听起来过于“科幻”而难以相信，可以回顾 ASPCA（美国防止虐待动物协会）。它于 1866 年成立时，也曾因为敢于主张“愚蠢”的动物也有权利而被人嘲笑。

然而，仅仅一百年后，ASPCA 已在全球设有很多分会，在华盛顿有活跃的游说团队，年预算数千万美元，并有庞大的实体机构（包括自己的警察、调查员和检察官），确保虐待动物的人不会逍遥法外。

随着有自我意识的人工智能逐渐成为现实，ASPCR 的使命会越来越重要，也有望使我们理所当然享有的权利，同样适用于所有智慧的生命，不论它们是不是“人工”创造的。

——ASPCR. Robotic Bill of Rights\[EB/OL]. \[2026-05-10]. <http://www.aspcr.com/newcss_rights.html>. 美国防止机器人虐待协会官网。

## 参考文献

* Vaswani A, et al. Attention is All You Need\[C]//Advances in Neural Information Processing Systems 30 (NIPS 2017). Red Hook: Curran Associates, Inc., 2017.
* IBM. 2026 年机器学习指南\[EB/OL]. \[2026-05-10]. <https://www.ibm.com/cn-zh/think/machine-learning#605511093>.

## 课后习题

1. 简述强人工智能与弱人工智能的区别。监督学习、无监督学习与强化学习各自适用于什么场景？请各举一例说明。
2. 图灵测试与中文房间思想实验分别从什么角度探讨了“机器能否思考”这一问题？你更认同哪一种观点，为什么？
3. Transformer 架构中的自注意力机制解决了传统循环神经网络在处理长序列时的什么局限？请用你自己的话解释注意力机制的核心思想。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/di-13-zhang-ren-gong-zhi-neng/di-13.1-jie-ren-gong-zhi-neng-ai-gai-shu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
