当前位置:   article > 正文

RNN神经网络实现文本情感分析_rnn的情感分析模型

rnn的情感分析模型

 基本思想

定义模型:使用RNNClassifier类定义了一个简单的循环神经网络模型,其中包括一个嵌入层、一个循环层和一个全连接层。

准备数据:定义了prepare_sequence函数,将文本数据转换为模型可接受的张量形式,并构建了单词到索引的映射word_to_ix和标签到索引的映射label_to_ix

定义超参数:定义了嵌入维度、隐藏状态维度、词汇表大小和输出类别数等超参数。

实例化模型、损失函数和优化器:创建了模型实例、交叉熵损失函数实例和随机梯度下降(SGD)优化器实例。

训练模型:使用双重循环进行了模型训练,外部循环控制训练轮数,内部循环遍历训练数据并更新模型参数。

测试模型:使用训练好的模型对训练数据进行了简单的测试,输出了每个句子的情感分类结果。                                                                                                                                       

定义模型

   

  1. class RNNClassifier(nn.Module):
  2. def __init__(self, input_size, hidden_size, output_size=2):
  3. super(RNNClassifier, self).__init__()
  4. self.hidden_size = hidden_size
  5. self.embedding = nn.Embedding(input_size, hidden_size)
  6. self.rnn = nn.RNN(hidden_size, hidden_size, batch_first=True)
  7. self.fc = nn.Linear(hidden_size, output_size)
  8. def forward(self, input):
  9. embedded = self.embedding(input)
  10. output, hidden = self.rnn(embedded.view(1, -1, self.hidden_size))
  11. # 移除维度为1的维度
  12. output = torch.squeeze(output, 0)
  13. output = self.fc(output)
  14. return output

在初始化函数__init__中,定义了模型的输入大小input_size、隐藏层大小hidden_size和输出大小output_size,默认为2。在初始化过程中调用了父类的初始化方法super(RNNClassifier, self).init(),并定义了模型的隐藏层大小、词嵌入层、RNN层和全连接层。

forward方法定义了模型的前向传播过程。首先将输入input通过词嵌入层embedding进行词嵌入操作,然后将嵌入后的数据传入RNN层中进行处理,得到输出output和隐藏状态hidden。接着通过压缩维度操作torch.squeeze去除维度为1的维度,再将输出数据传入全连接层fc中,得到最终的输出结果。最后返回输出结果output。   

数据准备

  1. def prepare_sequence(seq, to_ix):
  2. idxs = [to_ix[w] for w in seq]
  3. return torch.tensor(idxs, dtype=torch.long)

将文本序列转换为数值序列,这对于将单词输入到神经网络中是必要的,因为神经网络无法直接处理字符串或文本数据。相反,需要将这些单词转换为数字表示(索引),以便可以在嵌入层等结构中使用。

超参数的设置

EMBEDDING_DIM = 10:表示词嵌入的维度,即将词语映射到稠密向量空间的维度大小为10。

HIDDEN_DIM = 10:表示RNN隐藏状态的维度,即RNN模型中隐藏状态的维度大小为10。

VOCAB_SIZE = len(word_to_ix):表示词汇表的大小,即训练数据中所有不同单词的数量。

OUTPUT_SIZE = len(label_to_ix):表示输出类别的数量,即训练数据中所有不同标签的数量。

超参数是指在训练模型之前需要设置的参数,这些参数不是通过训练数据学习得到的,而是需要手动设置的。通过定义超参数,我们可以根据具体的任务需求和实验结果来调整模型的性能和效果。

 训练模型 

这段代码实现了迭代训练轮数,遍历训练数据,模型参数梯度清零,输入数据,获取模型输出数据,计算损失,反向传播梯度更新。

  1. for epoch in range(300):
  2. for sentence, label in training_data:
  3. model.zero_grad()
  4. inputs = prepare_sequence(sentence.split(), word_to_ix)
  5. # 扩展目标标签的维度以匹配模型输出的形状
  6. target = torch.tensor([label_to_ix[label]] * len(inputs), dtype=torch.long)
  7. output = model(inputs)
  8. loss = loss_function(output, target)
  9. loss.backward()
  10. optimizer.step()

测试模型

  1. with torch.no_grad():
  2. for sentence, _ in training_data:
  3. inputs = prepare_sequence(sentence.split(), word_to_ix)
  4. output = model(inputs)
  5. predicted_label = torch.argmax(output).item()
  6. print(f"Sentence: {sentence}, Predicted Label: {'positive' if predicted_label == 0 else 'negative'}")

通过rnn模型进行情感的预测

完整代码

  1. import torch
  2. import torch.nn as nn
  3. import torch.optim as optim
  4. import numpy as np
  5. # 构建 RNN 模型
  6. class RNNClassifier(nn.Module):
  7. def __init__(self, input_size, hidden_size, output_size=2):
  8. super(RNNClassifier, self).__init__()
  9. self.hidden_size = hidden_size
  10. self.embedding = nn.Embedding(input_size, hidden_size)
  11. self.rnn = nn.RNN(hidden_size, hidden_size, batch_first=True)
  12. self.fc = nn.Linear(hidden_size, output_size)
  13. def forward(self, input):
  14. embedded = self.embedding(input)
  15. output, hidden = self.rnn(embedded.view(1, -1, self.hidden_size))
  16. # 移除维度为1的维度
  17. output = torch.squeeze(output, 0)
  18. output = self.fc(output)
  19. return output
  20. # 准备数据
  21. def prepare_sequence(seq, to_ix):
  22. idxs = [to_ix[w] for w in seq]
  23. return torch.tensor(idxs, dtype=torch.long)
  24. training_data = [
  25. ("I love PyTorch", "positive"),
  26. ("I hate TensorFlow", "negative"),
  27. ("PyTorch is awesome", "positive"),
  28. ("TensorFlow is okay", "negative")
  29. ]
  30. word_to_ix = {}
  31. for sent, _ in training_data:
  32. for word in sent.split():
  33. if word not in word_to_ix:
  34. word_to_ix[word] = len(word_to_ix)
  35. label_to_ix = {"positive": 0, "negative": 1}
  36. # 定义超参数
  37. EMBEDDING_DIM = 10
  38. HIDDEN_DIM = 10
  39. VOCAB_SIZE = len(word_to_ix)
  40. OUTPUT_SIZE = len(label_to_ix)
  41. # 实例化模型、损失函数和优化器
  42. model = RNNClassifier(VOCAB_SIZE, HIDDEN_DIM, OUTPUT_SIZE)
  43. loss_function = nn.CrossEntropyLoss()
  44. optimizer = optim.SGD(model.parameters(), lr=0.1)
  45. # 训练模型
  46. # 训练模型
  47. for epoch in range(300):
  48. for sentence, label in training_data:
  49. model.zero_grad()
  50. inputs = prepare_sequence(sentence.split(), word_to_ix)
  51. # 扩展目标标签的维度以匹配模型输出的形状
  52. target = torch.tensor([label_to_ix[label]] * len(inputs), dtype=torch.long)
  53. output = model(inputs)
  54. loss = loss_function(output, target)
  55. loss.backward()
  56. optimizer.step()
  57. # 测试模型
  58. with torch.no_grad():
  59. for sentence, _ in training_data:
  60. inputs = prepare_sequence(sentence.split(), word_to_ix)
  61. output = model(inputs)
  62. predicted_label = torch.argmax(output).item()
  63. print(f"Sentence: {sentence}, Predicted Label: {'positive' if predicted_label == 0 else 'negative'}")

局限性

RNN网络会不可避免地带来一个问题:最后的输出结果受最近的输入较大,而之前较远的输入可能无法影响结果,这就是信息瓶颈问题,为了解决这个问题引入了双向LSTM。双向LSTM不仅增加了反向信息传播,而且每一轮的都会有一个输出,将这些输出进行组合之后再传给全连接层。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/780725
推荐阅读
  

闽ICP备14008679号