23 | 情感分析:如何使用LSTM进行情感分析?
数据准备
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何使用LSTM进行情感分析。作者首先解释了情感分析的概念和应用场景,然后详细介绍了使用Torchtext工具包读取IMDB数据集,并利用分词器和词汇表对文本进行处理。接着,作者讲解了数据处理pipelines的创建和训练数据的生成,以及如何处理变长数据。随后,文章详细介绍了LSTM网络的构建和训练过程,包括模型定义、损失函数与优化方法的设置,以及训练过程中的loss计算和模型评估。最后,文章提出了一个练习任务,要求读者编写一个函数实现输入一句话,输出情绪类别与概率的功能。整篇文章以教程的形式呈现,适合对情感分析和自然语言处理感兴趣的读者阅读学习。文章内容详实,涵盖了情感分析的技术细节和实现步骤,对读者进行了全面的指导。
《PyTorch 深度学习实战》,新⼈⾸单¥59
全部留言(21)
- 最新
- 精选
- 李雄置顶如果是使用torchtext==0.8.1以下的版本建议看官网文档: https://pytorch.org/text/0.8.1/datasets.html2021-12-311
- 林于翔LSTM模型定义中: if self.lstm.bidirectional: hidden = self.dropout(torch.cat([hidden[-1], hidden[-2]], dim=-1)) 这里不太理解,最后连接的不是最后一层hidden的第一个时间步和最后一个时间步嘛?另外dim为什么会是-1。
作者回复: Hello,感谢留言。 我们首先看一下torch.nn.LSTM这个函数的输入与输出,详见文档: https://pytorch.org/docs/stable/generated/torch.nn.LSTM.html?highlight=nn%20lstm#torch.nn.LSTM torch.nn.LSTM的输入参数: input_size: 表示的是输入的矩阵特征数 hidden_size: 表示的是输出矩阵特征数 num_layers 表示堆叠几层的LSTM,默认是1 bidirectional: 默认是false,代表不用双向LSTM,双向LSTM,也就是序列从左往右算一次,从右往左又算一次,这样就可以两倍的输出 batch_first: True 或者 False,因为nn.lstm()接受的数据输入是(序列长度,batch,输入维数),这和我们cnn输入的方式不太一致,所以使用batch_first,我们可以将输入变成(batch,序列长度,输入维数) torch.nn.LSTM的输出格式为:output,(h_n,c_n) 其中: output的shape=(seq_length,batch_size,num_directions*hidden_size),它包含的是LSTM的最后一时间步的输出特征(h_t),t是batch_size中每个句子的长度。 h_n.shape==(num_directions * num_layers,batch,hidden_size) c_n.shape==h_n.shape h_n包含的是句子的最后一个单词(也就是最后一个时间步)的隐藏状态,c_n包含的是句子的最后一个单词的细胞状态,所以它们都与句子的长度seq_length无关。 output[-1]与h_n是相等的,因为output[-1]包含的正是batch_size个句子中每一个句子的最后一个单词的隐藏状态。 if self.lstm.bidirectional: hidden = self.dropout(torch.cat([hidden[-1], hidden[-2]], dim=-1)) 这里面,hidden是torch.nn.LSTM的第二个输出h_n,hidden的shape是(2 * 2, batch, 300)。 因此,双向LSTM时,hidden[-1]表示从最后一个堆叠的从左到右的LSTM的的最后一个时间步向量,hidden[-2]表示最后一个堆叠的从右到左的LSTM最后一个时间步向量。将这两个向量拼接在一起,得到最后的hidden层。 而dim=-1表示torch.cat的拼接方式,拼接300(embedding_dim)那个维度,也就是将两个300维度的向量拼接成一个600维度的向量。
2021-12-171 - hallo128torchtext可以支持中文分词吗
作者回复: 你好,感谢你的留言。 torchtext支持的分词器有:spacy, moses, toktok, revtok, subword。 spacy库是可以支持中文分词的。 可以尝试以下代码: import spacy spacy = spacy.load("zh_core_web_sm") tokenizer = get_tokenizer(spacy)
2022-06-30 - Geek_a82ba7import torchtext train_iter = torchtext.datasets.IMDB(root='./data', split='train') next(train_iter) 'MapperIterDataPipe' object is not an iterator 为什么说这个不是一个迭代器,查了很多资料都没有解决,老师能回答一下吗? c
作者回复: 您好,感谢你的留言。 看看是不是torchtext版本更新了? 我用的是0.10.1
2022-06-214 - Sarai青霞方老师,我试了代码,输出显示: "\n输出:['here', 'is', 'the', 'an', 'example', '!']\n" 是断行出现问题了吗? 谢谢!
作者回复: 你好,感谢留言。 python的多行注释是用三对单引号。 ''' 输出:['here', 'is', 'the', 'an', 'example', '!'] ''' 这部分内容是代码中的注释,为了告诉你上述代码的运行结果是什么。 有的IDE运行时会输出多行注释,只需把注释删除即可,并不是断行出现问题。
2022-06-01 - Ringcoo老师好,请问 packed_output, (hidden, cell) = self.lstm(packed_embedded) output, output_length = torch.nn.utils.rnn.pad_packed_sequence(packed_output) 为什么从lstm层出来以后 会有(hidden, cell) ,我不太理解,以及为什么lstm层出来以后还有在进RNN层,底下的流程图上明明是lstm层出来以后进入了fc全连接层。麻烦您讲解一下
作者回复: hello,Ringcoo,你好。感谢你的留言。 当我们训练LSTM时,因为文本句子长短不一,如果想要进行批次化训练,就需要选择一个合适的长度来进行截断和填充。 torch.nn.utils.rnn.pad_packed_sequence()并不是一个rnn层,这个函数的目的是将LSTM返回的结果进行统一填充,得到长度相同的Tensor对象。 hidden和cell是LSTM的结构中的一部分。 LSTM神经元在时间维度上向后传递了两份信息: (1)cell state; (2)hidden state。 hidden state是cell state经过一个神经元和一道“输出门”后得到的,因此hidden state里包含的记忆,实际上是cell state衰减之后的内容。 另外,cell state在一个衰减较少的通道里沿时间轴传递,对时间跨度较大的信息的保持能力比hidden state要强很多。 因此,实际上hidden state里存储的,主要是“近期记忆”;cell state里存储的,主要是“远期记忆”。 cell state的存在,使得LSTM得以对长依赖进行很好地刻画。
2022-05-01 - 赵心睿请问使用的torchtext是哪个版本的呢?
作者回复: 你好,赵心睿,感谢留言。使用的是0.10.1。
2022-03-14 - 快乐小夜曲packed_embedded = torch.nn.utils.rnn.pack_padded_sequence(embedded, length.to('cpu'), batch_first=True, enforce_sorted=False) 这里length必须转为成cpu,否则会报错。
作者回复: 你好,快乐小夜曲,感谢你的留言。 在train函数中,已经对length进行了转换:length = length.to(device) length是从外部传入的,所以这里无需显示对length再进行转换了。
2022-01-02 - 李雄请问这是那个版本的torchtext
作者回复: hello,我用的是torchtext 0.10.1。
2021-12-31 - 吴十一def predict_sentiment(text, model, tokenizer, vocab, device): max_length = 256 pad = text_pipeline('<pad>') processed_text = text_pipeline(text)[:max_length] ids, length = [],[] ids.append((processed_text+pad*max_length)[:max_length]) length.append(len(processed_text)) ids_t,length_t = torch.tensor(ids, dtype = torch.int64), torch.tensor(length, dtype = torch.int64) print(ids_t,length_t) ids_t.to(device) length_t.to(device) pred = model(ids_t,length_t) return pred vocab_size = len(vocab) embedding_dim = 300 hidden_dim = 300 output_dim = 2 n_layers = 2 bidirectional = True dropout_rate = 0.5 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model = LSTM(vocab_size, embedding_dim, hidden_dim, output_dim, n_layers, bidirectional, dropout_rate) model = model.to(device) model.load_state_dict(torch.load("./lstm.pt")) model.eval() text = "This film is terrible!" pred = predict_sentiment(text, model, tokenizer, vocab, device) ''' 输出:('neg', 0.8874172568321228) ''' tips:一定要安装torchtext 稍微新点的版本,0.6.0 IDMB数据set跑报错,会一直要求用tensorflow v1 版本兼容2022-06-121