文章目录

  • TextCNN
  • 一、文件目录
  • 二、语料库(MR)
  • 三、数据处理(MR_Dataset.py)
  • 四、模型(TextCNN.py)
  • 五、防止过拟合(pytorchtools.py)
  • 六、训练和测试
  • 实验结果

TextCNN

一、文件目录

二、语料库(MR)

MR数据集(电影评论):
1.积极评论
2.消极评论

三、数据处理(MR_Dataset.py)

1.词向量导入
2.数据集加载
3.构建word2id并pad成相同的长度
4.求词向量均值和方差
5.生成词向量
6.生成训练集,验证集和测试集

from torch.utils import data
import os
import random
import numpy as np
from gensim.test.utils import datapath, get_tmpfile
from gensim.models import KeyedVectors
class MR_Dataset(data.Dataset):def __init__(self, state="train",k=0,embedding_type="word2cec"):self.path = os.path.abspath('.')if "data" not in self.path:self.path+="/data"# 加载MR数据集pos_samples = open(self.path+"/MR/rt-polarity.pos", errors="ignore").readlines()neg_samples = open(self.path+"/MR/rt-polarity.neg", errors="ignore").readlines()datas = pos_samples + neg_samplesdatas = [data.split() for data in datas]labels = [1] * len(pos_samples) + [0] * len(neg_samples)  # 区分积极,消极的标签# 构建word2id并pad成相同长度max_sample_length = max([len(sample) for sample in datas])word2id = {"<pad>": 0}for i, data in enumerate(datas):for j, word in enumerate(data):if word2id.get(word) == None:word2id[word] = len(word2id)datas[i][j] = word2id[word]datas[i] = datas[i] + [0] * (max_sample_length - len(datas[i]))  # 将所有句子pad成max_sample_length的长度 [10662,59]self.n_vocab = len(word2id)self.word2id = word2idif embedding_type=="word2vec":self.get_word2vec()# 将数据和标签打包一起打乱c = list(zip(datas, labels))random.seed(1)random.shuffle(c)datas[:], labels[:] = zip(*c)if state == "train":# [0 : 9]->[1 : 9]self.datas = datas[:int(k * len(datas) / 10)] + datas[int((k + 1) * len(datas) / 10):]self.labels = labels[:int(k * len(datas) / 10)] + labels[int((k + 1) * len(labels) / 10):]# [1 : 9]->[0 : 0.9*[1,9]]self.datas = np.array(self.datas[0:int(0.9 * len(self.datas))])self.labels = np.array(self.labels[0:int(0.9 * len(self.labels))])elif state == "valid":# [0 : 9]->[1 : 9]self.datas = datas[:int(k * len(datas) / 10)] + datas[int((k + 1) * len(datas) / 10):]self.labels = labels[:int(k * len(datas) / 10)] + labels[int((k + 1) * len(labels) / 10):]# [1 : 9]->[0.9*[1,9] : [1,9]]self.datas = np.array(self.datas[int(0.9 * len(self.datas)):])self.labels = np.array(self.labels[int(0.9 * len(self.labels)):])elif state == "test":# [0 : 9]->[0 : 1]self.datas = np.array(datas[int(k * len(datas) / 10):int((k + 1) * len(datas) / 10)])self.labels = np.array(labels[int(k * len(datas) / 10):int((k + 1) * len(datas) / 10)])def get_word2vec(self):if  not os.path.exists(self.path+"/word2vec_embedding_mr.npy"): # 如果已经保存了词向量,就直接读取print ("Reading word2vec Embedding...")# 求所用词向量均值和方差wvmodel = KeyedVectors.load_word2vec_format("./GoogleNews-vectors-negative300.bin.gz", binary=True)  # 词向量导入tmp = []  # 词向量for word, index in self.word2id.items():try:tmp.append(wvmodel.get_vector(word))except:passmean = np.mean(np.array(tmp))  # 均值std = np.std(np.array(tmp))  # 方差# 生成词向量vocab_size = len(self.word2id)embed_size = 300embedding_weights = np.random.normal(mean, std, [vocab_size, embed_size])  # 在word2id中找不到的话随机初始化实现for word, index in self.word2id.items():try:embedding_weights[index, :] = wvmodel.get_vector(word)  # (21402, 300)except:passnp.save(self.path + "/word2vec_embedding_mr.npy", embedding_weights)  # 保存生成的词向量else:embedding_weights = np.load(self.path + "/word2vec_embedding_mr.npy")  # 载入生成的词向量self.weight = embedding_weightsdef __getitem__(self, index):return self.datas[index], self.labels[index]def __len__(self):return len(self.datas)if __name__ == "__main__":# 生成训练集mr_train_dataset = MR_Dataset()print(mr_train_dataset.__len__())# 生成验证集mr_valid_dataset = MR_Dataset("valid")print(mr_valid_dataset.__len__())# 生成测试集mr_test_dataset = MR_Dataset("test")print(mr_test_dataset.__len__())

四、模型(TextCNN.py)

import torch
import torch.nn as nn
import numpy as np
class C2W(nn.Module):def __init__(self, config):super(C2W, self).__init__()self.char_hidden_size = config.char_hidden_sizeself.word_embed_size = config.word_embed_sizeself.lm_hidden_size = config.lm_hidden_sizeself.character_embedding = nn.Embedding(config.n_chars,config.char_embed_size) # 字符嵌入层,64,50self.sentence_length = config.max_sentence_lengthself.char_lstm = nn.LSTM(input_size=config.char_embed_size,hidden_size=config.char_hidden_size,bidirectional=True,batch_first=True)  # 字符lstm,50,50,self.lm_lstm = nn.LSTM(input_size=self.word_embed_size,hidden_size=config.lm_hidden_size,batch_first=True) # 语言模型lstm.50,150self.fc_1 = nn.Linear(2*config.char_hidden_size,config.word_embed_size) # 线性组合生成词表示self.fc_2 =nn.Linear(config.lm_hidden_size,config.vocab_size) # 生成类别用于预测def forward(self, x):input = self.character_embedding(x) #[64, 16, 50]char_lstm_result = self.char_lstm(input) #[64, 16, 100]word_input = torch.cat([char_lstm_result[0][:,-1,0:self.char_hidden_size],char_lstm_result[0][:,0,self.char_hidden_size:]],dim=1) #[64,100]word_input = self.fc_1(word_input) #[64,50]word_input = word_input.view([-1,self.sentence_length,self.word_embed_size]) #[8,8,50]lm_lstm_result = self.lm_lstm(word_input)[0].contiguous() #[8, 8, 150]lm_lstm_result = lm_lstm_result.view([-1,self.lm_hidden_size]) #[64, 150]print(lm_lstm_result.shape)out = self.fc_2(lm_lstm_result) #[64, 1000]return out
class config:def __init__(self):self.n_chars = 64  # 字符的个数self.char_embed_size = 50 # 字符嵌入大小self.max_sentence_length = 8 # 最大句子长度self.char_hidden_size = 50 # 字符lstm的隐藏层神经元个数self.lm_hidden_size = 150 # 语言模型的隐藏神经元个数self.word_embed_size = 50 # 生成的词表示大小config.vocab_size = 1000 # 词表大小
if __name__=="__main__":config = config()c2w = C2W(config)test = np.zeros([64,16])c2w(test)

五、防止过拟合(pytorchtools.py)

import numpy as np
import torchclass EarlyStopping:"""如果在给定的耐心之后,验证失败没有改善,那么Early会停止培训。"""def __init__(self, patience=7, verbose=False, delta=0,cv_index = 0):"""Args:patience (int):上次验证失败改善后需要等待多长时间。默认值:7verbose (bool): 如果为真,则为每个验证丢失改进打印一条消息。默认值:Falsedelta (float):监控量的最小变化,符合改善条件。默认值:0"""self.patience = patienceself.verbose = verboseself.counter = 0self.best_score = Noneself.early_stop = Falseself.val_loss_min = np.Infself.delta = deltaself.cv_index = cv_indexdef __call__(self, val_loss, model):score = -val_lossif self.best_score is None:self.best_score = scoreself.save_checkpoint(val_loss, model)elif score < self.best_score + self.delta:self.counter += 1print('EarlyStopping counter: %d out of %d'%(self.counter,self.patience))if self.counter >= self.patience:self.early_stop = Trueelse:self.best_score = scoreself.save_checkpoint(val_loss, model)self.counter = 0def save_checkpoint(self, val_loss, model):'''验证损失减少时保存模型。'''if self.verbose:print('Validation loss decreased (%.5f --> %.5f).  Saving model ...'%(self.val_loss_min,val_loss))torch.save(model.state_dict(), './checkpoints/checkpoint%d.pt'%self.cv_index)self.val_loss_min = val_loss

六、训练和测试

from pytorchtools import EarlyStopping
import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.optim as optim
from model import TextCNN
from data import MR_Dataset
import numpy as np
import config as argumentparser
config = argumentparser.ArgumentParser()
config.filters = list(map(int,config.filters.split(","))) # conv的大小
torch.manual_seed(config.seed) # 随机种子
# 判断cuda是否可用
if torch.cuda.is_available():torch.cuda.set_device(config.gpu)
i=0
early_stopping = EarlyStopping(patience=10, verbose=True,cv_index=i)
#训练集
training_set = MR_Dataset(state="train",k=i,embedding_type=config.embedding_type) #
config.n_vocab = training_set.n_vocab # 词表大小
training_iter = torch.utils.data.DataLoader(dataset=training_set,batch_size=config.batch_size,shuffle=True,num_workers=0) # num_workers=2,线程个数2
if config.use_pretrained_embed:config.embedding_pretrained = torch.from_numpy(training_set.weight).float() # 标记
else:config.embedding_pretrained = False
#验证集
valid_set = MR_Dataset(state="valid", k=i,embedding_type="no")
valid_iter = torch.utils.data.DataLoader(dataset=valid_set,batch_size=config.batch_size,shuffle=False,num_workers=0)
#测试集
test_set = MR_Dataset(state="test", k=i,embedding_type="no")
test_iter = torch.utils.data.DataLoader(dataset=test_set,batch_size=config.batch_size,shuffle=False,num_workers=0)model = TextCNN(config)if config.cuda and torch.cuda.is_available():model.cuda()config.embedding_pretrained.cuda()criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=config.learning_rate)
count = 0
loss_sum = 0def get_test_result(data_iter,data_set):model.eval()data_loss = 0true_sample_num = 0for data, label in data_iter:if config.cuda and torch.cuda.is_available():data = data.cuda()label = label.cuda()else:data = torch.autograd.Variable(data).long()out = model(data)#(bc,2)loss = criterion(out, autograd.Variable(label.long()))data_loss += loss.data.item()true_sample_num += np.sum((torch.argmax(out, 1) == label).cpu().numpy())acc = true_sample_num / data_set.__len__()return data_loss,accfor epoch in range(config.epoch):# 训练开始model.train()for data, label in training_iter:if config.cuda and torch.cuda.is_available():data = data.cuda()label = label.cuda()else:data = torch.autograd.Variable(data).long()label = torch.autograd.Variable(label).squeeze()out = model(data)l2_loss = config.l2*torch.sum(torch.pow(list(model.parameters())[1],2))loss = criterion(out, autograd.Variable(label.long()))+l2_lossloss_sum += loss.data.item()count += 1if count % 100 == 0:print("epoch", epoch, end='  ')print("The loss is: %.5f" % (loss_sum / 100))loss_sum = 0count = 0optimizer.zero_grad()loss.backward()optimizer.step()# save the model in every epoch# 一轮训练结束# 验证集上测试valid_loss,valid_acc = get_test_result(valid_iter,valid_set)early_stopping(valid_loss, model)print ("The valid acc is: %.5f" % valid_acc)if early_stopping.early_stop:print("Early stopping")break# 训练结束,开始测试acc = 0model.load_state_dict(torch.load('./checkpoints/checkpoint%d.pt' % i))test_loss, test_acc = get_test_result(test_iter, test_set)print("The test acc is: %.5f" % test_acc)acc += test_acc / 10
print("The test acc is: %.5f" % acc)

实验结果

输出loss值:

举个例子判断:

x = "it's so bad"
x = x.split()
x = [training_set.word2id[word] for word in x]
x = np.array(x+[0]*(59-len(x))).reshape([1,-1])
x = torch.autograd.Variable(torch.Tensor(x)).long()
out = model(x)


明显0.7111比较大,所以输出为位置0,0表示消极。

TextCNN(MR数据集----情感分类)相关推荐

  1. NLP之基于TextCNN的文本情感分类

    TextCNN 文章目录 TextCNN 1.理论 1.1 基础概念 **最大汇聚(池化)层:** ![请添加图片描述](https://img-blog.csdnimg.cn/10e6e1ed6bf ...

  2. 代码实践:基于LSTM网络的DEAP情感数据集情感分类

    2023/4/5 -4/17 脑机接口学习内容一览: 这一篇文章主要对DEAP数据集转化为python可以处理的格式,并且进一步使用LSTM网络进行分类工作. 一.数据集分析 详情见于官网:DEAPd ...

  3. pytorch实现IMDB数据集情感分类(全连接层的网络、LSTM)

    目录 一.任务描述 二.思路分析 三.准备数据集 3.1 基础dataset的准备 3.2 文本序列化 四.构建模型 4.1 仅有全连接层 4.2 LSTM 4.3 训练和测试 五.完整代码 5.1 ...

  4. 中文文本情感分类(基于LSTM和textCNN)

    中文新闻数据集 负面文本: 正面文本: 数据文本都是用爬虫从网络上爬取的,由人工进行分类,在使用这些数据之前,需要先对文本进行预处理,预处理包括去除标点符号,停用词过滤和分词等,由于篇幅有限,这里就不 ...

  5. MXNet中使用卷积神经网络textCNN对文本进行情感分类

    在图像识别领域,卷积神经网络是非常常见和有用的,我们试图将它应用到文本的情感分类上,如何处理呢?其实思路也是一样的,图片是二维的,文本是一维的,同样的,我们使用一维的卷积核去处理一维的文本(当作一维的 ...

  6. 基于LMDB电影影评数据集进行情感分类

    基于LMDB电影影评数据集进行情感分类 文章目录 基于LMDB电影影评数据集进行情感分类 数据集介绍 数据预处理:词频表的构造 特征工程 代码整理 附录 数据集介绍   标签数据集包含5万条IMDB影 ...

  7. [深度学习-NLP]Imdb数据集情感分析之模型对比(贝叶斯, LSTM, GRU, TextCNN, Transformer, BERT)

    一,详细原理以及代码请看下面博客 1.Imdb数据集情感分析之离散贝叶斯 2.Imdb数据集情感分析之LSTM长短期记忆 3.Imdb数据集情感分析之卷积神经网络-TextCNN 4.Imdb数据集情 ...

  8. 改良的用于情感分类的餐馆评论数据集

    改良的用于情感分类的餐馆评论数据集 原数据说明 字段说明 数据集改良 1.只保留 rating列 和comment列 2.数据集去重去空 3.按照rating大小二分类 4.均衡正负向评论 原数据说明 ...

  9. 中文文本情感分类实战(weibo_senti_100k为数据集)

    中文文本情感分类 数据准备 加载数据集 搭建模型结构 训练脚本的搭建 测试脚本的编写 数据准备 使用jieba分词 data_processing.py import jiebadata_path = ...

最新文章

  1. vue实现Excel文件的上传与下载
  2. 解决安装CMake报错:Could not find CMAKE_ROOT !!! CMake has most likely not been installed correctly.
  3. Starling粒子系统工具
  4. 【PostgreSQL-9.6.3】数据库的启动、登录、退出、关闭
  5. Python3安装turtle提示错误:Command python setup.py egg_info failed with error code 1
  6. 有趣的算法(四)最通俗易懂的KMP算法解析
  7. C++ | Qt编译DLL
  8. [渝粤教育] 西安交通大学 土力学 参考 资料
  9. [vue-ts]ts版本问题合集
  10. IIS7.5 500.19的解决方法 错误代码 0x8007007e
  11. matlab进行ai研究,人工智能AI的主要内容和AI有哪些研究方法及一些MATLAB仿真的详细说明...
  12. 图形学的三种拾取实现与比较
  13. [HDSC] 华大Cortex-M离线烧录器(CM PGM)HCTL-1A使用方法记录
  14. MySQL CAST()函数用法
  15. 使用parted创建大分区时 mkpart Warning: The resulting partition is not properly aligned for best performance.
  16. 终于搞定美团app人气榜提取的数据分类工作
  17. influxdb基础(二)——influxdb基本概念 (database、measurement、fields、tags) + 简单实操 (简单insert、select)
  18. iso镜像添加软件包_Linux系统自定义制作ISO安装镜像
  19. hadoop集群:Mapreduce-----WordCount
  20. Intel NUC11 在ubuntu系统下不能正常使用外接麦克风的问题解决方法

热门文章

  1. 使用Echart绘制3D饼环图、仪表盘、电池图
  2. iOS 3D Touch浅谈
  3. 股市暴跌让基金半年报更耀眼
  4. html分页插件大全,前端jquery分页插件推荐
  5. Win7环境下,强制手动添加HP3050J打印机
  6. [图像检索] paddleclas pp-shitu v1/v2
  7. CSS Zoom属性
  8. NENU - 字符串处理课后作业(问题A~问题H) 解析+参考代码(含有C++中的string函数库)
  9. 一个请求在网络各层之间数据流转过程
  10. LayoutInflater源码分析