TextRNN pytorch实现

本文介绍了RNN及其变体LSTM,详细阐述了TextRNN的网络结构,包括BiLSTM和多层RNN的使用。通过一个简单的代码实现展示了TextRNN在IMDB电影评论情感分析任务中的应用,包括数据预处理、模型构建、训练和验证过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Recurrent Neural Networks

RNN用来处理序列数据
具有记忆能力

Simple RNN

在这里插入图片描述

  • h t h_t ht:状态矩阵,不断更新(h_0: the;h_1: the cat…)
  • 只有一个参数矩阵A:随机初始化,然后用训练数据来学习A
    在这里插入图片描述
  • 为什么需要tanh激活函数:如果不激活可能会出现梯度消失或者梯度爆炸。

LSTM

  1. LSTM可以避免梯度消失的问题
  2. LSTM的记忆力要比SimpleRNN强

结构图:
在这里插入图片描述

  1. LSTM有四个参数矩阵
  2. 传送带(conveyor bert):过去的信息可以直接传送到未来。
  3. 过去的信息直接通过 C t C_t Ct传送到下一个时刻,不会发生太大的变化(以此避免梯度消失)

1. Forget Gate

  • f为遗忘门矩阵,为0就不通过
    在这里插入图片描述
  • W f W_f Wf:参数矩阵,通过反向传播从训练数据中学习
    在这里插入图片描述

2. Input Gate

  • W i W_i Wi:参数矩阵,通过反向传播从训练数据中学习
    在这里插入图片描述

3. New Value

在这里插入图片描述
在这里插入图片描述

4. Output Gate

在这里插入图片描述

  • Two Copies of ht:
    • 一个作为输出
    • 另一个传入到了下一步

改进RNN

  1. 多层RNN
  2. 双向RNN
  3. 预训练(预训练embedding层)

TextRNN

文本分类任务中,CNN可以用来提取句子中类似N-Gram的关键信息,适合短句子文本。TextRNN擅长捕获更长的序列信息。具体到文本分类任务中,从某种意义上可以理解为可以捕获变长、单向的N-Gram信息(Bi-LSTM可以是双向)。

一句话简介:textRNN指的是利用RNN循环神经网络解决文本分类问题,通常使用LSTM和GRU这种变形的RNN,而且使用双向,两层架构居多。

1. TextRNN简介

基本处理步骤:

  1. 将所有文本/序列的长度统一为n;对文本进行分词,并使用词嵌入得到每个词固定维度的向量表示。
  2. 对于每一个输入文本/序列,我们可以在RNN的每一个时间步长上输入文本中一个单词的向量表示,计算当前时间步长上的隐藏状态,然后用于当前时间步骤的输出以及传递给下一个时间步长并和下一个单词的词向量一起作为RNN单元输入。
  3. 再计算下一个时间步长上RNN的隐藏状态
  4. 以此重复…直到处理完输入文本中的每一个单词,由于输入文本的长度为n,所以要经历n个时间步长。

2. TextRNN网络结构

流程:embedding—>BiLSTM—>concat final output/average all output—–>softmax layer
在这里插入图片描述
两种形式:

  1. 一般取前向/反向LSTM在最后一个时间步长上隐藏状态,然后进行拼接,在经过一个softmax层(输出层使用softmax激活函数)进行一个多分类;
  2. 取前向/反向LSTM在每一个时间步长上的隐藏状态,对每一个时间步长上的两个隐藏状态进行拼接,然后对所有时间步长上拼接后的隐藏状态取均值,再经过一个softmax层(输出层使用softmax激活函数)进行一个多分类(2分类的话使用sigmoid激活函数)。

上述结构也可以添加dropout/L2正则化或BatchNormalization 来防止过拟合以及加速模型训练。

简单代码实现

任务:输入前两个此,预测下一个词

import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as Data

dtype = torch.FloatTensor
sentences = [ "i like dog", "i love coffee", "i hate milk"]

word_list = " ".join(sentences).split()
vocab = list(set(word_list))
word2idx = {
   w: i for i, w in enumerate(vocab)}
idx2word = {
   i: w for i, w in enumerate(vocab)}
n_class = len(vocab)
# TextRNN Parameter
batch_size = 2
n_step = 2 # number of cells(= number of Step) 输入有多少个单词
n_hidden = 5 # number of hidden units in one cell

def make_data(sentences):
    input_batch = []
    target_batch = []

    for sen in sentences:
        word = sen.split()
        input = [word2idx[n] for n in word[:-1]]
        target = word2idx[word[-1]]

        input_batch.append(np.eye(n_class)[input]) # one-hot编码
        target_batch.append(target)

    return input_batch, target_batch

input_batch, target_batch = make_data(sentences)
input_batch, target_batch = torch.Tensor(input_batch), torch.LongTensor(target_batch)
dataset = Data.TensorDataset(input_batch, target_batch)
loader = Data.DataLoader
### 如何用 PyTorch 实现 TextRNN TextRNN 是一种用于文本分类和其他自然语言处理任务的有效模型。该模型基于 RNN 架构,在每个时间步上接收输入词向量并更新隐藏状态,最终通过全连接层输出预测结果。 #### 1. 导入必要的库 为了构建 TextRNN 模型,首先需要导入所需的 Python 库: ```python import torch from torch import nn, optim import torch.nn.functional as F ``` #### 2. 定义 TextRNN 类 定义 `TextRNN` 类继承自 `nn.Module` 并初始化参数,包括嵌入矩阵、RNN 层以及线性变换层等组件[^2]。 ```python class TextRNN(nn.Module): def __init__(vocab_size, embed_dim=100, hidden_dim=128, num_layers=2, output_dim=2): super(TextRNN, self).__init__() # 嵌入层 self.embedding = nn.Embedding(vocab_size, embed_dim) # 双向 GRU/RNN/LSTM 层 self.rnn = nn.GRU(embed_dim, hidden_dim, num_layers=num_layers, bidirectional=True, batch_first=True, dropout=0.5) # 输出层 self.fc = nn.Linear(hidden_dim * 2, output_dim) def forward(self, text): embedded = self.embedding(text) # [batch size, seq_len, emb_dim] outputs, _ = self.rnn(embedded) # [batch size, seq_len, hid_dim*directions] encoding = torch.mean(outputs, dim=1) # 对所有时刻取平均作为句子表示 logits = self.fc(encoding) # [batch size, out_dim] return logits ``` 此部分代码实现了双向门控循环单元 (GRU),可以替换为其他类型的 RNN 或 LSTM 单元以适应具体应用场景的需求。 #### 3. 训练过程设置 创建实例化对象后即可开始训练流程,这里省略了数据预处理步骤,假设已经准备好了一批批次大小相同的数据集 `train_loader` 和相应的标签 `labels`: ```python device = 'cuda' if torch.cuda.is_available() else 'cpu' model = TextRNN(vocab_size=len(vocab), embed_dim=300).to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) for epoch in range(num_epochs): model.train() for i, (texts, labels) in enumerate(train_loader): texts, labels = texts.to(device), labels.to(device) optimizer.zero_grad() # 清除梯度缓存[^1] predictions = model(texts) loss = criterion(predictions, labels) loss.backward() optimizer.step() if i % log_interval == 0: print(f"Epoch [{epoch}/{num_epochs}], Step [{i}/{len(train_loader)}], Loss: {loss.item():.4f}") ``` 上述代码展示了完整的训练迭代逻辑,其中包含了清除旧有梯度的操作以防止累积错误的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值