pytorch LSTM情感分类全部代码
先运行main.py进行文本序列化,再train.py模型训练
dataset.py
from torch.utils.data import DataLoader,Dataset
import torch
import os
from utils import tokenlize
import config class ImdbDataset(Dataset):
def __init__(self,train=True):
super(ImdbDataset,self).__init__()
data_path = r"H:\073-nlp自然语言处理-v5.bt38[周大伟]\073-nlp自然语言处理-v5.bt38[周大伟]\第四天\代码\data\aclImdb_v1\aclImdb"
data_path += r"\train" if train else r"\test"
self.total_path = []
for temp_path in [r"\pos",r"\neg"]:
cur_path = data_path + temp_path
self.total_path += [os.path.join(cur_path,i) for i in os.listdir(cur_path) if i.endswith(".txt")] def __getitem__(self, idx):
file = self.total_path[idx]
review = open(file,encoding="utf-8").read()
review = tokenlize(review)
label = int(file.split("_")[-1].split(".")[0])
label = 0 if label < 5 else 1
return review,label def __len__(self):
return len(self.total_path) def collate_fn(batch):
'''
对batch数据进行处理
:param batch:
:return:
'''
reviews,labels = zip(*batch)
reviews = torch.LongTensor([config.ws.transform(i,max_len=config.max_len) for i in reviews])
labels = torch.LongTensor(labels)
return reviews,labels def get_dataloader(train):
imdbdataset = ImdbDataset(train=True)
batch_size = config.train_batch_size if train else config.test_batch_size
return DataLoader(imdbdataset,batch_size=batch_size,shuffle=True,collate_fn=collate_fn) if __name__ == '__main__':
# dataset = ImdbDataset(train=True)
# print(dataset[1])
for idx,(review,label) in enumerate(get_dataloader(train=True)):
print(review)
print(label)
break
utils.py
"""
实现额外的方法
"""
import re def tokenlize(sentence):
"""
进行文本分词
:param sentence: str
:return: [str,str,str]
""" fileters = ['!', '"', '#', '$', '%', '&', '\(', '\)', '\*', '\+', ',', '-', '\.', '/', ':', ';', '<', '=', '>',
'\?', '@', '\[', '\\', '\]', '^', '_', '`', '\{', '\|', '\}', '~', '\t', '\n', '\x97', '\x96', '”', '“', ]
sentence = sentence.lower() #把大写转化为小写
sentence = re.sub("<br />"," ",sentence)
# sentence = re.sub("I'm","I am",sentence)
# sentence = re.sub("isn't","is not",sentence)
sentence = re.sub("|".join(fileters)," ",sentence)
result = [i for i in sentence.split(" ") if len(i)>0] return result
word_sequence.py
'''
文本序列化
''' class WordSequence():
UNK_TAG = "<UNK>"
PAD_TAG = "<PAD>"
UNK = 1
PAD = 0 def __init__(self):
self.dict = {
self.UNK_TAG:self.UNK,
self.PAD_TAG:self.PAD
}
self.count = {} def fit(self,sentence):
'''
统计词频
:param sentence:
:return:
'''
for word in sentence:
self.count[word] = self.count.get(word,0)+1 def build_vocab(self,min_count=0,max_count = None,max_features = None):
"""
根据条件构建 词典
:param min_count:最小词频
:param max_count: 最大词频
:param max_features: 最大词语数
:return:
"""
if min_count is not None:
self.count = {word:count for word,count in self.count.items() if count >min_count}
if max_count is not None:
self.count = {word:count for word,count in self.count.items() if count<max_count}
if max_features is not None:
#排序
self.count = dict(sorted(self.count.items(),lambda x:x[-1],reverse=True)[:max_features]) for word in self.count:
self.dict[word] = len(self.dict) #每次word对应一个数字 #把dict进行翻转
self.inverse_dict = dict(zip(self.dict.values(),self.dict.keys())) def transform(self,sentence,max_len =None):
'''
把句子转化为数字序列
:param sentence:
:return:
'''
if len(sentence) > max_len:
sentence = sentence[:max_len]
else:
sentence = sentence + [self.PAD_TAG]*(max_len-len(sentence))
return [self.dict.get(i,1) for i in sentence] def inverse_transform(self,incides):
"""
把数字序列转化为字符
:param incides:
:return:
"""
return [self.inverse_dict.get(i,"<UNK>") for i in incides] def __len__(self):
return len(self.dict) if __name__ == '__main__':
sentences = [["今天","天气","很","好"],
["今天","去","吃","什么"]] ws = WordSequence()
for sentence in sentences:
ws.fit(sentence) ws.build_vocab(min_count=0)
print(ws.dict)
ret = ws.transform(["好","热","呀","呀","呀","呀","呀","呀","呀"],max_len=5)
print(ret)
ret = ws.inverse_transform(ret)
print(ret)
main.py
from word_sequence import WordSequence
from dataset import get_dataloader
import pickle
from tqdm import tqdm if __name__ == '__main__':
ws = WordSequence()
train_data = get_dataloader(True)
test_data = get_dataloader(False)
for reviews,labels in tqdm(train_data,total=len(train_data)):
for review in reviews:
ws.fit(review)
for reviews,labels in tqdm(test_data,total=len(test_data)):
for review in reviews:
ws.fit(review)
print("正在建立...")
ws.build_vocab()
print(len(ws))
pickle.dump(ws,open("./models/ws.pkl","wb"))
model.py
"""
构建模型
"""
import torch.nn as nn
import config
import torch.nn.functional as F class ImdbModel(nn.Module):
def __init__(self):
super(ImdbModel,self).__init__()
self.embedding = nn.Embedding(num_embeddings=len(config.ws),embedding_dim=300,padding_idx=config.ws.PAD)
self.fc = nn.Linear(config.max_len*300,2) def forward(self,input):
'''
:param input:
:return:
'''
input_embeded = self.embedding(input) input_embeded_viewed = input_embeded.view(input_embeded.size(0),-1) out = self.fc(input_embeded_viewed)
return F.log_softmax(out,dim=-1)
LSTMmodel.py
"""
构建模型
"""
import torch.nn as nn
import torch
import config
import torch.nn.functional as F class ImdbModel(nn.Module):
def __init__(self):
super(ImdbModel,self).__init__()
self.embedding = nn.Embedding(num_embeddings=len(config.ws),embedding_dim=300,padding_idx=config.ws.PAD)
self.lstm = nn.LSTM(input_size=200,hidden_size=64,num_layers=2,batch_first=True,bidirectional=True,dropout=0.5)
self.fc1 = nn.Linear(64*2,64)
self.fc2 = nn.Linear(64,2) def forward(self,input):
'''
:param input:
:return:
'''
input_embeded = self.embedding(input) #[batch_size,seq_len,200] output,(h_n,c_n) = self.lstm(input_embeded)
out = torch.cat(h_n[-1,:,:],h_n[-2,:,:],dim=-1) #拼接正向最后一个输出和反向最后一个输出 #进行全连接
out_fc1 = self.fc1(out)
#进行relu
out_fc1_relu = F.relu(out_fc1)
#全连接
out = self.fc2(out_fc1_relu)
return F.log_softmax(out,dim=-1)
train.py
'''
进行模型的训练
'''
import torch import config
from model import ImdbModel
from dataset import get_dataloader
from torch.optim import Adam
from tqdm import tqdm
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt
from eval import eval model = ImdbModel().to(config.device)
optimizer = Adam(model.parameters(),lr=0.001)
loss_list = [] def train(epoch):
train_dataloader = get_dataloader(train=True)
bar = tqdm(train_dataloader,total=len(train_dataloader)) for idx,(input,target) in enumerate(bar):
optimizer.zero_grad()
input = input.to(config.device)
target = target.to(config.device)
output = model(input)
loss = F.nll_loss(output,target)
loss.backward()
loss_list.append(loss.item())
optimizer.step()
bar.set_description("epoch:{} idx:{} loss:{:.6f}".format(epoch,idx,np.mean(loss_list))) if idx%10 == 0:
torch.save(model.state_dict(),"./models/model.pkl")
torch.save(optimizer.state_dict(),"./models/optimizer.pkl") if __name__ == '__main__':
for i in range(5):
train(i)
eval()
plt.figure(figsize=(20,8))
plt.plot(range(len(loss_list)),loss_list)
eval.py
'''
进行模型的训练
'''
import torch import config
from model import ImdbModel
from dataset import get_dataloader
from torch.optim import Adam
from tqdm import tqdm
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt def eval():
model = ImdbModel().to(config.device)
model.load_state_dict(torch.load("./models/model.pkl"))
model.eval()
loss_list = []
acc_list = []
test_dataloader = get_dataloader(train=False)
with torch.no_grad():
for input,target in test_dataloader:
input = input.to(config.device)
target = target.to(config.device)
output = model(input)
loss = F.nll_loss(output,target)
loss_list.append(loss.item())
#准确率
pred= output.max(dim = -1)[-1]
acc_list.append(pred.eq(target).cpu().float().mean())
print("loss:{:.6f},acc:{}".format(np.mean(loss_list),np.mean(acc_list))) if __name__ == '__main__':
eval()
pytorch LSTM情感分类全部代码的更多相关文章
- pytorch 文本情感分类和命名实体识别NER中LSTM输出的区别
文本情感分类: 文本情感分类采用LSTM的最后一层输出 比如双层的LSTM,使用正向的最后一层和反向的最后一层进行拼接 def forward(self,input): ''' :param inpu ...
- NLP(十九) 双向LSTM情感分类模型
使用IMDB情绪数据来比较CNN和RNN两种方法,预处理与上节相同 from __future__ import print_function import numpy as np import pa ...
- PaddlePaddle︱开发文档中学习情感分类(CNN、LSTM、双向LSTM)、语义角色标注
PaddlePaddle出教程啦,教程一部分写的很详细,值得学习. 一期涉及新手入门.识别数字.图像分类.词向量.情感分析.语义角色标注.机器翻译.个性化推荐. 二期会有更多的图像内容. 随便,帮国产 ...
- 使用BERT进行情感分类预测及代码实例
文章目录 0. BERT介绍 1. BERT配置 1.1. clone BERT 代码 1.2. 数据处理 1.2.1预训练模型 1.2.2数据集 训练集 测试集 开发集 2. 修改代码 2.1 加入 ...
- 基于Bert的文本情感分类
详细代码已上传到github: click me Abstract: Sentiment classification is the process of analyzing and reaso ...
- kaggle——Bag of Words Meets Bags of Popcorn(IMDB电影评论情感分类实践)
kaggle链接:https://www.kaggle.com/c/word2vec-nlp-tutorial/overview 简介:给出 50,000 IMDB movie reviews,进行0 ...
- 文本情感分类:分词 OR 不分词(3)
为什么要用深度学习模型?除了它更高精度等原因之外,还有一个重要原因,那就是它是目前唯一的能够实现“端到端”的模型.所谓“端到端”,就是能够直接将原始数据和标签输入,然后让模型自己完成一切过程——包括特 ...
- 使用bert进行情感分类
2018年google推出了bert模型,这个模型的性能要远超于以前所使用的模型,总的来说就是很牛.但是训练bert模型是异常昂贵的,对于一般人来说并不需要自己单独训练bert,只需要加载预训练模型, ...
- NLP文本情感分类传统模型+深度学习(demo)
文本情感分类: 文本情感分类(一):传统模型 摘自:http://spaces.ac.cn/index.php/archives/3360/ 测试句子:工信处女干事每月经过下属科室都要亲口交代24口交 ...
随机推荐
- 多伦多大学&NVIDIA最新成果:图像标注速度提升10倍!
图像标注速度提升10倍! 这是多伦多大学与英伟达联合公布的一项最新研究:Curve-GCN的应用结果. Curve-GCN是一种高效交互式图像标注方法,其性能优于Polygon-RNN++.在自动模式 ...
- BUAA_2020_OO_第一单元总结
三次作业,三次成长 第一次作业--幂函数求导总结 作业思路和心得 第一次作业的要求只有x的指数这样的幂函数加减组成表达式,对表达式进行求导,而且没有格式错误的检查,所以难度感觉还不是很高.不过由于我寒 ...
- 线段树(区间合并)HDU - 1540
题意:输入n,m,给定n个相互连通的村庄,有m个操作,D x,表示破坏x村庄使其与相邻的两个村庄不相通,R 表示修复上一个被破坏的村庄,与相邻的两个村庄联通.Q x表示与x相连的村庄有多少个. 思路: ...
- 安装arcgis server时提示“应用程序无法启动,因为应用程序......或使用命令行sxstrace.exe”
说一下这个原因:有几个条件不满足会产生这样的问题: 1.软件的发布是不需要安装的,直接在vs里编译好release版就发布了,而发布的时候如果缺少一些库文件,就会产生这样的问题. 一版都是目 ...
- 常用的python标准库
os : 操作系统接口 sys: 命令行操作 re : 正则模块 math : 数学模块 time,timedate: 日期模块 random: 随机数模块 threading: 线程 ...
- M_map(五)
一.圆形区域的画图 1. clear all LATLIMS=[14 22]; LONLIMS=[108 118];%南海边界范围 m_proj('miller','lon',LONLIMS,'lat ...
- turtle实例
1.彩虹 (1) from turtle import * def HSB2RGB(hues): hues = hues * 3.59 #100转成359范围 rgb=[0.0,0.0,0.0] i ...
- 《Java基础复习》-控制执行流程
最近任务太多了,肝哭我了,boom 参考书目:Thinking in Java <Java基础复习>-控制执行流程 Java使用了C的所有流程控制语句 涉及关键字:if-else.whil ...
- rem布局和使用js rem动态改变字体大小,自适应
解决rem文字动态改变字体大小: <script> console.log(window.devicePixelRatio); var iScale = 1; iScale = iScal ...
- 泛型代码中的 default 关键字
在泛型类和泛型方法中会出现的一个问题是,如何把缺省值赋给参数化类型,此时无法预先知道以下两点: l T将是值类型还是引用类型 l 如果T是值类型,那么T将是数值还是结构 对 ...