基于PyTorch使用LSTM实现新闻文本分类任务

这篇具有很好参考价值的文章主要介绍了基于PyTorch使用LSTM实现新闻文本分类任务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文参考

PyTorch深度学习项目实战100例

https://weibaohang.blog.csdn.net/article/details/127154284?spm=1001.2014.3001.5501

任务介绍

基于PyTorch使用LSTM实现新闻文本分类任务的概况如下:

任务描述:新闻文本分类是一种常见的自然语言处理任务,旨在将新闻文章分为不同的类别,如政治、体育、科技等。

方法:使用深度学习模型中的LSTM(长短时记忆网络)来处理文本序列数据。LSTM能够捕获文本中的长期依赖关系,适应不定长文本,自动提取特征,适应多类别分类,并在大型数据集上表现出色。

做数据的导入

数据+代码
https://download.csdn.net/download/weixin_55982578/88323618?spm=1001.2014.3001.5503

环境介绍

通俗的说:
直接白嫖 Google colab

优雅的说
Google Colab(Colaboratory)是一种基于云的免费Jupyter笔记本环境,具有以下优点和好处:

免费使用:Colab提供免费的GPU和TPU(Tensor Processing Unit)资源,使用户能够免费运行深度学习和机器学习任务,而无需担心硬件成本。
Google Colab(Colaboratory)是一种基于云的免费Jupyter笔记本环境,具有以下优点和好处:

免费使用:Colab提供免费的GPU和TPU(Tensor Processing Unit)资源,使用户能够免费运行深度学习和机器学习任务,而无需担心硬件成本。

导入必要的包

介绍torchnet和keras

Torchnet 是一个轻量级框架,旨在为 PyTorch 提供一些抽象和实用工具,以简化常见的深度学习研究任务。Torchnet 的设计是模块化和扩展性的,这使得研究者可以更轻松地尝试新的思路和方法。

Keras 是一个开源深度学习框架,最初由François Chollet创建并维护。它是一个高级神经网络API,旨在使深度学习模型的设计和训练变得简单而快速

!pip install torchnet
!pip install keras
import pickle
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from tensorflow.keras.preprocessing.sequence import pad_sequences
from sklearn.model_selection import train_test_split
from torch.utils.data import TensorDataset
from torch import optim
from torchnet import meter
from tqdm import tqdm```

做数据的导入

数据+代码

类别

# {0: '法治',
#  1: '国际',
#  2: '国内',
#  3: '健康',
#  4: '教育',
#  5: '经济',
#  6: '军事',
#  7: '科技',
#  8: '农经',
#  9: '三农',
#  10: '人物',
#  11: '社会',
#  12: '生活',
#  13: '书画',
#  14: '文娱'}

给必要的参数命名

# config file
# 模型输入参数,需要自己根据需要调整
num_layers = 1 # LSTM的层数
hidden_dim = 100 # LSTM中的隐层大小
epochs = 50 # 迭代次数
batch_size = 32 # 每个批次样本大小
embedding_dim = 15 # 每个字形成的嵌入向量大小
output_dim = 15 # 输出维度,因为是二分类
lr = 0.01 # 学习率
import torch

# 检查是否有可用的GPU
device = torch.device('cuda')
file_path = './news.csv' # 数据路径
input_shape = 80 # 每句话的词的个数,如果不够需要使用0进行填充

加载文本数据


# 加载文本数据
def load_data(file_path, input_shape=20):
    df = pd.read_csv(file_path, encoding='gbk')

    # 标签及词汇表
    labels, vocabulary = list(df['label'].unique()), list(df['brief'].unique())

    # 构造字符级别的特征
    string = ''
    for word in vocabulary:
        string += word

    # 所有的词汇表
    vocabulary = set(string)

    # word2idx 将字映射为索引 '你':0
    word2idx = {word: i + 1 for i, word in enumerate(vocabulary)}
    with open('word2idx.pk', 'wb') as f:
        pickle.dump(word2idx, f)
    # idx2word 将索引映射为字 0:'你'
    idx2word = {i + 1: word for i, word in enumerate(vocabulary)}
    with open('idx2word.pk', 'wb') as f:
        pickle.dump(idx2word, f)
    # label2idx 将正反面映射为0和1 '法治':0
    label2idx = {label: i for i, label in enumerate(labels)}
    with open('label2idx.pk', 'wb') as f:
        pickle.dump(label2idx, f)
    # idx2label 将0和1映射为正反面 0:'法治'
    idx2label = {i: labels for i, labels in enumerate(labels)}
    with open('idx2label.pk', 'wb') as f:
        pickle.dump(idx2label, f)

    # 训练数据中所有词的个数
    vocab_size = len(word2idx.keys())  # 词汇表大小
    # 标签类别,分别为法治、健康等
    label_size = len(label2idx.keys())  # 标签类别数量

    # 序列填充,按input_shape填充,长度不足的按0补充
    # 将一句话映射成对应的索引 [0,24,63...]
    x = [[word2idx[word] for word in sent] for sent in df['brief']]
    # 如果长度不够input_shape,使用0进行填充
    x = pad_sequences(maxlen=input_shape, sequences=x, padding='post', value=0)
    # 形成标签0和1
    y = [[label2idx[sent]] for sent in df['label']]
    #     y = [np_utils.to_categorical(label, num_classes=label_size) for label in y]
    y = np.array(y)
    return x, y, idx2label, vocab_size, label_size, idx2word

读取数据返回参数

变量名 描述
x 包含了填充后的文本数据(字符索引的序列)
y 包含了标签数据
idx2label 用于将模型的输出索引映射回标签
vocab_size 存储词汇表大小
label_size 存储标签类别数量
idx2word 用于将字符索引映射回字符

生成

字典名称 描述
word2idx 字符映射为索引,例如 ‘你’ 映射为 0
idx2word 索引映射回字符,例如 0 映射回 ‘你’
label2idx 标签映射为索引,例如 ‘法治’ 映射为 0
idx2label 索引映射回标签,例如 0 映射回 ‘法治’

代码里面提供了可视化的方法

创建LSTM 网路结构

LSTM(Long Short-Term Memory)是一种循环神经网络(Recurrent Neural Network,RNN)的变种,它在处理序列数据时具有很好的性能,特别是在长序列上能够更好地捕捉长期依赖关系。下面是关于LSTM网络结构的说明:

背景:LSTM是为了解决传统RNN中的梯度消失和梯度爆炸问题而提出的。它引入了特殊的记忆单元来维护和控制信息的流动,以更好地捕捉序列数据中的长期依赖关系。

LSTM单元:LSTM网络的基本构建单元是LSTM单元。每个LSTM单元包括以下组件:

  • 输入门(Input Gate):控制新信息的输入。
  • 遗忘门(Forget Gate):控制过去信息的遗忘。
  • 输出门(Output Gate):控制输出的生成。
  • 细胞状态(Cell State):用于维护长期依赖关系的记忆。

记忆细胞:LSTM单元内部的细胞状态是其核心。它可以看作一个传送带,可以在不同时间步骤上添加或删除信息。通过输入门、遗忘门和输出门来控制信息的读取、写入和遗忘,以保持对序列中重要信息的长期记忆。

输入门:输入门决定了在当前时间步骤中,新的输入信息中哪些部分将会更新细胞状态。输入门通常由一个Sigmoid激活函数和一个tanh激活函数组成,用于产生0到1之间的权重和-1到1之间的新候选值。

遗忘门:遗忘门决定了哪些信息应该从细胞状态中丢弃。它使用Sigmoid激活函数来产生0到1之间的权重,控制细胞状态中哪些信息应该保留。

输出门:输出门决定了基于当前细胞状态和输入信息,LSTM单元应该输出什么。它使用Sigmoid激活函数来确定输出的哪些部分应该激活,并使用tanh激活函数来生成可能的输出值。
基于PyTorch使用LSTM实现新闻文本分类任务,自学pytorch,pytorch,lstm,分类

# 定义网络结构
class LSTM(nn.Module):
    def __init__(self, vocab_size, hidden_dim, num_layers, embedding_dim, output_dim):
        super(LSTM, self).__init__()
        self.hidden_dim = hidden_dim  # 隐层大小
        self.num_layers = num_layers  # LSTM层数

        # 嵌入层,会对所有词形成一个连续型嵌入向量,该向量的维度为embedding_dim
        # 然后利用这个向量来表示该字,而不是用索引继续表示
        self.embeddings = nn.Embedding(vocab_size + 1, embedding_dim)

        # 定义LSTM层,第一个参数为每个时间步的特征大小,这里就是每个字的维度
        # 第二个参数为隐层大小
        # 第三个参数为LSTM的层数
        self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers)

        # 利用全连接层将其映射为2维,即正反面的概率
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        # 1.首先形成嵌入向量
        embeds = self.embeddings(x)

        # 2.将嵌入向量导入到LSTM层
        output, (h_n, c_n) = self.lstm(embeds)

        # 获取输出的形状
        timestep, batch_size, hidden_dim = output.shape

        # 3.将其导入全连接层
        output = output.reshape(-1, hidden_dim)
        output = self.fc(output)  # 形状为batch_size * timestep, 15

        # 重新调整输出的形状,使其变为 timestep x batch_size x output_dim
        output = output.reshape(timestep, batch_size, -1)

        # 返回最后一个时间片的输出,维度为 batch_size x output_dim
        return output[-1]


数据前处理

# 1.获取训练数据
x, y, idx2label, vocab_size, label_size, idx2word = load_data(file_path, input_shape)

# 2.划分训练、测试数据
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1, random_state=42)

# 3.将numpy转成tensor
x_train = torch.from_numpy(x_train).to(torch.int32)
y_train = torch.from_numpy(y_train).to(torch.float32)
x_test = torch.from_numpy(x_test).to(torch.int32)
y_test = torch.from_numpy(y_test).to(torch.float32)

# 将训练数据和标签移到GPU上加速
x_train = x_train.to('cuda:0')
y_train = y_train.to('cuda:0')
x_test = x_test.to('cuda:0')
y_test = y_test.to('cuda:0')

使用torch中的Dataloader的方法

# 4.形成训练数据集
train_data = TensorDataset(x_train, y_train)
test_data = TensorDataset(x_test, y_test)

# 5.将数据加载成迭代器
train_loader = torch.utils.data.DataLoader(train_data,
                                           batch_size,
                                           True)

test_loader = torch.utils.data.DataLoader(test_data,
                                          batch_size,
                                          False)

模型训练

# 6.模型训练
model = LSTM(vocab_size=vocab_size, hidden_dim=hidden_dim, num_layers=num_layers,
             embedding_dim=embedding_dim, output_dim=output_dim)

Configimizer = optim.Adam(model.parameters(), lr=lr) # 优化器
criterion = nn.CrossEntropyLoss() # 多分类损失函数

model.to(device)
loss_meter = meter.AverageValueMeter()

best_acc = 0 # 保存最好准确率
best_model = None # 保存对应最好准确率的模型参数

for epoch in range(epochs):
    model.train() # 开启训练模式
    epoch_acc = 0 # 每个epoch的准确率
    epoch_acc_count = 0 # 每个epoch训练的样本数
    train_count = 0 # 用于计算总的样本数,方便求准确率
    loss_meter.reset()

    train_bar = tqdm(train_loader)  # 形成进度条
    for data in train_bar:
        x_train, y_train = data  # 解包迭代器中的X和Y

        x_input = x_train.long().transpose(1, 0).contiguous()
        x_input = x_input.to(device)
        Configimizer.zero_grad()

        # 形成预测结果
        output_ = model(x_input).to(device)

        # 计算损失
        loss = criterion(output_, y_train.long().view(-1))
        loss.backward()
        Configimizer.step()

        loss_meter.add(loss.item())

        # 计算每个epoch正确的个数
        epoch_acc_count += (output_.argmax(axis=1) == y_train.view(-1)).sum()
        train_count += len(x_train)

    # 每个epoch对应的准确率
    epoch_acc = epoch_acc_count / train_count

    # 打印信息
    print("【EPOCH: 】%s" % str(epoch + 1))
    print("训练损失为%s" % (str(loss_meter.mean)))
    print("训练精度为%s" % (str(epoch_acc.item() * 100)[:5]) + '%')

    # 保存模型及相关信息
    if epoch_acc > best_acc:
        best_acc = epoch_acc
        best_model = model.state_dict()

    # 在训练结束保存最优的模型参数
    if epoch == epochs - 1:
        # 保存模型
        torch.save(best_model, './best_model.pkl')

# 打印测试集精度
test_accuracy = (model(x_test.long().transpose(1, 0).contiguous()).argmax(axis=1) == y_test.view(-1)).sum() / len(y_test)
print("【训练精度为】%s" % (str(test_accuracy.item() * 100)[:5]) + '%')

验证


# 导入字典,用于形成编码
with open('word2idx.pk', 'rb') as f:
    word2idx = pickle.load(f)
with open('label2idx.pk', 'rb') as f:
    label2idx = pickle.load(f)
with open('idx2word.pk', 'rb') as f:
    idx2word = pickle.load(f)
with open('idx2label.pk', 'rb') as f:
    idx2label = pickle.load(f)

try:
    # 数据预处理
    input_shape = 80 # 序列长度,就是时间步大小,也就是这里的每句话中的词的个数
    # 用于测试的话
    sent = "陈金英,一位家住浙江丽水的耄耋老人。今年这个年,陈金英过得格外舒心,因为春节前,她耗费10年,凭借自己的努力,不拖不欠,终于还清了所有欠款。"
    # 将对应的字转化为相应的序号
    x = [[word2idx[word] for word in sent]]
    # 如果长度不够180,使用0进行填充
    x = pad_sequences(maxlen=input_shape, sequences=x, padding='post', value=0)
    x = torch.from_numpy(x)

    # 加载模型
    model_path = './best_model.pkl'
    model = LSTM(vocab_size=vocab_size, hidden_dim=hidden_dim, num_layers=num_layers,
             embedding_dim=embedding_dim, output_dim=output_dim)
    model.load_state_dict(torch.load(model_path, 'cpu'))

    # 模型预测,注意输入的数据第一个input_shape,就是180
    y_pred = model(x.long().transpose(1, 0))
    print('输入语句: %s' % sent)
    print('新闻分类结果: %s' % idx2label[y_pred.argmax().item()])

except KeyError as err:
    print("您输入的句子有汉字不在词汇表中,请重新输入!")
    print("不在词汇表中的单词为:%s." % err)


弄成函数好调用

def classify_news_sentiment(sent):
    # 导入字典,用于形成编码
    with open('word2idx.pk', 'rb') as f:
        word2idx = pickle.load(f)
    with open('label2idx.pk', 'rb') as f:
        label2idx = pickle.load(f)
    with open('idx2word.pk', 'rb') as f:
        idx2word = pickle.load(f)
    with open('idx2label.pk', 'rb') as f:
        idx2label = pickle.load(f)

    try:
        # 数据预处理
        input_shape = 80  # 序列长度,就是时间步大小,也就是这里的每句话中的词的个数
        # 将对应的字转化为相应的序号
        x = [[word2idx[word] for word in sent]]
        # 如果长度不够180,使用0进行填充
        x = pad_sequences(maxlen=input_shape, sequences=x, padding='post', value=0)
        x = torch.from_numpy(x)

        # 加载模型
        model_path = './best_model.pkl'
        model = LSTM(vocab_size=vocab_size, hidden_dim=hidden_dim, num_layers=num_layers,
                     embedding_dim=embedding_dim, output_dim=output_dim)
        model.load_state_dict(torch.load(model_path, 'cpu'))

        # 模型预测,注意输入的数据第一个input_shape,就是180
        y_pred = model(x.long().transpose(1, 0))
        result_label = idx2label[y_pred.argmax().item()]

        return result_label

    except KeyError as err:
        return f"您输入的句子有汉字不在词汇表中,请重新输入!\n不在词汇表中的单词为:{err}"


测试

sent = "陈金英,一位家住浙江丽水的耄耋老人。今年这个年,陈金英过得格外舒心,因为春节前,她耗费10年,凭借自己的努力,不拖不欠,终于还清了所有欠款。"
classify_news_sentiment(sent)

结果文章来源地址https://www.toymoban.com/news/detail-705716.html

人物

到了这里,关于基于PyTorch使用LSTM实现新闻文本分类任务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part1 案例复现

    【时间序列篇】基于LSTM的序列分类-Pytorch实现 part1 案例复现 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part2 自有数据集构建 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用 本篇文章是对已有一篇文章的整理归纳,并对文章中提及的模型用Pytorch实现。 序列,

    2024年01月24日
    浏览(40)
  • 基于pytorch 的RNN实现文本分类

    首先,需要导入必要的库,包括torch、torchtext、numpy等: 然后,我们需要加载数据集并进行数据预处理。在这里,我们使用AG News数据集,其中包含120,000个新闻文本,分为四个不同的类别:World、Sports、Business和Sci/Tech。我们首先定义一个函数来预处理数据: 接下来,我们定义

    2024年02月04日
    浏览(31)
  • 【毕业设计】基于Spark的海量新闻文本聚类(新闻分类)

    🔥 Hi,大家好,这里是丹成学长的毕设系列文章! 🔥 对毕设有任何疑问都可以问学长哦! 这两年开始,各个学校对毕设的要求越来越高,难度也越来越大… 毕业设计耗费时间,耗费精力,甚至有些题目即使是专业的老师或者硕士生也需要很长时间,所以一旦发现问题,一定

    2024年02月12日
    浏览(29)
  • 基于pytorch 的RNN实现字符级姓氏文本分类

    当使用基于PyTorch的RNN实现字符级姓氏文本分类时,我们可以使用一个非常简单的RNN模型来处理输入的字符序列,并将其应用于姓氏分类任务。下面是一个基本的示例代码,包括数据预处理、模型定义和训练过程。 首先,我们需要导入必要的库: 接下来,我们将定义数据集和

    2024年02月04日
    浏览(32)
  • 大数据分析案例-基于随机森林算法构建新闻文本分类模型

    🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章 大数据分析案例合集

    2024年02月02日
    浏览(46)
  • 分类任务使用Pytorch实现Grad-CAM绘制热力图

    对于深度学习网络,在我们指定数据集类别的情况下,Grad-CAM能够绘制出相应的热力图,让我们能够非常直观的看出网络关注的主要区域与特征是什么。本文主要记录在绘制热力图过程中,自己碰到的一些实际问题,希望能对小伙伴们有所帮助。 以下是本文的参考视频和代码

    2024年02月04日
    浏览(34)
  • 【机器学习合集】人脸表情分类任务Pytorch实现&TensorBoardX的使用 ->(个人学习记录笔记)

    注意:整个项目来自阿里云天池,下面是开发人员的联系方式,本人仅作为学习记录!!! 该文章原因,学习该项目,完善注释内容,针对新版本的Pytorch进行部分代码调整 本文章采用pytorch2.0.1版本,python3.10版本 源码链接 1. 网络结构 2. 训练函数 部分代码内容与作者不同

    2024年02月08日
    浏览(29)
  • NLP | 基于LLMs的文本分类任务

    比赛链接:讯飞开放平台 来源:DataWhale AI夏令营3(NLP)   ①Roberta在预训练的阶段中没有对下一句话进行预测( NSP ) ②采用了 动态掩码 ③使用 字符级 和 词级别 表征的 混合文本编码 。 论文:https://arxiv.org/pdf/1907.11692.pdf   DataWhale Topline的改进:   特征1:平均池化Mean

    2024年02月11日
    浏览(25)
  • 第N2周:中文文本分类-Pytorch实现

    🍨 本文为🔗365天深度学习训练营 中的学习记录博客 🍖 原作者:K同学啊|接辅导、项目定制 环境搭建 Python 3.8 pytorch == 1.8.1 torchtext == 0.9.1

    2024年02月01日
    浏览(45)
  • chatgpt实现NLP基本任务(实体识别、关系抽取、属性抽取、事件抽取、文本分类)

    抽取文本: 驻港部队从1993年初开始组建,1996年1月28日组建完毕,1997年7月1日0时进驻香港,取代驻港英军接管香港防务,驻港军费均由中央人民政府负担。《中华人民共和国香港特别行政区驻军法》规定了驻香港部队的职责为防备和抵抗侵略,保卫香港特别行政区的安全以及

    2024年02月13日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包