前语

大家好,我是阿光。

本专栏整理了《PyTorch深度学习项目实战100例》,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完好的代码+数据集。

正在更新中~ ✨

我的项目环境:

  • 渠道:Windows10
  • 语言环境:python3.7
  • 编译器:PyCharm
  • PyTorch版别:1.8.1

项目专栏:【PyTorch深度学习项目实战100例】


一、运用LSTM进行流言检测

本项目运用根据循环神经网络(LSTM)的流言检测模型,将文本中的流言事情进行接连向量化,经过循环神经网络的学习练习来挖掘表明文本深层的特征,避免了特征构建的问题,并能发现那些不容易被人发现的特征,从而发生更好的作用。

【PyTorch深度学习项目实战100例】—— 基于pytorch使用LSTM进行谣言检测 | 第8例

在这里刺进图片描述

二、数据集介绍

本项目中运用的数据是微博头条新闻数据,该数据集的下载网址为:下载链接 ,该数据集一共有3387条新闻数据,新闻的类型分为两类:“流言新闻”和“实在新闻”,该数据集的前几行如下: 由于新闻数据敏感,所以进行打马赛克,

【PyTorch深度学习项目实战100例】—— 基于pytorch使用LSTM进行谣言检测 | 第8例

在这里刺进图片描述

三、项目完成思路

本项目运用的是LSTM,如果运用一般MLP网络仍然能够完成二分类,可是关于文本信息,他不同词之间是存在语义关系的,并不是独立的,每个词会受语境及上下文所影响,如果运用传统模型是捕捉不到这层关系。 所以考虑运用循环神经网络,能够将不同时刻步的数据向下进行传递,将上文语境信息向后传入进行剖析。

【PyTorch深度学习项目实战100例】—— 基于pytorch使用LSTM进行谣言检测 | 第8例

四、加载文本数据

由于数据会集是每一个样本为一句话,这样是不能够进行练习的,所以需求将其转化为数值信息。

  1. 首要需求取得词汇表,便是练习样本中一切呈现的字
  2. 然后将其转化为字典,键为字,值为对应的编号,用于进行映射
  3. 将每一句话进行映射构成对应的数值编号
  4. 如果每一行的字数不行input_shape,那么就运用0进行填补,坚持送入网络模型中的数据的维度是共同的
#加载文本数据
defload_data(file_path,input_shape=20):
df=pd.read_csv(file_path,sep='\t')
#标签及词汇表
labels,vocabulary=list(df['label'].unique()),list(df['text'].unique())
#构造字符等级的特征
string=''
forwordinvocabulary:
string+=word

#一切的词汇表
vocabulary=set(string)
#word2idx将字映射为索引
word_dictionary={word:i+1fori,wordinenumerate(vocabulary)}
withopen('word_dict.pk','wb')asf:
pickle.dump(word_dictionary,f)
#idx2word将索引映射为字
inverse_word_dictionary={i+1:wordfori,wordinenumerate(vocabulary)}
#label2idx将正反面映射为0和1
label_dictionary={label:ifori,labelinenumerate(labels)}
withopen('label_dict.pk','wb')asf:
pickle.dump(label_dictionary,f)
#idx2label将0和1映射为正反面
output_dictionary={i:labelsfori,labelsinenumerate(labels)}

#练习数据中一切词的个数
vocab_size=len(word_dictionary.keys())#词汇表巨细
#标签类别,分别为正、反面
label_size=len(label_dictionary.keys())#标签类别数量
#序列填充,按input_shape填充,长度缺乏的按0补充
#将一句话映射成对应的索引[0,24,63...]
x=[[word_dictionary[word]forwordinsent]forsentindf['text']]
#如果长度不行input_shape,运用0进行填充
x=pad_sequences(maxlen=input_shape,sequences=x,padding='post',value=0)
#构成标签0和1
y=[[label_dictionary[sent]]forsentindf['label']]
#y=[np_utils.to_categorical(label,num_classes=label_size)forlabeliny]
y=np.array(y)
returnx,y,output_dictionary,vocab_size,label_size,inverse_word_dictionary

五、界说网络结构

项目中运用的模型是LSTM,在模型中咱们界说了三个组件,分别是embedding层lstm层全衔接层

  • Embedding层:将每个词生成对应的嵌入向量,便是利用一个接连型向量来表明每个词
  • Lstm层:提取句子中的语义信息
  • Linear层:将成果映射成2巨细用于二分类,即流言和非流言的概率

留意:在LSTM网络中回来的值为最终一个时刻片的输出,而不是将整个output悉数输出,由于咱们是需求捕捉整个句子的语义信息,并不是取得特定时刻片的数据。

#界说网络结构
classLSTM(nn.Module):
def__init__(self,vocab_size,hidden_dim,num_layers,embedding_dim,output_dim):
super(LSTM,self).__init__()
self.hidden_dim=hidden_dim#隐层巨细
self.num_layers=num_layers#LSTM层数
#嵌入层,会对一切词构成一个接连型嵌入向量,该向量的维度为embedding_dim
#然后利用这个向量来表明该字,而不是用索引继续表明
self.embeddings=nn.Embedding(vocab_size+1,embedding_dim)
#界说LSTM层,第一个参数为每个时刻步的特征巨细,这里便是每个字的维度
#第二个参数为隐层巨细
#第三个参数为lstm的层数
self.lstm=nn.LSTM(embedding_dim,hidden_dim,num_layers)
#利用全衔接层将其映射为2维,即正反面的概率
self.fc=nn.Linear(hidden_dim,output_dim)
defforward(self,x):
#1.首要构成嵌入向量
embeds=self.embeddings(x)
#2.将嵌入向量导入到lstm层
output,(h_n,c_n)=self.lstm(embeds)
timestep,batch_size,hidden_dim=output.shape
output=output.reshape(-1,hidden_dim)
#3.将其导入全衔接层
output=self.fc(output)#形状为batch_size*timestep,2
output=output.reshape(timestep,batch_size,-1)
returnoutput[-1]#回来最终一个时刻片的输出,维度为batch_size,2

六、模型练习

#6.模型练习
model=LSTM(vocab_size=len(word_dictionary),hidden_dim=hidden_dim,num_layers=num_layers,
embedding_dim=embedding_dim,output_dim=output_dim)
Configimizer=optim.Adam(model.parameters(),lr=lr)#优化器
criterion=nn.CrossEntropyLoss()#多分类丢掉函数
model.to(device)
loss_meter=meter.AverageValueMeter()
best_acc=0#保存最好准确率
best_model=None#保存对应最好准确率的模型参数
forepochinrange(epochs):
model.train()#开启练习形式
epoch_acc=0#每个epoch的准确率
epoch_acc_count=0#每个epoch练习的样本数
train_count=0#用于核算总的样本数,便利求准确率
loss_meter.reset()

train_bar=tqdm(train_loader)#构成进度条
fordataintrain_bar:
x_train,y_train=data#解包迭代器中的X和Y
x_input=x_train.long().transpose(1,0).contiguous()
x_input=x_input.to(device)
Configimizer.zero_grad()

#构成预测成果
output_=model(x_input)

#核算丢掉
loss=criterion(output_,y_train.long().view(-1))
loss.backward()
Configimizer.step()

loss_meter.add(loss.item())

#核算每个epoch正确的个数
epoch_acc_count+=(output_.argmax(axis=1)==y_train.view(-1)).sum()
train_count+=len(x_train)

#每个epoch对应的准确率
epoch_acc=epoch_acc_count/train_count

#打印信息
print("【EPOCH:】%s"%str(epoch+1))
print("练习丢掉为%s"%(str(loss_meter.mean)))
print("练习精度为%s"%(str(epoch_acc.item()*100)[:5])+'%')
#保存模型及相关信息
ifepoch_acc>best_acc:
best_acc=epoch_acc
best_model=model.state_dict()

#在练习完毕保存最优的模型参数
ifepoch==epochs-1:
#保存模型
torch.save(best_model,'./best_model.pkl')

七、句子测验

完成规定好input_shape,如果不行运用0进行填补,便利送入网络傍边。 读取模型以及相应的词序号映射信息,然后将咱们待测验的话转成相应的tensor,送入网络中,然后的tensor为2维,即对应正面和反面的概率,然后运用argmax函数取得最大值对应的索引。

try:
input_shape=180#序列长度,便是时刻步巨细,也便是这里的每句话中的词的个数
#sent="电视刚安装好,说实话,画质不怎么样,很差!"
#用于测验的话
sent="清晨的长春,丢掉的孩子找到了,被偷走的车也找到,仅仅偷车贼没找到,看来,向雷锋同志学习50周年的今天,还是一个有作用的日子啊。"
#将对应的字转化为相应的序号
x=[[word2idx[word]forwordinsent]]
#如果长度不行180,运用0进行填充
x=pad_sequences(maxlen=input_shape,sequences=x,padding='post',value=0)
x=torch.from_numpy(x)
#加载模型
model_path='./best_model.pkl'
model=LSTM(vocab_size=len(word_dictionary),hidden_dim=hidden_dim,num_layers=num_layers,
embedding_dim=embedding_dim,output_dim=output_dim)
model.load_state_dict(torch.load(model_path,'cpu'))
#模型预测,留意输入的数据第一个input_shape,便是180
y_pred=model(x.long().transpose(1,0))
print('输入句子:%s'%sent)
print('流言检测成果:%s'%label_dict[y_pred.argmax().item()])
exceptKeyErroraserr:
print("您输入的句子有汉字不在词汇表中,请从头输入!")
print("不在词汇表中的单词为:%s."%err)

完好源码

【PyTorch深度学习项目实战100例】—— 根据pytorch运用LSTM进行流言检测 | 第8例