NLP——RNN传统模型

发布于:2025-06-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、概念

RNN(Recurrent Neural Network),中文称作循环神经网络 它一般以序列数据为输入, 通过网络内部的结构设计有效捕捉序列之间的关系特征(比如语义,上下文),一般也是以序列形式进行输出。

  • RNN的循环机制使模型隐层上一时间步产生的结果, 能够作为当下时间步输入的一部分(当下时间步的输入除了正常的输入外还包括上一步的隐层输出)对当下时间步的输出产生影响。

RNN和ANN的区别:

ANN输入的语料单词都是互相独立的,无法联系上下文信息;

RNN能通过网络内部的结构设计有效捕捉序列之间的关系特征,然后进行信息预测。

二、作用

因为RNN结构能够很好利用序列之间的关系, 因此针对自然界具有连续性的输入序列, 如人类的语言, 语音等进行很好的处理, 广泛应用于NLP领域的各项任务, 如文本分类, 情感分析, 意图识别, 机器翻译

三、分类

从输入输出的角度

  • N vs N - RNN :输入和输出序列是等长,对对联,古诗

  • N vs 1 - RNN:输出是一个单独的值,文本分类

  • 1 vs N - RNN:输入不是序列而输出为序列,图生文

  • N vs M - RNN:不限输入输出长度,机器翻译(seq2seq架构)

从内部构造角度

  • 传统RNN

  • LSTM

  • Bi-LSTM(双向LSTM)

  • GRU

  • Bi-GRU(双向GRU)

四、传统RNN模型的内部结构

1. 结构分析

公式

h_{t}=tanh\left ( W_{t}\left [ X_{t},h_{t-1} \right ]+b_{t} \right )

计算过程

组成输入数据:基于时间步组合当前的输入数据

        输入:上一个时间步的隐藏状态h(t-1)+当前输入向量x(t)

        输出:当前时间步输出h(t)

计算当前时间步结果:基于当前时间步的输入,经过线性层和激活函数,得到当前时间步输出h(t)

        输入:拼接后的参数矩阵[h(t-1), x(t)]

        输出:当前时间步输出 h(t)

2. 使用Pytorch构建RNN模型

  • input_size : 输入张量的维度,也是词向量的嵌入维度

  • hidden_size : 隐层维度

  • batch_size: 一个批次的大小

  • seq_len: 一个序列有多少个词

  • num_layer: RNN层数

代码实现
① 导包
② 定义函数名,并且给定参数
import torch
import torch.nn as nn
def  dm01_rnn():
    input_size = 8
    hidden_size = 6
    num_layers = 1

    num_directions = 1
    batch_size = 5
    sequence_length = 1

注意:下面各项参数的顺序)

③ 定义RNN模型(

第一个参数:input_size(输入张量x的维度)
第二个参数:hidden_size(隐藏层的维度, 隐藏层的神经元个数)
第三个参数:num_layer(隐藏层的数量)

④ 构建输入数据X(

第一个参数:batch_size(批次的样本数量)
第二个参数:sequence_length(输入的序列长度)
第三个参数:input_size(输入张量的维度)

⑤ 初始化隐藏层数据h0(

第一个参数:num_layer * num_directions(层数*网络方向)
第二个参数:batch_size(批次的样本数)
第三个参数:hidden_size(隐藏层的维度, 隐藏层神经元的个数)

    # 1.定义RNN模型,传参
    rnn = nn.RNN(input_size=input_size,hidden_size=hidden_size,num_layers=num_layers)

    # 2.构建输入数据X,传参
    X = torch.randn(batch_size,sequence_length,input_size)

    # 3.初始化隐藏层数据h0,传参
    h0 = torch.randn(num_layers*num_directions,batch_size,hidden_size)
⑥ 前向传播

注意:前向传播结果有两个,out是所有时间步hn的拼接,hn是最后一个时间步的隐层输出

    out,hn = rnn(X,h0)

    # 打印输出
    print(out.shape)
    # TODO 输出结果为(batch_size,sequence_length,hidden_size)    输出结果中的hidden_size会受num_directions影响
    print(hn.shape)
    # TODO 输出结果为(num_layers*num_directions,batch_size,hidden_size)
⑦ 主程序
if __name__ == '__main__':
    dm01_rnn()

3. 传统RNN的优缺点

优势:结构简单,参数量小,短序列效果相对可以

缺点:处理长序列效果比较差, 容易梯度消失或者爆炸

梯度消失和梯度爆炸介绍

根据反向传播算法和链式法则, 梯度的计算可以简化为以下公式

Dn=σ′(z1)w1⋅σ′(z2)w2⋅⋯⋅σ′(zn)wn

  • 参数说明:

    • σ′(zn):第n层

    • w_n:连接第 i 层与下一层的权重参数

  • 其中sigmoid的导数值域是固定的, 在[0, 0.25]之间,

  • 而一旦公式中的w也小于1, 那么通过这样的公式连乘后, 最终的梯度就会变得非常非常小, 这种现象称作梯度消失. 反之, 如果我们人为的增大w的值, 使其大于1, 那么连乘够就可能造成梯度过大, 称作梯度爆炸.

  • 梯度消失或爆炸的危害:

    • 如果在训练过程中发生了梯度消失,权重无法被更新,最终导致训练失败; 梯度爆炸所带来的梯度过大,大幅度更新网络参数,在极端情况下,结果会溢出(NaN值)


网站公告

今日签到

点亮在社区的每一天
去签到