当前位置:   article > 正文

人工智能 实验六 基于循环神经网络实现情感分类_循环神经网络nlp-情感分类的实验总结

循环神经网络nlp-情感分类的实验总结

代码参照

实践 | 基于循环神经网络实现情感分类

  • 实验目的

熟悉和掌握循环神经网络的模型架构和工作原理,了解语言数据集的一些基本

概念,例如词表、数据对齐等等,掌握对语言数据集的基本预处理操作,加深对分

类问题的理解,并进一步熟悉使用paddle paddle进行深度学习。

  • 实验内容

本实验使用IMDB数据集,该数据集中包括50000条偏向明显的评论,其中包括

25000条训练数据和25000条测试数据,label0negative)和1positive)。

本实验要求使用飞桨搭建循环神经网络模型,并利用上述数据集训练该模型;

训练结束后保存模型,存储模型的参数;评估网络时,从参数文件中加载模型参

数,再评估模型。

  • 实验环境

1.建议使用百度提供的AI Studio平台做下面两个实验,该平台提供了免费的算

力支持,并且已经集成了我们要用的paddle等库。

https://aistudio.baidu.com/aistudio/index

进入网页后--》点击项目》创建项目Notebook—》选paddle 2.0.2版本

》创建即可。该实验建议选择gpu环境,否则训练十分缓慢。

2.如果要在自己电脑实验,Paddle Paddle的安装参考一下飞桨的官方文档:

https://www.paddlepaddle.org.cn/install/quickpaddlepaddle的版本建议选择2.0.2登

三、实验步骤

1.登入飞桨平台https://aistudio.baidu.com/index

2.登录后创建项目

3.选Notebook->+添加数据集->选择IMDB情感分析数据集->选AI Studio经典版->选paddle 2.0.2版本->创建

4.启动环境->选择GPU->确定->进入

5.代码段分开

一、环境设置

  1. import paddle
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import paddle.nn as nn
  5. print(paddle.__version__) # 查看当前版本
  6. # cpu/gpu环境选择,在 paddle.set_device() 输入对应运行设备。
  7. #device = paddle.set_device('gpu')


二、数据准备

  1. # 加载训练数据
  2. train_dataset = paddle.text.datasets.Imdb(mode='train')
  3. # 加载测试数据
  4. test_dataset = paddle.text.datasets.Imdb(mode='test')
  5. #eval_dataset
  1. word_dict = train_dataset.word_idx # 获取数据集的词表
  2. # add a pad token to the dict for later padding the sequence
  3. word_dict['<pad>'] = len(word_dict)
  4. for k in list(word_dict)[:5]:
  5. print("{}:{}".format(k.decode('ASCII'), word_dict[k]))
  6. print("...")
  7. for k in list(word_dict)[-5:]:
  8. print("{}:{}".format(k if isinstance(k, str) else k.decode('ASCII'), word_dict[k]))
  9. print("totally {} words".format(len(word_dict)))

三、 参数设置

设置词表大小,embedding的大小,batch_size,等等

  1. vocab_size = len(word_dict) + 1
  2. print(vocab_size)
  3. emb_size = 256
  4. seq_len = 200
  5. batch_size = 32
  6. epochs = 2
  7. pad_id = word_dict['<pad>']
  8. classes = ['negative', 'positive']
  9. # 生成句子列表
  10. def ids_to_str(ids):
  11. # print(ids)
  12. words = []
  13. for k in ids:
  14. w = list(word_dict)[k]
  15. words.append(w if isinstance(w, str) else w.decode('ASCII'))
  16. return " ".join(words)
  1. # 可以用 docs 获取数据的list,用 labels 获取数据的label值,打印出来对数据有一个初步的印象。
  2. # 取出来第一条数据看看样子。
  3. sent = train_dataset.docs[0]
  4. label = train_dataset.labels[1]
  5. print('sentence list id is:', sent)
  6. print('sentence label id is:', label)
  7. print('--------------------------')
  8. print('sentence list is: ', ids_to_str(sent))
  9. print('sentence label is: ', classes[label])

四、对齐数据

文本数据中,每一句话的长度都是不一样的,为了方便后续的神经网络的计算,常见的处理方式是把数据集中的数据都统一成同样长度的数据。这包括:对于较长的数据进行截断处理,对于较短的数据用特殊的词进行填充。

  1. # 读取数据归一化处理
  2. def create_padded_dataset(dataset):
  3. padded_sents = []
  4. labels = []
  5. for batch_id, data in enumerate(dataset):
  6. sent, label = data[0], data[1]
  7. padded_sent = np.concatenate([sent[:seq_len], [pad_id] * (seq_len - len(sent))]).astype('int32')
  8. padded_sents.append(padded_sent)
  9. labels.append(label)
  10. return np.array(padded_sents), np.array(labels)
  11. # 对train、test数据进行实例化
  12. train_sents, train_labels = create_padded_dataset(train_dataset)
  13. test_sents, test_labels = create_padded_dataset(test_dataset)
  14. # 查看数据大小及举例内容
  15. print(train_sents.shape)
  16. print(train_labels.shape)
  17. print(test_sents.shape)
  18. print(test_labels.shape)
  19. for sent in train_sents[:3]:
  20. print(ids_to_str(sent))

五、用Dataset 与 DataLoader 加载

将前面准备好的训练集与测试集用Dataset 与 DataLoader封装后,完成数据的加载。

  1. class IMDBDataset(paddle.io.Dataset):
  2. '''
  3. 继承paddle.io.Dataset类进行封装数据
  4. '''
  5. def __init__(self, sents, labels):
  6. self.sents = sents
  7. self.labels = labels
  8. def __getitem__(self, index):
  9. data = self.sents[index]
  10. label = self.labels[index]
  11. return data, label
  12. def __len__(self):
  13. return len(self.sents)
  14. train_dataset = IMDBDataset(train_sents, train_labels)
  15. test_dataset = IMDBDataset(test_sents, test_labels)
  16. train_loader = paddle.io.DataLoader(train_dataset, return_list=True,
  17. shuffle=True, batch_size=batch_size, drop_last=True)
  18. test_loader = paddle.io.DataLoader(test_dataset, return_list=True,
  19. shuffle=True, batch_size=batch_size, drop_last=True)

六、模型配置

  1. import paddle.nn as nn
  2. import paddle
  3. # 定义RNN网络
  4. class MyRNN(paddle.nn.Layer):
  5. def __init__(self):
  6. super(MyRNN, self).__init__()
  7. self.embedding = nn.Embedding(vocab_size, 256)
  8. self.rnn = nn.SimpleRNN(256, 256, num_layers=2, direction='forward',dropout=0.5)#维数,隐藏维数,层数
  9. self.linear = nn.Linear(in_features=256*2, out_features=2)
  10. self.dropout = nn.Dropout(0.5)
  11. def forward(self, inputs):
  12. emb = self.dropout(self.embedding(inputs))
  13. #output形状大小为[batch_size,seq_len,num_directions * hidden_size]
  14. #hidden形状大小为[num_layers * num_directions, batch_size, hidden_size]
  15. #把前向的hidden与后向的hidden合并在一起
  16. output, hidden = self.rnn(emb)
  17. hidden = paddle.concat((hidden[-2,:,:], hidden[-1,:,:]), axis = 1)
  18. #hidden形状大小为[batch_size, hidden_size * num_directions]
  19. hidden = self.dropout(hidden)
  20. return self.linear(hidden)

七、模型训练

  1. # 可视化定义
  2. def draw_process(title,color,iters,data,label):
  3. plt.title(title, fontsize=24)
  4. plt.xlabel("iter", fontsize=20)
  5. plt.ylabel(label, fontsize=20)
  6. plt.plot(iters, data,color=color,label=label)
  7. plt.legend()
  8. plt.grid()
  9. plt.show()
  1. # 对模型进行封装
  2. def train(model):
  3. model.train()
  4. opt = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters())
  5. steps = 0
  6. Iters, total_loss, total_acc = [], [], []
  7. for epoch in range(epochs):
  8. for batch_id, data in enumerate(train_loader):
  9. steps += 1
  10. sent = data[0]
  11. label = data[1]
  12. logits = model(sent)
  13. loss = paddle.nn.functional.cross_entropy(logits, label)
  14. acc = paddle.metric.accuracy(logits, label)
  15. if batch_id % 500 == 0: # 500个epoch输出一次结果
  16. Iters.append(steps)
  17. total_loss.append(loss.numpy()[0])
  18. total_acc.append(acc.numpy()[0])
  19. print("epoch: {}, batch_id: {}, loss is: {}".format(epoch, batch_id, loss.numpy()))
  20. loss.backward()
  21. opt.step()
  22. opt.clear_grad()
  23. # evaluate model after one epoch
  24. model.eval()
  25. accuracies = []
  26. losses = []
  27. for batch_id, data in enumerate(test_loader):
  28. sent = data[0]
  29. label = data[1]
  30. logits = model(sent)
  31. loss = paddle.nn.functional.cross_entropy(logits, label)
  32. acc = paddle.metric.accuracy(logits, label)
  33. accuracies.append(acc.numpy())
  34. losses.append(loss.numpy())
  35. avg_acc, avg_loss = np.mean(accuracies), np.mean(losses)
  36. print("[validation] accuracy: {}, loss: {}".format(avg_acc, avg_loss))
  37. model.train()
  38. # 保存模型
  39. paddle.save(model.state_dict(),str(epoch)+"_model_final.pdparams")
  40. # 可视化查看
  41. draw_process("trainning loss","red",Iters,total_loss,"trainning loss")
  42. draw_process("trainning acc","green",Iters,total_acc,"trainning acc")
  43. model = MyRNN()
  44. train(model)

 八、模型评估

  1. '''
  2. 模型评估
  3. '''
  4. model_state_dict = paddle.load('1_model_final.pdparams') # 导入模型
  5. model = MyRNN()
  6. model.set_state_dict(model_state_dict)
  7. model.eval()
  8. accuracies = []
  9. losses = []
  10. for batch_id, data in enumerate(test_loader):
  11. sent = data[0]
  12. label = data[1]
  13. logits = model(sent)
  14. loss = paddle.nn.functional.cross_entropy(logits, label)
  15. acc = paddle.metric.accuracy(logits, label)
  16. accuracies.append(acc.numpy())
  17. losses.append(loss.numpy())
  18. avg_acc, avg_loss = np.mean(accuracies), np.mean(losses)
  19. print("[validation] accuracy: {}, loss: {}".format(avg_acc, avg_loss))

九、模型预测

  1. def ids_to_str(ids):
  2. words = []
  3. for k in ids:
  4. w = list(word_dict)[k]
  5. words.append(w if isinstance(w, str) else w.decode('UTF-8'))
  6. return " ".join(words)
  7. label_map = {0:"negative", 1:"positive"}
  8. # 导入模型
  9. model_state_dict = paddle.load('1_model_final.pdparams')
  10. model = MyRNN()
  11. model.set_state_dict(model_state_dict)
  12. model.eval()
  13. for batch_id, data in enumerate(test_loader):
  14. sent = data[0]
  15. results = model(sent)
  16. predictions = []
  17. for probs in results:
  18. # 映射分类label
  19. idx = np.argmax(probs)
  20. labels = label_map[idx]
  21. predictions.append(labels)
  22. for i,pre in enumerate(predictions):
  23. print(' 数据: {} \n 情感: {}'.format(ids_to_str(sent[0]), pre))
  24. break
  25. break

图片如下,每段代码单独放置

想要运行点“运行全部”,或者一段一段接着点运行,上一段运行结束再点下一段。

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

闽ICP备14008679号