一文搞懂NLP框架之RNN、LSTM、Transformer结构原理!

NLP领域中,特征提取可谓是经历了显著的“变迁”与发展。回首过往,RNN曾以其独特的序列建模能力一度引领潮流,如今正如同明日黄花,逐步淡出历史舞台。紧接着,LSTM以解决长时依赖问题的独特设计展现出强大的生命力,虽已非最前沿,却仍老骥伏枥,若能进一步优化,其潜力不可小觑。

而今,Transformer架构如日中天,凭借自注意力机制彻底革新了特征提取的方法,已在NLP诸多任务中发挥着中流砥柱的作用。

本文笔者将深入浅出剖析RNN、LSTM以及Transformer的核心结构原理,一起见证算法是怎样做到一浪更比一浪强的。

RNN

为什么会出现RNN?

要搞明白这个问题,我们是不是可以先回想一下,在RNN之前的模型还有什么可改进点?

没错,从这里着手,问题就将会迎刃而解了。细想BP、CNN(卷积神经网络),可以当做能够拟合任意函数的黑盒子,只要训练数据足够,给定特定的x,就能得到期望的y。结构图如下:

在这里插入图片描述

但是不难发现,它们都只能单独的处理一个个的输入,前一个输入和后一个输入是完全没有关系的。而我们实际应用中肯定有需要处理序列信息的任务吧,即就是前面的输入和后面的输入是有关系的。

例如,当我们理解某句话意思时,孤立的理解每个词肯定是不够的,而是需要处理这些词连接起来的整个序列,“词本无意,意由境生”,也正是此意。还有,处理视频的时候,当前也不能只单独的分析每一帧,而是要分析这些帧连接起来的整个序列。

为了解决一些这样类似的问题,能够更好的处理序列的信息,RNN就诞生了。

RNN解释

我们通常所说的RNN实际上有两种,一种是Recurrent Neural Networks,即循环神经网络,一种是Recursive Neural Networks,即递归神经网络。

循环神经网络,是一种时间上进行线性递归的神经网络,用于处理序列数据

相比于传统的神经网络,它可以处理序列变化的数据。比如某个词汇的含义根据上下文内容不同而有所不同,RNN则可以很好地解决这类问题。

递归神经网络(Recursive Neural Networks)被视为循环神经网络的推广,它是一种在结构上进行递归的神经网络,常用于NLP中的序列学习,它的输入数据本质不一定是时序的,但结构却往往更加复杂。

我们这里只说循环神经网络RNN

首先来看一个简单的RNN,它由输入层、一个隐藏层和一个输出层组成:

在这里插入图片描述

如果将W的那个带箭头的圈去掉,它就变成了最普通的全连接神经网络。

  • x是一个向量,它表示输入层的值。
  • s是一个向量,它表示隐藏层的值(这里隐藏层面画了一个节点,你也可以想象这一层其实是多个节点,节点数与向量s的维度相同)。
  • U是输入层到隐藏层的权重矩阵。
  • o也是一个向量,它表示输出层的值。
  • V是隐藏层到输出层的权重矩阵。

那么,现在我们来看看W是什么。循环神经网络的隐藏层的值s不仅仅取决于当前这次的输入x,还取决于上一次隐藏层的值s。而权重矩阵W就是隐藏层上一次的值作为这一次的输入的权重。

具体如下图所示。可以清楚的看到,上一时刻的隐藏层是如何影响当前时刻的隐藏层的。

在这里插入图片描述

当然我们也可以将上面的图按时间线展开,循环神经网络也可以画成下面的样子:

在这里插入图片描述

现在就可以清晰看出,该网络在 t t t时刻接收输入 x t x_t xt,隐藏层的值 s t s_t st由上一时刻的 s t − 1 s_{t-1} st1 x t x_t xt的权重矩阵W决定。

公式表示如下:

O t = g ( V ∗ S t ) O_t = g(V*S_t) Ot=g(VSt)

S t = f ( U ∗ X t + W ∗ S t − 1 ) S_t = f(U*X_t+W*S_{t-1}) St=f(U

### 关于RNNLSTMTransformer的代码实现 #### RNN 实现 对于简单的循环神经网络(RNN),可以利用 PyTorch 提供的功能快速搭建。下面是一个基本的例子: ```python import torch.nn as nn class SimpleRNN(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(SimpleRNN, self).__init__() self.hidden_size = hidden_size self.rnn = nn.RNN(input_size, hidden_size, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): h0 = torch.zeros(1, x.size(0), self.hidden_size).to(x.device) # 初始化隐藏层 out, _ = self.rnn(x, h0) # 前向传播 RNN out = self.fc(out[:, -1, :]) # 取最后一个时刻的状态作为输出 return out ``` 这段代码定义了一个简单的一层 RNN 模型,适用于处理序列数据[^2]。 #### LSTM 实现 长短期记忆(LSTM)单元通过引入门控机制解决了传统 RNN 难以捕捉长期依赖的问题。以下是使用 PyTorch 构建的一个简易 LSTM 模型实例: ```python import torch.nn as nn class SimpleLSTM(nn.Module): def __init__(self, input_dim, hidden_dim, layer_dim, output_dim): super(SimpleLSTM, self).__init__() self.hidden_dim = hidden_dim self.layer_dim = layer_dim self.lstm = nn.LSTM(input_dim, hidden_dim, layer_dim, batch_first=True) self.fc = nn.Linear(hidden_dim, output_dim) def forward(self, x): h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_().to(x.device) c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_().to(x.device) out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach())) out = self.fc(out[:, -1, :]) return out ``` 此段代码展示了如何创建一个多层 LSTM 结构来增强模型的记忆力和表达能力。 #### Transformer 实现 Transformers 利用了自注意力机制替代了传统的循环结构,在许多 NLP 任务上取得了更好的效果。这里给出一个简化版的 Transformer 编码器部分实现方式: ```python from transformers import BertModel class SimpleTransformerEncoder(nn.Module): def __init__(self, model_name='bert-base-uncased'): super().__init__() self.transformer_model = BertModel.from_pretrained(model_name) def forward(self, inputs): outputs = self.transformer_model(**inputs)[0] cls_output = outputs[:, 0, :] # 获取 [CLS] token 的表示 return cls_output ``` 在这个例子中,选择了预训练好的 BERT 模型作为基础框架来进行文本分类或其他下游任务的应用[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿着帆布鞋也能走猫步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值