• 情感分析:使用循环神经网络


    情感分析:使用循环神经网络

    与词相似度和类比任务一样,我们也可以将预先训练的词向量应用于情感分析。由于IMDb评论数据集不是很大,使用在大规模语料库上预训练的文本表示可以减少模型的过拟合。我们将使用预训练的Glove模型来表示每个词元,并将这些词元表示送入多层双向循环神经网络以获得文本序列表示,该文本序列表示将被转换为情感分析输出,对于相同的下游应用,我们将考虑不同的架构选择

    import torch
    from torch import nn
    from d2l import torch as d2l
    
    batch_size = 64
    train_iter,test_iter,vocab = d2l.load_data_imdb(batch_size)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1 - 使用循环神经网络表示单个文本

    在文本分类任务(如情感分析)中,可变长度的文本序列将被转化为固定长度的类别。在下面的BiRNN类中,虽然文本序列的每个词元经由嵌入层(self.embedding)获得其单独的预训练GloVe表示,但是整个序列由双向循环神经(self.encoder)编码。更具体地说,双向长短期记忆网络在初始和最终时间步的隐状态(在最后一层)被连结起来作为文本序列的表示。然后,通过一个具有两个输出(“积极”和“消极”)的全连接层(self.decoder),将此单一文本表示转换为输出类别

    class BiRNN(nn.Module):
        def __init__(self,vocab_size,embed_size,num_hiddens,num_layers,**kwargs):
            super(BiRNN,self).__init__(**kwargs)
            self.embedding = nn.Embedding(vocab_size,embed_size)
            # 将bidirectional设置为True以获取双向循环神经网络
            self.encoder = nn.LSTM(embed_size,num_hiddens,num_layers=num_layers,bidirectional=True)
            self.decoder = nn.Linear(4 * num_hiddens,2)
            
        def forward(self,inputs):
            # inputs的形状是(批量大小,时间步数)
            # 因为长短期记忆网络要求其输入的第一个维度是时间维,所在获得词元表示之前,输入会被转置,输出形状为(时间步数,批量大小,词向量维度)
            embeddings = self.embedding(inputs.T)
            self.encoder.flatten_parameters()
            
            # 返回上一个隐藏层在不同时间步的隐状态,outputs的形状是(时间步数,批量大小,2*隐藏单元数)
            outputs,_ = self.encoder(embeddings)
            
            # 连结初始和最终时间步的隐状态,作为全连接层的输入,其形状为(批量大小,4*隐藏单元数)
            encoding = torch.cat((outputs[0],outputs[-1]),dim=1)
            outs = self.decoder(encoding)
            
            return outs
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    让我们构造一个具有两个隐藏层的双向循环神经网络来表示单个文本以进行情感分析

    embed_size,num_hiddens,num_layers = 100,100,2
    devices = d2l.try_all_gpus()
    net = BiRNN(len(vocab),embed_size,num_hiddens,num_layers)
    
    • 1
    • 2
    • 3
    def init_weights(m):
        if type(m) == nn.Linear:
            nn.init.xavier_uniform_(m.weight)
        if type(m) == nn.LSTM:
            for param in m._flat_weights_names:
                if "weight" in param:
                    nn.init.xavier_uniform_(m._parameters[param])
                    
    net.apply(init_weights)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    BiRNN(
      (embedding): Embedding(49346, 100)
      (encoder): LSTM(100, 100, num_layers=2, bidirectional=True)
      (decoder): Linear(in_features=400, out_features=2, bias=True)
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2 - 加载预训练的词向量

    下面,我们为词表中的单词加载预训练的100维(需要与embed_size一致)的GloVe嵌入

    glove_embedding = d2l.TokenEmbedding('glove.6b.100d')
    
    • 1

    打印词表中所有词元向量的形状

    embeds = glove_embedding[vocab.idx_to_token]
    embeds.shape
    
    • 1
    • 2
    torch.Size([49346, 100])
    
    • 1

    我们使用这些预训练的词向量来表示评论中的词元,并且在训练期间不要更新这些向量

    net.embedding.weight.data.copy_(embeds)
    net.embedding.weight.requires_grad = False
    
    • 1
    • 2

    3 - 训练和评估模型

    现在我们可以训练双向循环神经网络进行情感分析

    lr,num_epochs = 0.01,5
    trainer = torch.optim.Adam(net.parameters(),lr=lr)
    loss = nn.CrossEntropyLoss(reduction="none")
    d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs,devices)
    
    • 1
    • 2
    • 3
    • 4
    loss 0.351, train acc 0.847, test acc 0.839
    1697.8 examples/sec on [device(type='cuda', index=0)]
    
    • 1
    • 2

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r3AAnunJ-1665320310841)(https://yingziimage.oss-cn-beijing.aliyuncs.com/img/202210092056573.svg)]

    我们定义以下函数来使用训练好的模型net,去预测文本序列的情感

    def predict_sentiment(net,vocab,sequence):
        """预测文本序列的情感"""
        sequence = torch.tensor(vocab[sequence.split()],device=d2l.try_gpu())
        label = torch.argmax(net(sequence.reshape(1, -1)), dim=1)
        return 'positive' if label == 1 else 'negative'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    最后,让我们使用训练好的模型对两个简单的句子进行情感预测

    predict_sentiment(net,vocab,'this movie is so great')
    
    • 1
    'positive'
    
    • 1
    predict_sentiment(net, vocab, 'this movie is so bad')
    
    • 1
    'negative'
    
    • 1

    4 - 小结

    • 预训练的词向量可以表示文本序列中的各个词元
    • 双向循环神经网络可以表示文本序列。例如通过连结初始和最终时间步的隐状态,可以使用全连接的层将该单个文本表示转换为类别
  • 相关阅读:
    Apache HBase概述(图文并茂~)
    [附源码]计算机毕业设计企业人事管理系统Springboot程序
    Notepad++ 和正则表达式 只保留自己想要的内容
    荣获国家高新技术企业认证,苹芯科技领航AI芯片产业发展
    28.在springboot中使用thymeleaf的内置对象(#request,#session,session)
    C语言 switch语句
    模糊控制算法实例matlab程序
    计算机操作系统第二章 进程的描述与控制
    【Learning eBPF-2】eBPF 的“Hello world”
    Bert性能提升14.8%,MindSpore算子自动生成技术详解
  • 原文地址:https://blog.csdn.net/mynameisgt/article/details/127233974