【LLM】从零开始学大语言模型 | 3 | RNN
序列建模的演进与困境:彻底理解 RNN、LSTM 与 GRU 前言 在上一篇文章中,我们学会了把文字变成计算机可以处理的向量——词向量,相当于拿到了处理文字的"数字砖块"。接下来的问题自然是:如何把这些砖块砌成一面能理解"上下文"的墙?语言天生带有顺序,同样几个词,顺序不同,意思可能完全相反。本文将讲述早期的研究者如何试图给模型装上"记忆",以及这些尝试为何最终走入死局。只有把这份"痛"理解透彻,日后才能真正体会 Transformer 带来的范式革命。 全文将沿着三个问题展开:RNN 是干什么的?它靠什么机制实现?它又卡在了哪里? 一、MLP 是"失忆"的,而语言是有顺序的 回顾一下多层感知机(MLP,也就是神经网络的基本形态)。从数学上看,一个训练好的 MLP 就是一个固定的函数 $y = f(x)$:输入 $x$,经过逐层的线性变换与非线性激活,得到输出 $y$。这里要注意"函数"二字的含义——每一次调用都是独立的。你输入 $x_1$ 得到 $y_1$,再输入 $x_2$ 得到 $y_2$,这两次计算在底层完全不共享任何内部状态,前一次输入对后一次输出没有任何影响。换句话说,MLP 没有记忆:处理完一个输入就忘,根本不知道上一个输入是什么。 但语言恰恰是讲究顺序的。“我打了他"和"他打了我”,词完全一样,仅因顺序不同,意思就完全相反。如果把每个词独立地喂进 MLP,模型看到的只是一堆孤立的词,看不见顺序,也看不见上下文。这就像一页一页随机抽着读一本书,永远拼不出完整的情节。 因此,要处理语言,就需要一种带记忆的结构:它在处理当前输入时,能够同时参考"之前发生过什么"。这正是循环神经网络(Recurrent Neural Network, RNN)的出发点。 二、先明确目标:RNN 最终输出什么? 在讲机制之前,有必要先说清楚 RNN 是用来干什么的。不知道目的,就很容易在过程的细节里迷路。 RNN 的目的,是处理变长的序列数据(文本、语音等),把它压缩成包含上下文信息的向量,或者直接输出另一个序列,从而完成分类、翻译、预测等任务。具体而言,最典型的任务形态有三种: 多对一(Many-to-One):输入一整句话,输出一个标签。典型例子是情感分类:模型依次读入"这 / 电影 / 太 / 棒 / 了",读完最后一个词后,给出"正面 95%、负面 5%“这样的判断,目的是分辨这句话是夸还是骂。 序列到序列(Seq2Seq):输入一个序列,输出另一个序列。典型例子是机器翻译:一个 RNN 作为编码器(Encoder)读入中文"我 / 爱 / 你”,把整句话压缩成一个浓缩语义的上下文向量;另一个 RNN 作为解码器(Decoder)依据这个向量,逐个词地生成英文"I → love → you"。 多对多(Many-to-Many):每读入一个词,同时输出一个标签。典型例子是词性标注:对"我 / 吃 / 苹果",模型同步输出 [代词, 动词, 名词],用于分析句子的语法结构。 ...