前言
清库存。正式切入大模型后,打算把基础知识都梳理一遍,然后写了两篇就发现写不动了,后面就捡重要的记录。RNN知识仅此一篇记录,扫盲记录。
【自然语言处理】
(Natural Language Processing,NLP)
- 是指让计算机接受用户自然语言形式的输入,并在内部通过人类所定义的算法进行加工、计算等系列操作,以模拟人类对自然语言的理解,并返回用户所期望的结果。
- 自然语言处理的目的在于用计算机代替人工来处理大规模的自然语言信息。让计算机能够确切理解人类的语言,并自然地与人进行交互是NLP的最终目标。
- 自然语言处理的挑战通常涉及语音识别、自然语言理解和自然语言生成。
【序列建模】
- 是许多领域的一个重要问题,包括自然语言处理、语音识别和语音合成、时间序列预测、音乐生成和生物信息学。
1 序列模型
1.1 简单介绍
机器学习领域中一种专门设计来 处理具有时间顺序或序列结构数据的模型。这类模型能够理解和学习数据中的顺序依赖关系,因此在处理如自然语言处理、语音识别、音乐生成、时间序列预测等任务时表现出色。
以下是关于序列模型的详细解析:
- 【定义与分类】
序列模型是一种处理序列数据的机器学习模型,其输入和/或输出通常为序列形式的数据。
序列模型可以分为多种类型,包括但不限于:
- 线性序列模型
如 自回归模型(AR)、移动平均模型(MA)和自回归移动平均模型(ARMA),这类模型基于线性关系对时间序列进行建模和预测,具有较好的解释性和可解释性,但只适用于线性数据。- 非线性序列模型
如神经网络模型(NN)、支持向量机模型(SVM)和决策树模型(DT),这类模型允许因素之间的相互作用和非线性关系,能够更好地适应非线性数据的特点。其中,神经网络模型在处理复杂、非线性时间序列数据方面表现出色。- 【核心特点】
- 时间依赖关系:能够捕捉序列数据中的时间依赖关系,即序列中的每个元素都与前面的元素有关系。
- 上下文信息:能够利用序列数据中的上下文信息,即每个元素都包含前面元素的信息。
- 变长序列处理:模型能够处理变长序列数据。
- 【应用领域】
序列模型在自然语言处理、语音识别、图像处理等多个领域都有广泛的应用:
- 自然语言处理:通过序列模型,可以实现文本分类、情感分析、命名实体识别、机器翻译等任务。例如,使用编码器-解码器结构和注意力机制的序列模型可以将一种语言的句子翻译成另一种语言的句子。
- 语音识别:将声音波形转化为文字,实现语音识别。这一技术在智能家居、智能客服等领域得到广泛应用。早期使用循环神经网络(RNN)等序列模型实现。
- 时间序列预测:在金融、气象学、信号处理等领域,序列模型被用于股票价格预测、外汇汇率预测、气温预测、降水量预测、语音识别和图像分类等任务。
- 【关键技术】
- 循环神经网络(RNN):RNN是一种特殊类型的神经网络,能够处理序列数据。它通过引入“循环”结构,允许信息在网络内部循环传递,从而捕获序列中的长期依赖关系。然而,RNN在训练过程中存在梯度消失和梯度爆炸的问题,对于非常长的序列可能无法有效处理。
- 长短期记忆网络(LSTM)和门控循环单元(GRU):作为RNN的变种,LSTM和GRU通过引入门控机制和记忆单元,改进了RNN的记忆能力,使得它们能够更好地处理长序列数据。
- 注意力机制:注意力机制被广泛应用于序列模型中,以提高模型对输入序列中重要信息的关注程度。这有助于模型更准确地理解和处理序列数据。
综上所述,序列模型是一种强大的机器学习模型,能够处理各种序列数据并生成有用的输出。随着深度学习技术的不断发展,序列模型在自然语言处理、语音识别等领域的应用越来越广泛,并持续推动着这些领域的发展。
1.2 序列模型的数学表达
用数学表达式 p(x)=p(x1)∗p(x2∣x1)∗p(x3∣x1,x2)∗...p(xT∣x1,...xT−1)p(x)=p(x_1)*p(x_2|x_1)*p(x_3|x_1,x_2)*...p(x_T|x_1,...x_{T-1})p(x)=p(x1)∗p(x2∣x1)∗p(x3∣x1,x2)∗...p(xT∣x1,...xT−1)。
- 方案一:马尔科夫假设
假设当前数据仅与最近的τ\tauτ 个数据相关,从而简化模型。则对条件概率建模:p(xt∣x1,...xt−1)=p(x∣f(x1,...xt−1))p(x_t|x_1,... x_{t-1})=p(x|f(x_1,...x_{t-1}))p(xt∣x1,...xt−1)=p(x∣f(x1,...xt−1)),其中f(x1,...xt−1)f(x_1,...x_{t-1})f(x1,...xt−1)- 方案二:潜变量模型
引入潜变量 hth_tht 来表示过去信息 ht=f(x1,...xt−1)h_t=f(x_1,...x_{t-1})ht=f(x1,...xt−1)
潜变量模型使用潜变量来概括历史信息。(输入为两个,当前数据+潜变量数据)
RNN的隐藏单元是潜变量的一种。隐变量是一个真实存在的东西,只是没有被观察到;潜变量可能是一个真实不存在的东西,根本就观察不到
1.3 关键词
- token(词元):指的是文本中的一个基本单位或独立部分。Token可以是单词、词组、标点符号、字符等,具体取决于文本处理的需求和方法。
- Tokenization(分词):将连续的文本序列划分成离散的Token的过程,这也是文本处理的第一步。这个过程可以通过多种方法实现,包括基于规则的分词、基于统计的分词等。
- vocabulary(词汇):指的是文本数据集中出现的所有token的集合(不会存在重复的词),这些单词构成了理解和处理文本的基础。
2 语言模型
什么是语言模型呢?语言模型为序列模型的一种:对于任意的词序列,它能够计算出这个序列是一句话的概率。即 给定文本序列 x1,...,xTx_1,...,x_Tx1,...,xT,语言模型的目标是估计联合概率 p(x1,...,xT)p(x_1,...,x_T)p(x1,...,xT)。它的应用包括:
- 做预训练模型(例:BERT、GPT-3)
- 生成文本,给你前面几个词,不断的使用 xt p(xt∣x1,...,xt−1)x_t ~ p(x_t|x_1,...,x_{t-1})xt p(xt∣x1,...,xt−1),来生成后续文本。
- 判断多个序列中哪个更常见。
2.1 N-gram模型
N-gram是语言模型中的一种重要方法。
- N-gram是是基于统计的方法,基于马尔科夫假设,它会根据历史出现的N-1个单词(或字符)序列的频率来选择最可能的下一个单词(或字符)。
- N-gram模型的参数是固定的,这些参数是通过统计训练语料库中N-gram的出现频率来得到的,不需要在训练过程中进行迭代更新。但在实际应用中,我们可能会根据新的数据或需求重新构建模型。
- N-gram模型简单高效,对于短期依赖关系的预测效果较好。适用于处理简单的语言模型和文本分析,常用于自动补全、拼写纠错等任务。然而,N-gram方法无法捕捉长距离的依赖关系和上下文信息,这是其局限性之一。
2.2 常见的N-gram包括
1-gram(Unigram)
它仅考虑文本中单个词(或称为元素)的出现频率,而不考虑词之间的顺序或上下文关系。(马尔科夫中的 τ=0\tau=0τ=0)P(wi)=count(wi)total_words P(w_i) = \frac{\text{count}(w_i)}{\text{total\_words}} P(wi)=total_wordscount(wi)
- P(wi)P(w_i)P(wi):词 wiw_iwi在文本中出现的概率。
count(wi)\text{count}(w_i)count(wi):词 wiw_iwi在语料库中出现的次数。
total_words\text{total\_words}total_words:语料库中所有单词的总数。2-gram(Bigram)
考虑了文本中连续两个词(元素)的联合出现频率。它假设一个词的出现概率仅与其前一个词有关。(马尔科夫中的 τ=1\tau=1τ=1)P(wi∣wi−1)=count(wi−1,wi)count(wi−1) P(w_i | w_{i-1}) = \frac{\text{count}(w_{i-1}, w_i)}{\text{count}(w_{i-1})} P(wi∣wi−1)=count(wi−1)count(wi−1,wi)
- P(wi∣wi−1)P(w_i | w_{i-1})P(wi∣wi−1):在给定前一个词wi−1w_{i-1}wi−1的条件下,词wiw_iwi出现的概率。
count(wi−1,wi)\text{count}(w_{i-1}, w_i)count(wi−1,wi):词对(wi−1,wi)(w_{i-1}, w_i)(wi−1,wi)在语料库中相邻出现的次数。
count(wi−1)\text{count}(w_{i-1})count(wi−1):词wi−1w_{i-1}wi−1在语料库中出现的总次数。3-gram(Trigram)
考虑了文本中连续三个词的联合出现频率。它假设一个词的出现概率与其前两个词都有关。马尔科夫中的 τ=2\tau=2τ=2)
P(wi∣wi−1,wi−2)=count(wi−2,wi−1,wi)count(wi−2,wi−1) P(w_i | w_{i-1}, w_{i-2}) = \frac{\text{count}(w_{i-2}, w_{i-1}, w_i)}{\text{count}(w_{i-2}, w_{i-1})} P(wi∣wi−1,wi−2)=count(wi−2,wi−1)count(wi−2,wi−1,wi)
- P(wi∣wi−1,wi−2)P(w_i | w_{i-1}, w_{i-2})P(wi∣wi−1,wi−2):在给定前两个词wi−2w_{i-2}wi−2和wi−1w_{i-1}wi−1的条件下,词wiw_iwi出现的条件概率。
count(wi−2,wi−1,wi)\text{count}(w_{i-2}, w_{i-1}, w_i)count(wi−2,wi−1,wi):三元组(wi−2,wi−1,wi)(w_{i-2}, w_{i-1}, w_i)(wi−2,wi−1,wi)在语料库中连续出现的次数。
count(wi−2,wi−1)\text{count}(w_{i-2}, w_{i-1})count(wi−2,wi−1):二元组(wi−2,wi−1)(w_{i-2}, w_{i-1})(wi−2,wi−1)在语料库中出现的总次数。N-gram(N>3)
P(wi∣wi−1,wi−2,…,wi−N+1)=count(wi−N+1,wi−N+2,…,wi)count(wi−N+1,wi−N+2,…,wi−1) P(w_i | w_{i-1}, w_{i-2}, \ldots, w_{i-N+1}) = \frac{\text{count}(w_{i-N+1}, w_{i-N+2}, \ldots, w_i)}{\text{count}(w_{i-N+1}, w_{i-N+2}, \ldots, w_{i-1})} P(wi∣wi−1,wi−2,…,wi−N+1)=count(wi−N+1,wi−N+2,…,wi−1)count(wi−N+1,wi−N+2,…,wi)
- 数据稀疏性问题随N的增加而急剧严重,很多的N元组在训练预料中出现频率极低。
计算复杂度和存储需求显著增加,可能导致模型在实际应用中难以部署。
3 循环神经网络
第一个序列模型的神经网络 – 循环神经网络。
3.1 简单的神经网络
通过调整Win、WoutW_{in}、W_{out}Win、Wout达到学习的效果。
隐藏层输出 Si=f(Win∗X+bin)S_i=f(W_{in}*X+b_{in})Si=f(Win∗X+bin)、Yi=f(WoutSi+bout)Y_i=f(W_{out}S_{i}+b_{out})Yi=f(WoutSi+bout)
3.2 循环神经网络
会关注数据在时间序列上的变化。RNN会假定不同的层级之间共享相同的权重矩阵 WsW_sWs,这样有效的减少训练参数。
此时的隐藏层: Si=f(Win∗X+WsSt−1+b)S_i=f(W_{in}*X+W_sS_{t-1}+b)Si=f(Win∗X+WsSt−1+b),该时刻的隐藏层的输出 的来源多了个上时刻的隐藏层的输出,自然而然,循环神经网络的输出取决于当前输入和上一时刻的隐变量
3.3 困惑度公式
困惑度(Perplexity, PP)通常定义为模型预测的概率分布与实际值之间的交叉熵的 指数形式。指数形式 使其成为一个更直观的评估指标。具体地,对于给定的测试集,困惑度可以表示为:PP=exp(−1N∑i=1NlogP(xi∣xi−1,xi−2,…,x1))\text{PP} = \exp\left( -\frac{1}{N} \sum_{i=1}^{N} \log P(x_i | x_{i-1}, x_{i-2}, \ldots, x_1) \right) PP=exp(−N1i=1∑NlogP(xi∣xi−1,xi−2,…,x1))
- NNN 是测试集中词(token)的总数。
- xix_ixi 是测试集中的第 iii 个词(token),代表模型需要预测的目标。
- P(xi∣xi−1,xi−2,…,x1)P(x_i | x_{i-1}, x_{i-2}, \ldots, x_1)P(xi∣xi−1,xi−2,…,x1) 是在给定前文 xi−1,xi−2,…,x1x_{i-1}, x_{i-2}, \ldots, x_1xi−1,xi−2,…,x1 的条件下,模型预测下一个单词 xix_ixi 的概率。
- exp\expexp 表示指数函数。
【例子(简化版)】
假设我们有一个非常简单的测试集,只包含一个句子:“the cat sits”。我们使用一个语言模型来预测这个句子中每个单词的概率。
- 对于单词“the”,假设模型预测的概率是1(因为是句子的开头,且只有一个可能的“the”)。
- 对于单词“cat”,假设模型在给定“the”的条件下预测的概率是0.8。
- 对于单词“sits”,假设模型在给定“the cat”的条件下预测的概率是0.6。
那么,我们可以计算这个测试集的困惑度:PP=exp(−13(log(1)+log(0.8)+log(0.6)))\text{PP} = \exp\left( -\frac{1}{3} \left( \log(1) + \log(0.8) + \log(0.6) \right) \right) PP=exp(−31(log(1)+log(0.8)+log(0.6)))注意,这里的计算是简化的,因为在实际应用中,语言模型通常会考虑更长的上下文,并且预测概率会基于整个训练集来计算。此外,困惑度的计算通常涉及整个测试集,而不仅仅是一个句子。这个例子只是为了说明困惑度公式的应用。
小结来说:
- 循环神经网络的输出取决于当下输入和前一时间的隐变量
- 应用到语言模型中时,循环神经网络根据当前词预测下一次时刻词
- 通常使用困惑度来衡量语言模型的好坏
4 RNN 的改进
4.1 门控循环单元(GRU)
关注一个序列时,不是每个观测值都是同等重要,想要只记住相关的观测值,需要:能遗忘的机制(重置门)、能关注的机制(更新门)
【GRU的工作流程如下】:
- 初始化隐藏状态
隐藏状态 h0h_0h0 通常初始化为零向量或随机向量- 计算重置门和更新门
- 【重置门rtr_trt】 xtx_txt是当前时刻的输入向量,h(t−1)h_(t-1)h(t−1)是前一时刻的隐藏状态。WrW_rWr和UrU_rUr是权重矩阵,brb_rbr是偏置,σ\sigmaσ是sigmoid激活函数。
rt=σ(Wrxt+UrHt−1+br)r_t= \sigma(W_rx_t+U_rH_{t-1}+b_r)rt=σ(Wrxt+UrHt−1+br)- 【更新门 ztz_tzt】WzW_zWz和UzU_zUz是权重矩阵,bzb_zbz是偏置项。
zt=σ(Wzxt+Uzht−1+bz)z_t=\sigma(W_zx_t+U_zh_{t-1}+b_z)zt=σ(Wzxt+Uzht−1+bz)- 计算候选隐藏状态
- 候选隐藏状态 h^t\hat{h}_th^t 是通过当前输入xtx_txt和前一时刻隐藏状态 ht−1h_{t-1}ht−1(经过重置门加权后)来计算的。其中,WhW_hWh和UhU_hUh是权重矩阵,bhb_hbh是偏置项,tanh 是激活函数,⊙\odot⊙ 表示逐元素乘法 h^t=tanh(Whxt+Uh(rt⊙ht−1)+bh)\hat{h}_t=\tanh (W_hx_t+U_h(r_t\odot h_{t-1})+b_h)h^t=tanh(Whxt+Uh(rt⊙ht−1)+bh)
- 计算当前时刻的隐藏状态
- 当前时刻的隐藏状态 hth_tht是通过前一时刻的隐藏状态 ht−1h_{t-1}ht−1 和候选隐藏状态 h^t\hat{h}_th^t(经过更新门加权后)来计算的。ht=zt⊙ht−1+(1−zt)⊙h^th_t=z_t\odot{h}_{t-1}+(1-z_t)\odot \hat{h}_tht=zt⊙ht−1+(1−zt)⊙h^t
个人思考:
- GRU隐藏层的更新,与卡尔曼滤波有点相似:先更新个当前候选状态,再根据当前候选状态和上一时刻状态进行加权,得到更新后的当前状态。
- GRU中的两个门,作为后续加权时的权重。我们希望 该权重为可学习的状态,并且输出为0~1之间。故该变量的设计为:一般的可学习参数与输入参数的相乘,再加个sigmoid。
若后续自己修改网路有相关需求,可借鉴该处的设计。
4. 2 长短期记忆网络(LSTM)
(整个信息记忆方式,逐渐像人类记忆方式靠近)
- 遗忘门:决定从上一时刻丢弃多少信息。
- 输入门:决定当前输入向量中多少信息被获取。
- 输出门:决定当前的隐藏状态应输出多少信息。
- 记忆单元C:用于记忆长期信息。数值没有限制。是LSTM网络中信息长期传递的主要路径,它能够在整个序列中保持不变或缓慢变化,从而捕捉到序列中的长期依赖关系。
- 隐藏层H:输出为-1~1之间的数值
- 计算遗忘门和输入门的信息
- 遗忘门(Forget Gate)。ft=σ(Wf[ht−1,xt]+bf)f_t=\sigma(W_f[h_{t-1}, x_t]+b_f)ft=σ(Wf[ht−1,xt]+bf)
其中 WfW_fWf 是遗忘门的权重矩阵,[ht−1,xt][h_{t-1},x_t][ht−1,xt]是前一个两个变量的拼接,bfb_fbf是遗忘门的偏置项,σ\sigmaσ 是sigmoid激活函数。- 输入门(Input Gate)。 it=σ(Wi[ht−1,xt]+bi)i_t=\sigma(W_i[h_{t-1},x_t]+b_i)it=σ(Wi[ht−1,xt]+bi)
- 输入门(Output Gate)。ot=σ(Wo)[ht−1,xt]+boo_t=\sigma(W_o)[h_{t-1},x_t]+b_oot=σ(Wo)[ht−1,xt]+bo
- 计算 候选记忆单元
- 候选记忆单元。 c^t=tanh(Wc[ht−1,xt]+bc)\hat{c}_t=\tanh(W_c[h_{t-1}, x_t]+b_c)c^t=tanh(Wc[ht−1,xt]+bc)
- 计算 记忆单元。根据遗忘门、输入门、候选记忆单元来更新。ct=ft⊙ct−1+it⊙c^tc_t=f_t\odot c_{t-1}+i_t\odot \hat{c}_tct=ft⊙ct−1+it⊙c^t
- 隐藏状态
- 根据输出门、记忆单元变量 计算出当前隐藏状态
ht=ot⊙tanh(ct)h_{t}=o_t\odot \tanh(c_t)ht=ot⊙tanh(ct)
4.3 深度循环神经网络
使用多个隐藏层来获取更多的非线性
4.4 双向循环神经网络
- 可以看到,正向和反向之间没有依赖关系,所以是可以并行计算的。
对于反向,计算时候仅需将输入序列的顺序反向,输出时再反向操作下即可。- 不适用于预测未来。适用于对序列抽取特征,填空。比如翻译。
5 序列到序列(Seq2Seq)神经网络模型
下图展示了两种典型的序列到序列(Seq2Seq)神经网络模型,它们在自然语言处理(NLP)领域中非常常见。这些模型通常用于处理序列数据,例如机器翻译、文本摘要、语音识别等任务。
- 编码器-解码器(Encoder-Decoder)模型
典型的编码器-解码器结构(图中左侧)。,编码器部分(蓝色方框)处理输入序列 (x1,x2,x3,x4)(x_1, x_2, x_3, x_4)(x1,x2,x3,x4),并生成一系列隐藏状态(h1,h2,h3,h4)(h_1, h_2, h_3, h_4)(h1,h2,h3,h4)。这些隐藏状态随后被用来生成一个上下文向量(图中黄色圆圈),该向量包含了输入序列的压缩信息。解码器部分(紫色方框)使用这个上下文向量和解码器的隐藏状态 (h1′,h2′,h3′)(h_1', h_2', h_3')(h1′,h2′,h3′) 来生成输出序列 (y1,y2,y3)(y_1, y_2, y_3)(y1,y2,y3)。- 直接序列到序列(Direct Seq2Seq)模型
图中右侧展示的是直接序列到序列模型。这种模型中,编码器和解码器共享相同的隐藏层状态。输入序列 (x1,x2,x3,x4)(x_1, x_2, x_3, x_4)(x1,x2,x3,x4) 直接通过编码器生成隐藏状态 (h1,h2,h3,h4)(h_1, h_2, h_3, h_4)(h1,h2,h3,h4),然后解码器直接使用这些隐藏状态来生成输出序列 (y1,y2,y3)(y_1, y_2, y_3)(y1,y2,y3)。
这些模型中的隐藏状态和上下文向量都是神经网络中的激活值,它们通过神经网络的权重和偏置进行计算。在实际应用中,这些模型通常使用循环神经网络(RNN)、长短期记忆网络(LSTM)或门控循环单元(GRU)等结构来实现。这些结构能够处理序列数据的时间依赖性,从而有效地处理和生成序列数据。
【循环神经网络与Seq2Seq模型的关系】
循环神经网络(RNN)、门控循环单元(GRU)、长短期记忆网络(LSTM)以及它们的变体如深度RNN(Deep RNN)和双向RNN(Bi-directional RNN)都是不同类型的循环神经网络,它们可以作为序列到序列(Seq2Seq)模型的构建块。这些网络类型之间的关系并不是简单的包含关系,而是它们可以被用来实现Seq2Seq模型的不同部分。
以下是这些网络类型与Seq2Seq模型之间的关系:
- 循环神经网络(RNN)
RNN是最基本的循环神经网络结构,它通过循环连接来处理序列数据。然而,由于梯度消失或梯度爆炸的问题,标准RNN在处理长序列时效果不佳。- 长短期记忆网络(LSTM)
LSTM是RNN的一种改进,它通过引入输入门、遗忘门和输出门来解决梯度消失问题,从而能够学习长期依赖关系。LSTM可以作为Seq2Seq模型中的编码器或解码器。- 门控循环单元(GRU)
GRU是另一种RNN的改进,它将LSTM中的三个门简化为两个门(更新门和重置门),同时合并了细胞状态和隐藏状态。GRU同样可以作为Seq2Seq模型中的编码器或解码器。- 深度循环神经网络(Deep RNN)
深度RNN指的是具有多个隐藏层的RNN结构。这种结构可以捕捉更复杂的特征,但同时也可能面临更复杂的训练问题。在Seq2Seq模型中,深度RNN可以用于构建更复杂的编码器和解码器。- 双向循环神经网络(Bi-directional RNN)
双向RNN在每个时间步同时处理过去和未来的信息。这种结构可以提供更丰富的上下文信息,因为它考虑了序列的前后文。在Seq2Seq模型中,双向RNN通常用于编码器部分,以增强模型对输入序列的理解。
在Seq2Seq模型中,编码器和解码器可以是上述任何一种RNN结构,或者它们的组合。例如,一个Seq2Seq模型可能使用LSTM作为编码器,GRU作为解码器,或者使用双向LSTM作为编码器来增强对输入序列的理解。
总结来说,RNN、LSTM、GRU、深度RNN和双向RNN是不同类型的循环神经网络结构,它们可以被用来构建Seq2Seq模型的不同部分,而不是简单的并级或包含关系。选择合适的网络结构取决于具体的任务需求、数据特性以及模型的复杂度。