循环神经网络 RNN 是什么?带“记忆”的序列处理网络
循环神经网络(Recurrent Neural Network,RNN)是一类专门用来处理序列数据的神经网络,比如文本、语音、时间序列。它的特点是网络中存在“循环”:在处理序列中的每一个元素时,它不仅接收当前的输入,还接收自己上一步留下来的“记忆”,也就是隐藏状态。这让它能够利用之前看到的信息来理解当前的内容。
为什么需要循环神经网络
普通的前馈神经网络,每次处理一个固定大小的输入,输入之间是相互独立的,没有“记忆”。但很多数据是有先后顺序的,前后之间密切相关:理解一句话中的某个词,需要知道前面说了什么;预测明天的气温,需要参考过去几天的气温;识别一段语音,需要结合前后的声音。而且序列的长度往往是不固定的,一句话可长可短。循环神经网络正是为了处理这样的数据而设计的。
它是怎么工作的
循环神经网络按照顺序,一个接一个地处理序列中的元素,每处理一个元素叫作一个时间步。在每个时间步,它把当前的输入和上一个时间步的隐藏状态结合起来,通过一个神经网络层计算出新的隐藏状态,再根据隐藏状态产生当前的输出。新的隐藏状态又会被传给下一个时间步。这样,隐藏状态就像一个不断更新的“记忆”,概括了到目前为止看到的所有信息。一个关键的特点是:在所有的时间步上,网络使用的都是同一组参数。这让它能够处理任意长度的序列,而参数的数量不会随着序列变长而增加。如果把循环神经网络在时间上展开,它看起来就像一个很深的前馈网络,每一层对应一个时间步,各层共享同样的权重。训练时使用通过时间的反向传播算法,把误差沿着时间一步步地往回传。
1990 年,Jeffrey Elman 提出了一种简单而有影响力的循环神经网络结构,被称为 Elman 网络,至今仍是理解循环神经网络的基础模型;稍早的 Jordan 网络也是一种早期的形式。
处理序列的不同方式
循环神经网络可以灵活地处理各种输入和输出的组合:输入一个序列、输出一个结果,比如判断一段评论的情感;输入一个序列、在每个位置都输出一个结果,比如给句子中的每个词标注词性;输入一个、输出一个序列,比如根据一张图片生成一句描述;输入一个序列、输出另一个序列,比如机器翻译,这通常使用编码器-解码器的结构。还可以使用双向的循环神经网络,同时从前往后和从后往前处理序列,或者把多层循环神经网络堆叠起来。
长期依赖的难题和改进
简单的循环神经网络有一个严重的问题:在训练时,梯度需要沿着时间一步步地往回传,经过很多个时间步之后,梯度会以指数的速度衰减或者增大,也就是梯度消失或梯度爆炸,导致网络很难学到序列中相隔很远的元素之间的关系。为了解决这个问题,Sepp Hochreiter 和 Jürgen Schmidhuber 在 1997 年提出了长短期记忆网络(LSTM),通过门控机制和一条细胞状态,让信息能够在很长的时间跨度上稳定地传递;2014 年,Kyunghyun Cho 等人提出了结构更简单的门控循环单元(GRU)。
兴衰与传承
在 2010 年代中期,基于长短期记忆网络的循环神经网络在语言模型、机器翻译、语音识别、手写识别等任务上取得了巨大的成功。但循环神经网络有一个根本的局限:它必须按顺序逐个地处理,前一步没算完,后一步就无法开始,难以利用 GPU 进行大规模的并行计算,在很长的序列上训练很慢。2017 年提出的 Transformer 完全基于注意力机制,可以并行地处理整个序列,任意两个位置之间都能直接联系,很快在大多数任务上取代了循环神经网络。不过,循环神经网络的思想并没有消失:它在推理时每一步的计算量和内存占用是固定的,不随序列的长度增长,这一优点在处理超长序列时很有吸引力。近年来出现的 Mamba 等状态空间模型、RWKV 等架构,就试图兼具 Transformer 训练时可以并行的优点和循环网络推理时高效的优点。