查看全课大纲(第 39 / 69 节)
  1. 1.NLP 的研究领域、应用与学习路径
  2. 2.自然语言的基本术语
  3. 3.信息论基础:信息熵与交叉熵
  4. 4.语言的进化与语义变迁
  5. 5.主观概率、客观概率与条件概率
  6. 6.贝叶斯原理与推理
  7. 7.随机变量:二项式、期望方差与联合概率
  8. 8.常见概率分布
  9. 9.辛普森悖论与贝叶斯解题实例
  10. 10.语言模型:语言概率与词袋模型
  11. 11.n-gram 语言模型(二元 / 三元 / N-Gram)
  12. 12.语言模型评价:交叉熵、困惑度与插值
  13. 13.朴素贝叶斯文本分类:垃圾邮件
  14. 14.拼写检查
  15. 15.中文分词:构词法、最大匹配、最优路径与 Jieba
  16. 16.词表示问题与语义相似度
  17. 17.TF-IDF 权重处理
  18. 18.One-Hot 表达与词表示的局限
  19. 19.Word2Vec 核心思想
  20. 20.Word2Vec 训练过程
  21. 21.Skip-gram 模型详解
  22. 22.词性标注任务与标注方法(规则 + N-Gram)
  23. 23.EM 算法与混合模型
  24. 24.高斯混合模型 GMM
  25. 25.从混合模型到隐马尔可夫模型
  26. 26.隐马尔可夫模型(HMM)推导与维特比解码
  27. 27.线性链条件随机场 CRF
  28. 28.贝叶斯网络与图模型
  29. 29.隐马尔可夫链与 HMM 推导
  30. 30.PLSA 主题模型
  31. 31.LSI 与 SVD 向量表达
  32. 32.LDA 与狄利克雷分布
  33. 33.主题模型实验复现(困惑度 / 分类 / 相似度 / 延展)
  34. 34.上下文无关文法(CFG)与句法分析
  35. 35.概率上下文无关文法 PCFG
  36. 36.统计机器翻译:词对齐与翻译模型
  37. 37.统计机器翻译中的对齐模型与参数估计
  38. 38.从统计机器翻译到神经机器翻译
  39. 39.神经元与反向传播速览(指向深度学习课)
  40. 40.CNN 原理及其在 NLP 中的应用
  41. 41.循环神经网络的基本原理与 Elman / Jordan 网络
  42. 42.LSTM:长短期记忆网络的核心思想与分步实现
  43. 43.Encoder-Decoder 框架
  44. 44.Seq2Seq 与早期注意力机制
  45. 45.注意力机制的背景与动机
  46. 46.注意力模型实现原理与匹配函数
  47. 47.记忆网络:组成与计算
  48. 48.注意力机制的应用与历史延展
  49. 49.Transformer 结构:Encoder-Decoder 栈与 Self-Attention
  50. 50.Multi-Head Attention、FFNN 与位置编码
  51. 51.层归一化、损失函数与 Universal Transformer 延展
  52. 52.预训练范式:从 ELMo 到 BERT
  53. 53.BERT 与掩码语言模型
  54. 54.BERT 下游任务微调与 GLUE 口径
  55. 55.GPT 与自回归语言建模
  56. 56.GPT-1 到 GPT-4 的演进
  57. 57.指令微调与 RLHF
  58. 58.分词器:BPE、WordPiece 与中文词表
  59. 59.上下文窗口与长文本处理
  60. 60.能力边界、成本与适用场景
  61. 61.文本分类实战:从朴素贝叶斯到逻辑回归
  62. 62.命名实体识别实战
  63. 63.文本生成与摘要实战
  64. 64.语义检索与向量库实战
  65. 65.RAG 知识库问答
  66. 66.NLP 评估指标:BLEU / ROUGE / BERTScore 与人工评估
  67. 67.幻觉与事实性问题
  68. 68.文本与知识结合(知识图谱压缩)
  69. 69.跨媒体信息检索与未来展望

神经元与反向传播速览(指向深度学习课)

小象实战讲义 · 自然语言处理

在自然语言处理中,我们常常需要建模词语之间复杂的非线性关系,例如预测一个词在给定上下文后出现的概率。传统的统计方法(如 n-gram)难以捕捉这种深层关联。本节将引入神经网络作为解决此类问题的强大工具。我们将从最基本的计算单元——神经元入手,理解其数学本质,并快速了解神经网络如何通过误差反向传播算法进行学习。本节旨在为后续的神经语言模型等高级内容打下基础,更深入的神经网络原理请参考站内《深度学习基础》课程。

💡 核心导读

  • 从统计到神经:理解为何需要引入神经网络来建模语言中复杂的非线性关系。
  • 神经元与逻辑回归的联系:掌握神经元作为基本计算单元的数学形式,即线性加权后接激活函数;只有 sigmoid 二分类概率输出时,单个神经元才等价于逻辑回归。
  • 前馈网络:了解如何将多个神经元连接成层,并通过线性组合与非线性激活的交替堆叠构成前馈神经网络。
  • 反向传播原理:理解通过链式法则将输出误差梯度反向传播至网络各层权重,从而实现参数更新的核心思想。
  • 梯度问题:初步认识梯度消失与梯度爆炸问题,以及 ReLU 等现代激活函数的作用。

神经语言模型的动机

在之前的课程中,我们学习了基于统计的语言模型,例如 n-gram 模型。它的核心是计算一个词序列 W1,W2,...,WmW_1, W_2, ..., W_m 出现的概率 P(W)P(W)。n-gram 模型通过统计频率来近似条件概率,例如 bigram 模型 P(Wi∣Wi−1)P(W_i | W_{i-1}) 或 trigram 模型 P(Wi∣Wi−2,Wi−1)P(W_i | W_{i-2}, W_{i-1})。

然而,词与词之间的关系可能远比简单的统计共现要复杂,它们之间可能存在非线性的依赖关系。对于这种复杂的非线性关系,我们很难预先指定一个精确的数学模型。神经网络,特别是神经语言模型,提供了一种通用的解决方案:我们可以将上下文词(如前 n-1 个词)作为神经网络的输入,而网络的输出则是预测下一个词的概率分布。这种模型能够自动从数据中学习词与词之间的复杂关联模式。

为了理解神经语言模型,我们首先需要回顾神经网络的基本构建块。

神经元:基本计算单元

人工神经网络(Artificial Neural Networks)的灵感来源于生物神经系统,但其本质是一个数学计算模型。其最基本的组成单元是神经元。

一个神经元可以看作一个数学函数,其结构如下图所示(概念图):

输入: x1, x2, ..., xn
        ↓
加权求和: z = (w1*x1 + w2*x2 + ... + wn*xn) + b
        ↓
激活函数: a = σ(z)
        ↓
输出: a

其中:

  • x1,x2,...,xnx_1, x_2, ..., x_n 是输入向量。
  • w1,w2,...,wnw_1, w_2, ..., w_n 是对应的权重(Weight),是需要学习的参数。
  • bb 是偏置(Bias),也是一个需要学习的参数。
  • zz 是输入的线性组合。
  • σσ 是激活函数(Activation Function),一个非线性函数。
  • aa 是神经元的输出。

当激活函数 σσ 是 sigmoid 函数时,这个结构就是一个逻辑回归(Logistic Regression)模型:输出 aa 被压缩到 (0, 1) 区间,可以解释为概率。若换成 tanh、ReLU 等其他激活,同一计算单元就不再是逻辑回归。sigmoid 函数的公式为: σ(z)=11+e−z\sigma(z) = \frac{1}{1 + e^{-z}}

因此,一个神经元就是一个“决策单元”,它通过线性加权和偏置,再经过一个非线性变换,将输入映射到一个输出值。

全连接前馈神经网络

单个神经元能力有限。神经网络通过将许多神经元连接在一起,形成强大的函数逼近器。最常见的一种是全连接前馈神经网络。

网络结构与符号

考虑相邻的两层,第 l−1l-1 层和第 ll 层。

  • 第 l−1l-1 层有 Nl−1N_{l-1} 个神经元,其输出向量记为 al−1=[a1l−1,a2l−1,...,aNl−1l−1]T\mathbf{a}^{l-1} = [a_1^{l-1}, a_2^{l-1}, ..., a_{N_{l-1}}^{l-1}]^T。
  • 第 ll 层有 NlN_l 个神经元。
  • 连接这两层的权重用一个矩阵 Wl\mathbf{W}^l 表示。其元素 wijlw_{ij}^l 表示从第 l−1l-1 层的第 jj 个神经元到第 ll 层的第 ii 个神经元的连接权重。
  • 第 ll 层还有一个偏置向量 bl=[b1l,b2l,...,bNll]T\mathbf{b}^l = [b_1^l, b_2^l, ..., b_{N_l}^l]^T。

前向传播计算

对于第 ll 层的第 ii 个神经元,其输入 zilz_i^l 是上一层所有输出的加权和加上偏置: zil=∑j=1Nl−1wijlajl−1+bilz_i^l = \sum_{j=1}^{N_{l-1}} w_{ij}^l a_j^{l-1} + b_i^l 然后,该神经元的输出 aila_i^l 是: ail=σ(zil)a_i^l = \sigma(z_i^l) 我们可以用矩阵形式简洁地表示整个第 ll 层的计算: zl=Wlal−1+bl\mathbf{z}^l = \mathbf{W}^l \mathbf{a}^{l-1} + \mathbf{b}^l al=σ(zl)\mathbf{a}^l = \sigma(\mathbf{z}^l) 这里 σ\sigma 被应用于向量的每个元素。

通过将多个这样的层堆叠起来,我们就得到了一个深度前馈网络。例如,一个三层网络的计算流程为:

输入 x -> (线性组合 W1, b1) -> z1 -> (激活 σ) -> a1 -> (线性组合 W2, b2) -> z2 -> (激活 σ) -> a2 -> (线性组合 W3, b3) -> z3 -> (激活 σ) -> 输出 y

这个过程就是前向传播。

为何需要激活函数?

激活函数引入了非线性。如果没有非线性激活函数,无论堆叠多少层,整个网络仍然等价于一个线性变换,无法学习复杂的模式。此外,像 sigmoid 这样的激活函数还能将输出值规范到一个固定的范围(如 0 到 1),有助于数值稳定性和概率解释。对于多分类问题,我们通常在最后一层使用 softmax 函数,它是 sigmoid 函数在多维上的推广,可以将输出转化为一个概率分布。

神经网络的强大之处在于其通用近似定理:一个足够大的神经网络可以以任意精度逼近任何连续函数。这意味着我们不需要对数据背后的具体函数形式做出强假设(如线性、高斯分布等),网络可以通过调整权重来自动学习数据中复杂的关系。

反向传播算法原理

神经网络的学习过程就是寻找一组权重和偏置参数,使得网络在训练数据上的预测误差最小。这通常通过梯度下降法实现:参数沿着损失函数梯度的反方向更新。反向传播(Back Propagation, BP)算法就是高效计算网络中每个参数梯度的方法。

链式法则:核心思想

反向传播的核心是微积分中的链式法则。对于一个复合函数 f(g(x))f(g(x)),其对 xx 的导数为: dfdx=dfdg⋅dgdx\frac{df}{dx} = \frac{df}{dg} \cdot \frac{dg}{dx} 对于更复杂的嵌套函数 k(f(g(x)))k(f(g(x))),其导数为: dkdx=dkdf⋅dfdg⋅dgdx\frac{dk}{dx} = \frac{dk}{df} \cdot \frac{df}{dg} \cdot \frac{dg}{dx} 神经网络的正向传播就是一个极其复杂的复合函数。反向传播就是从最终输出层的误差开始,利用链式法则,将误差梯度一层层反向传播到每一层的权重和偏置上。

一个简化示例

考虑一个极其简单的计算:f(x,y,z)=(x+y)∗zf(x, y, z) = (x + y) * z。令 x=−2,y=5,z=−4x=-2, y=5, z=-4。

  1. 前向传播:
    • q=x+y=−2+5=3q = x + y = -2 + 5 = 3
    • f=q∗z=3∗(−4)=−12f = q * z = 3 * (-4) = -12
  2. 反向传播(计算梯度):
    • 首先计算 ff 对 qq 的梯度:∂f∂q=z=−4\frac{\partial f}{\partial q} = z = -4
    • 计算 ff 对 zz 的梯度:∂f∂z=q=3\frac{\partial f}{\partial z} = q = 3
    • 计算 qq 对 xx 的梯度:∂q∂x=1\frac{\partial q}{\partial x} = 1
    • 计算 qq 对 yy 的梯度:∂q∂y=1\frac{\partial q}{\partial y} = 1
    • 利用链式法则,ff 对 xx 的梯度为:∂f∂x=∂f∂q⋅∂q∂x=−4∗1=−4\frac{\partial f}{\partial x} = \frac{\partial f}{\partial q} \cdot \frac{\partial q}{\partial x} = -4 * 1 = -4
    • 同理,∂f∂y=−4∗1=−4\frac{\partial f}{\partial y} = -4 * 1 = -4

这个过程可以形象地看作梯度从输出 ff 反向流回输入 x,y,zx, y, z。

应用于一个神经元

让我们看一个具体的神经元例子。假设神经元函数为 f=σ(z)f = \sigma(z),其中 z=w0x0+w1x1+w2z = w_0 x_0 + w_1 x_1 + w_2(这里 w2w_2 是偏置项;x0x_0、x1x_1 都是普通输入,本例 x0=−1x_0=-1、x1=−2x_1=-2,并非恒为 1 的虚拟输入)。给定值:w0=2,w1=−3,w2=−3,x0=−1,x1=−2w_0=2, w_1=-3, w_2=-3, x_0=-1, x_1=-2。

前向传播计算过程如下:

import math

# 给定参数
w0, w1, w2 = 2, -3, -3
x0, x1 = -1, -2

# 前向传播
z = w0 * x0 + w1 * x1 + w2
print(f"线性组合 z = {w0}*({x0}) + ({w1})*({x1}) + ({w2}) = {z}")
# 经过 sigmoid 激活
f = 1 / (1 + math.exp(-z))
print(f"sigmoid 输出 f = 1 / (1 + exp(-{z})) = {f:.4f}")
线性组合 z = 2*(-1) + (-3)*(-2) + (-3) = 1
sigmoid 输出 f = 1 / (1 + exp(-1)) = 0.7311

现在,我们的目标是计算损失函数 LL(例如均方误差)关于权重 w0w_0 的梯度 ∂L∂w0\frac{\partial L}{\partial w_0}。根据链式法则: ∂L∂w0=∂L∂f⋅∂f∂z⋅∂z∂w0\frac{\partial L}{\partial w_0} = \frac{\partial L}{\partial f} \cdot \frac{\partial f}{\partial z} \cdot \frac{\partial z}{\partial w_0}

  • ∂L∂f\frac{\partial L}{\partial f} 取决于具体的损失函数。假设是平方误差 L=12(y−f)2L = \frac{1}{2}(y - f)^2,则 ∂L∂f=−(y−f)\frac{\partial L}{\partial f} = -(y - f)。这里我们先计算 ∂f∂w0\frac{\partial f}{\partial w_0},即 ff 对 w0w_0 的敏感度。
  • ∂f∂z\frac{\partial f}{\partial z}:sigmoid 函数的导数有一个优美性质:σ′(z)=σ(z)(1−σ(z))\sigma'(z) = \sigma(z)(1 - \sigma(z))。已知 f=σ(z)=0.7311f = \sigma(z) = 0.7311,所以 ∂f∂z=0.7311∗(1−0.7311)=0.1966\frac{\partial f}{\partial z} = 0.7311 * (1 - 0.7311) = 0.1966。
  • ∂z∂w0=x0=−1\frac{\partial z}{\partial w_0} = x_0 = -1。

因此,∂f∂w0=∂f∂z⋅∂z∂w0=0.1966∗(−1)=−0.1966\frac{\partial f}{\partial w_0} = \frac{\partial f}{\partial z} \cdot \frac{\partial z}{\partial w_0} = 0.1966 * (-1) = -0.1966。

如果我们将整个计算图拆解成最基本的加、乘、指数、倒数等运算,然后从输出 ff 开始,每一步计算局部梯度并乘以来自上一步的梯度,最终也能得到相同的结果。这就是反向传播的微观操作。

权重更新

得到梯度后,我们就可以用梯度下降法更新权重。例如,更新 w0w_0: w0new=w0old−α⋅∂L∂w0w_0^{\text{new}} = w_0^{\text{old}} - \alpha \cdot \frac{\partial L}{\partial w_0} 其中 α\alpha 是学习率。假设 α=0.01\alpha = 0.01,且 ∂L∂w0\frac{\partial L}{\partial w_0} 中的 ∂L∂f=−0.5\frac{\partial L}{\partial f} = -0.5(仅为示例),则 ∂L∂w0=−0.5∗−0.1966=0.0983\frac{\partial L}{\partial w_0} = -0.5 * -0.1966 = 0.0983。那么: w0new=2−0.01∗0.0983≈1.9990w_0^{\text{new}} = 2 - 0.01 * 0.0983 \approx 1.9990 权重被轻微调整,以使损失减小。

梯度消失与激活函数

在深层网络中,反向传播需要将梯度从输出层传递到输入层。如果使用 sigmoid 或 tanh 等激活函数,当输入值的绝对值较大时,其导数会趋近于 0。在多层连乘后,传到前面层的梯度会变得极其微小,导致前面层的权重几乎无法更新,这就是梯度消失问题。这曾是训练深度网络的主要障碍。

为了解决这个问题,现代神经网络常使用 ReLU(Rectified Linear Unit)及其变体作为激活函数。ReLU 函数为 f(x)=max⁡(0,x)f(x) = \max(0, x),在正区间的导数为 1,有效缓解了梯度消失问题,使得深层网络的训练成为可能。

在 NLP 中的意义与展望

本节我们快速回顾了神经网络的基础:神经元、前馈网络和反向传播。在 NLP 中,神经网络使我们能够构建神经语言模型,它比传统的 n-gram 模型更能捕捉长距离和复杂的词义依赖。此外,词向量(如 Word2Vec)本质上也是浅层神经网络训练的副产品。

更重要的是,神经网络为后续更强大的序列模型(如 RNN、LSTM)和注意力机制奠定了基础,这些模型彻底改变了机器翻译、文本生成等任务。而这一切模型训练的核心引擎,就是反向传播算法。

对于希望深入理解神经网络架构、卷积神经网络(CNN)以及更优化技巧的同学,强烈建议学习站内《深度学习基础》与《计算机视觉》课程。

📝 动手练一练

  1. 概念辨析:一个使用 sigmoid 激活函数的神经元,当输入线性组合 zz 的值非常大(如 10)或非常小(如 -10)时,其输出 aa 和梯度 dadz\frac{da}{dz} 分别会趋近于什么值?这对训练有什么潜在影响?
👉 点击查看参考答案
  • 当 zz 非常大(如 10)时:
    • 输出 a=σ(10)≈1a = \sigma(10) \approx 1。
    • 梯度 σ′(10)=σ(10)(1−σ(10))≈1∗(1−1)=0\sigma'(10) = \sigma(10)(1-\sigma(10)) \approx 1 * (1-1) = 0。
  • 当 zz 非常小(如 -10)时:
    • 输出 a=σ(−10)≈0a = \sigma(-10) \approx 0。
    • 梯度 σ′(−10)=σ(−10)(1−σ(−10))≈0∗(1−0)=0\sigma'(-10) = \sigma(-10)(1-\sigma(-10)) \approx 0 * (1-0) = 0。
  • 潜在影响:当神经元的激活值接近 0 或 1 时(称为“饱和”状态),其梯度会接近 0。在反向传播中,这个接近 0 的梯度会与后续梯度相乘,导致传递到更前面层的梯度变得极其微小,可能引发梯度消失问题,使得前面层的参数更新缓慢甚至停滞。
  1. 手算梯度:考虑一个无隐藏层的单个输出神经元(直接由输入映射到输出)。输入 x=2x=2,权重 w=1.5w=1.5,偏置 b=1b=1,使用 sigmoid 激活函数。假设真实标签 y=0.8y=0.8,使用平方损失函数 L=12(y−y^)2L = \frac{1}{2}(y - \hat{y})^2。请手动计算损失 LL 对权重 ww 的梯度 ∂L∂w\frac{\partial L}{\partial w}。(提示:先做前向传播得到预测值 y^\hat{y},然后按链式法则分解为 ∂L∂y^\frac{\partial L}{\partial \hat{y}}, ∂y^∂z\frac{\partial \hat{y}}{\partial z}, ∂z∂w\frac{\partial z}{\partial w} 并计算。)
👉 点击查看参考答案
  1. 前向传播:
    • 线性组合:z=w∗x+b=1.5∗2+1=4z = w * x + b = 1.5 * 2 + 1 = 4
    • 激活输出:y^=σ(z)=11+e−4≈0.9820\hat{y} = \sigma(z) = \frac{1}{1+e^{-4}} \approx 0.9820
  2. 计算各局部梯度:
    • ∂L∂y^=−(y−y^)=−(0.8−0.9820)=0.1820\frac{\partial L}{\partial \hat{y}} = - (y - \hat{y}) = - (0.8 - 0.9820) = 0.1820
    • ∂y^∂z=y^(1−y^)=0.9820∗(1−0.9820)≈0.0177\frac{\partial \hat{y}}{\partial z} = \hat{y}(1-\hat{y}) = 0.9820 * (1-0.9820) \approx 0.0177
    • ∂z∂w=x=2\frac{\partial z}{\partial w} = x = 2
  3. 链式法则求总梯度:
    • ∂L∂w=∂L∂y^⋅∂y^∂z⋅∂z∂w=0.1820∗0.0177∗2≈0.00644\frac{\partial L}{\partial w} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial z} \cdot \frac{\partial z}{\partial w} = 0.1820 * 0.0177 * 2 \approx 0.00644

因此,损失函数关于权重 ww 的梯度约为 0.00644。这意味着如果学习率 α=0.1\alpha=0.1,权重 ww 的更新量为 −0.1∗0.00644=−0.000644-0.1 * 0.00644 = -0.000644,新的 ww 约为 1.499356,调整幅度很小,因为预测值 y^\hat{y} 已经非常接近 1,且 sigmoid 在 z=4z=4 时梯度很小。

本章小结

本节我们完成了从统计语言模型到神经语言模型的思维跨越,并速览了神经网络的核心机制:

  • 神经元是神经网络的基本单元,其数学形式是线性变换后接一个非线性激活函数;只有在 sigmoid 二分类概率输出这一特定情形下,它才等同于一个逻辑回归模型,采用 tanh、ReLU 等其他激活时并不等价。
  • 全连接前馈神经网络通过将神经元分层连接,并交替进行线性变换与非线性激活,能够拟合输入与输出之间极其复杂的函数关系。
  • 反向传播算法是训练神经网络的关键。它利用链式法则,将最终输出层的误差梯度高效地反向传播至网络中的每一个权重和偏置参数,从而指导参数通过梯度下降法进行更新。
  • 梯度消失是训练深层网络的历史性挑战,与 sigmoid/tanh 激活函数在饱和区的微小梯度有关。ReLU 等现代激活函数在很大程度上缓解了此问题。

📋 行动清单

  • 理解神经元的前向计算公式,并能手动计算给定输入和权重下的输出。
  • 掌握链式法则在计算复合函数导数中的应用,并能将其与反向传播的思想联系起来。
  • 了解梯度消失问题的成因及其对深度网络训练的影响。

—— 小象教研组