提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 目标
  • 一、LSTM介绍
  • 二、LSTM使用实例
    • GRU API
    • 2.双向LSTM
    • 3. LSTM和GRU的使用注意点
    • 4. 使用LSTM完成文本情感分类

目标

1. 知道LSTM和GRU的使用方法及输入输出格式
2. 能够应用LSTM和GRU实现文本情感分类


提示:以下是本篇文章正文内容,下面案例可供参考

一、LSTM介绍

LSTM和GRU都是由torch.nn提供,通过观察文档,可知LSTM的参数:

torch.nn.LSTM(input_size,hidden_size,num_layers,batch_first,dropout,bidirectional)
  1. input_size:输入数据的形状,即embedding_dim
  2. hidden_size:隐藏层的数量,即每一层有多少个LSTM单元
  3. num_layer:即RNN中LSTM单元的层数
  4. batch_first:表示数据中的batch_size是否在第一个维度,默认值为False,输入的数据格式为[seq_len,batch_size,feature],如果为True,则为[batch_size,seq_len, feature]
  5. dropout:dropout的比例,默认值为0,表示不进行dropout。dropout是一种训练过程中让部分参数随机失活的一种方式,能够提高训练速度,同时能够解决过拟合的问题。这里是在LSTM的最后一层,对每个输出进行dropout。
  6. bidirectional:是否使用双向LSTM,默认是False

实例化LSTM对象之后,**不仅需要传入数据,还需要前一次的h_0(前一次的隐藏状态)和c_0(前一次memory)**如果没有传h_0和c_0,网络会自动帮我们生成一个全为0且符合结构的状态。
即:lstm(input,(h_0,c_0))
LSTM的默认输出为output,(h_n,c_n)

  • output:(seq_len,batch_size,num_directions * hidden_size)
  • h_n:(num_layers*num_directions,batch_size,hidden_size)
  • c_n:(num_layers*num_directions,batch_size,hidden_size)

二、LSTM使用实例

假设数据输入为input,形状是[10,20],假设embedding的形状是[100,30]。
代码如下(示例):

import torch.nn as nn
import torchbatch_size = 10     # 每次句子的数量
seq_len = 20        # 句子的长度
embedding_dim = 30  # 用长度为30的向量表示一个词语
vocab_size = 100    # 词典的大小
hidden_size = 18    # 隐层中lstm的个数
num_layer = 2       # 多少个隐藏层# 准备数据
input = torch.randint(low=0,high=100,size=[batch_size,seq_len])embedding = nn.Embedding(num_embeddings=vocab_size,embedding_dim=embedding_dim)
input_embedd = embedding(input)     # [batch_size,seq_len,embedding_dim]10,20,30lstm = nn.LSTM(input_size=embedding_dim,hidden_size=hidden_size,num_layers=num_layer,batch_first=True)
output,(h_n,c_n) = lstm(input_embedd)
print(output.size())
print("*"*100)
print(h_n.size())
print("*"*100)
print(c_n.size())

GRU API

  • 也是torch.nn提供
  • GRU(参数同LSTM)
  • 输出为:output,h_n = gru(input,h_0)
  • 形状同LSTM

2.双向LSTM

如果需要使用双向LSTM,则在实例化LSTM的过程中,需要把LSTM的bidriectional 设为True,同时h_0和c_0使用num_layer*2

  • output的拼接顺序:正向的第一个拼接反向的最后一个,把最后一个维度进行拼接

    双向LSTM中:
    output:按照正反计算的结果顺序把第2个维度进行拼接,正向第一个拼接反向的最后一个输出。
    hidden state:按照得到的结果在第0个维度进行拼接,正向第一个之后接着是反向第一个。[layers*num_direction,batch_size,hidden_size]
batch_size = 10     # 每次句子的数量
seq_len = 20        # 句子的长度
embedding_dim = 30  # 用长度为30的向量表示一个词语
vocab_size = 100    # 词典的大小
hidden_size = 18    # 隐层中lstm的个数
num_layer = 2       # 多少个隐藏层# 准备数据
input = torch.randint(low=0,high=100,size=[batch_size,seq_len])
embedding = nn.Embedding(num_embeddings=vocab_size,embedding_dim=embedding_dim)
input_embedd = embedding(input)     # [batch_size,seq_len,embedding_dim]10,20,30
# 双向
bilstm = nn.LSTM(input_size=embedding_dim,hidden_size=hidden_size,num_layers=num_layer,batch_first=True,bidirectional=True)
h_0 = torch.rand(num_layer*2,batch_size,hidden_size)
c_0 = torch.rand(num_layer*2,batch_size,hidden_size)
output,(h_n,c_n) = bilstm(input_embedd,(h_0,c_0))
print(output)

3. LSTM和GRU的使用注意点

  1. 在第一次调用之前,需要初始化隐藏状态,如果不初始化,默认创建全为0的隐藏状态
  2. 往往会使用LSTM或GRU输出的最后一维的结果,来代表LSTM、GRU对文本处理的结果,其形状为[batch,num_directions*hidden_size]
    - 并不是所有模型都会使用最后一维的结果
    - 如果实例化LSTM的过程中,batch_first=False,则output[-1]output[-1,:,:]可以获得最后一维
    - 如果实例化LSTM的过程中,batch_first=True,则output[:,-1,:]可以获得最后一维
  3. 如果结果是(seq_len,batch_size,num_directions*hidden_size),需要把它转化为(batch_size,seq_len,num_directions*hidden_size)的形状,不能够不是view等变形的方法,需要使用output.permute(1,0,2),即交换0和1轴,实现上述效果
  4. 使用双向LSTM的时候,往往会分别使用每个方向最后一次的output,作为当前数据经过双向LSTM的结果
    - 即:torch.cat([h_1[-2,:,:],h_1[-1,:,:]],dim=-1)
    - 最后表示的size是[batch_size,hidden_size*2]
  5. 上述内容在GRU中同理

4. 使用LSTM完成文本情感分类

在前面,我们使用了word embedding去实现了toy级别的文本情感分类,那么现在我们在这个模型中加上LSTM层,观察分类结果。
为了达到更好的效果,对之前的模型做了如下修改:

  1. max_len = 200
  2. 构建dataset的过程,把数据转化为2分类的问题,pos为1,neg为0,否则25000个样本完成10个类别的划分,数据量是不够的
  3. 在实例化LSTM的时候,使用dropout=0.5,在model.eval()的过程中,dropout自动会为0.
class MyModel(nn.Module):def __init__(self):super().__init__()super(MyModel,self).__init__()self.embedding = nn.Embedding(len(lib.ws),100)  # 参数为[词的数量,词的维度]self.lstm = nn.LSTM(input_size=100,hidden_size=lib.hidden_size,num_layers=lib.num_layers,batch_first=True,bidirectional=lib.bidirectional,dropout=lib.dropout)self.fc = nn.Linear(lib.hidden_size*2,2)          # 参数为[input_feature,output_feature]def forward(self, input):"""模型训练时,不需要使用forward,只要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数:param input:[batch_size,max_len]:return:"""x = self.embedding(input)   # 进行embedding操作,形状为:[batch_size,max_len]# 输出中的x:[batch_size,max_len,2*hidden_size] ,h_n:[2*2,batch_size,hidden_size]x,(h_n,c_n) = self.lstm(x)# 获得两个方向的output,进行一次concatoutput_fw = h_n[-2,:,:] # 正向最后一次的输出output_bw = h_n[-1,:,:] # 反向最后一次的输出output = torch.cat([output_fw,output_bw],dim=-1)   # [batch_size,hidden_size*2]out = self.fc(output)return F.log_softmax(out,dim=-1)# 一般loss为负是在loss采用交叉熵的情况下:可以将softmax 改为 log_softmaxmodel = MyModel().to(lib.device)
optimizer = Adam(model.parameters(),0.001)
if os.path.exists("./model/model.pkl"):model.load_state_dict(torch.load("./model/model.pkl"))optimizer.load_state_dict(torch.load("./model/optimizer.pkl"))def train(epoch):for idx,(input,target) in enumerate(get_dataloader(train=True)):input.to(lib.device)target.to(lib.device)# 梯度归0optimizer.zero_grad()output = model(input)loss = F.nll_loss(output,target)loss.backward()optimizer.step()print(epoch,idx,loss.item())if idx%100 == 0:torch.save(model.state_dict(),"./model/model.pkl")torch.save(optimizer.state_dict(), "./model/model.pkl")if __name__ == '__main__':for i in range(1):train(i)

模型评估:

def eval():loss_list = []acc_list = []data_loader = get_dataloader(train=False)for idx, (input, target) in tqdm(enumerate(data_loader),total=len(data_loader)):input = input.to(lib.device)target = target.to(lib.device)with torch.no_grad():output = model(input)# 计算损失cur_loss = F.nll_loss(output,target)loss_list.append(cur_loss)# 计算准确度pred = output.max(dim=-1)[-1]cur_acc = pred.eq(target).float().mean()acc_list.append(cur_acc)print("total loss acc :",np.mean(loss_list),np.mean(acc_list))

LSTM api的介绍相关推荐

  1. 2021年大数据Flink(三十):Flink ​​​​​​​Table API  SQL 介绍

    目录 ​​​​​​​Table API & SQL 介绍 为什么需要Table API & SQL ​​​​​​​Table API& SQL发展历程 架构升级 查询处理器的选 ...

  2. 线性回归api深度介绍

    线性回归api深度介绍 sklearn.linear_model.LinearRegression(fit_intercept=True) 通过正规方程优化 fit_intercept:是否计算偏置  ...

  3. CompletableFuture API用法介绍(二)

    文章目录 一.纯消费 API 1.thenAccep 2.thenAcceptBoth 3.runAfterBoth 4.thenRun(Runnable action) 二.组合API 1.then ...

  4. spring3 的restful API RequestMapping介绍

    原文链接:http://www.javaarch.net/jiagoushi/694.htm spring3 的restful API RequestMapping介绍 在spring mvc中 @R ...

  5. C++文件操作API函数介绍

    转自 http://www.studentblog.net/m/tonycat/archives/2006/26364.html 文件的基本概念 所谓"文件"是指一组相关数据的有序 ...

  6. 【小程序开发必备】微信小程序常用API全介绍,附示例代码和使用场景

    文章目录 1.网络请求相关API 1.1 wx.request 1.2 wx.uploadFile 1.3 wx.downloadFile 1.4 wx.connectSocket 2.页面跳转相关A ...

  7. 混音器原理及Mixer API函数介绍

    混音器原理及Mixer API函数介绍   为了理解Mixer API是如何工作的,首先我们得弄清楚一个典型声卡的硬件组成.因此非常有必要去建立一个声卡模型,此声卡应拥有多个典型的组件并且这些组件都是 ...

  8. Tyk API网关介绍及安装说明

    Tyk API网关介绍及安装说明 Tyk是一个开源的轻量级API网关程序. 什么是API网关 API网关是一个各类不同API的前置服务器.API网关封装了系统内部架构,对外提供统一服务.此外还可以实现 ...

  9. 强大的 API 监控工具 之 Win32Exts for API Monitor 介绍

    强大的 API 监控工具 之 Win32Exts for API Monitor 介绍          Win32Exts for API_Monitor 是Win32Exts项目组提供的一个强大的 ...

  10. LSTM原理专项介绍

    LSTM提出背景 LSTM缓解了RNN中梯度消失的问题,使其可以处理长短时序列.但是LSTM并没有彻底解决梯度消失的问题.LSTM被各大科技公司应用在文字翻译,语音识别等方向,因为其相比RNN,在各个 ...

最新文章

  1. 设置编码格式为utf8
  2. 经典 | 吴恩达《机器学习落地应用指南》(30页ppt)
  3. egret 开发总结
  4. 如何高效安全的将资源同步到本地数据库
  5. Cython屏蔽GIL锁实践
  6. 微服务(Microservices)和服务网格(Service Mesh)架构概念整理
  7. 超详细!一文告诉你 SparkStreaming 如何整合 Kafka !附代码可实践
  8. 学用软件:laTex软件初体验
  9. 罗佳琪的第三次预备作业——虚拟机的安装及Linux的初步学习
  10. vue3被删除的两个功能
  11. 卡内基梅隆计算机专业,详解卡内基梅隆大学计算机学院
  12. python 读取excel 生成json 读取json
  13. 最近在做支付宝支付,在本地测试一切正常,上传到服务器就遇到报错:
  14. Qt中SQL语句update同时更新多字段及设置字段值为空的方法
  15. vray渲染里服务器信息,VRay分布式渲染详细介绍
  16. The field imgFile exceeds its maximum permitted size of 1048576 bytes.
  17. git commit 提交信息写错,怎么更改?
  18. css3效果隔两秒旋转然后停两秒再继续旋转,无限循环
  19. ​LeetCode刷题实战603:连续空余座位
  20. python操作txt找到最便宜的素菜_Python線性模型學習筆記

热门文章

  1. 温故知新 —— Floyd算法
  2. CSS属性:display详解
  3. blender 用户界面基本构成
  4. ad logon hour
  5. 转I give the orders around here.
  6. [置顶] Android改变图像的饱和度、亮度和对比度
  7. 批量重命名同一文件夹下的文件
  8. 复旦NLP组:大厂模型的鲁棒性进步了吗?
  9. 【EMNLP2020】Cross-Thought句子表示预训练
  10. 谈谈这一两年的成长 | 读研一年半,靠学习收入四十多万 !