LSTM api的介绍
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 目标
- 一、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)
input_size
:输入数据的形状,即embedding_dimhidden_size
:隐藏层的数量,即每一层有多少个LSTM单元num_layer
:即RNN中LSTM单元的层数batch_first
:表示数据中的batch_size是否在第一个维度,默认值为False,输入的数据格式为[seq_len,batch_size,feature],如果为True,则为[batch_size,seq_len, feature]dropout
:dropout的比例,默认值为0,表示不进行dropout。dropout是一种训练过程中让部分参数随机失活的一种方式,能够提高训练速度,同时能够解决过拟合的问题。这里是在LSTM的最后一层,对每个输出进行dropout。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的使用注意点
- 在第一次调用之前,需要初始化隐藏状态,如果不初始化,默认创建全为0的隐藏状态
- 往往会使用LSTM或GRU输出的最后一维的结果,来代表LSTM、GRU对文本处理的结果,其形状为
[batch,num_directions*hidden_size]
。
- 并不是所有模型都会使用最后一维的结果
- 如果实例化LSTM的过程中,batch_first=False
,则output[-1]
或output[-1,:,:]
可以获得最后一维
- 如果实例化LSTM的过程中,batch_first=True
,则output[:,-1,:]
可以获得最后一维 - 如果结果是
(seq_len,batch_size,num_directions*hidden_size)
,需要把它转化为(batch_size,seq_len,num_directions*hidden_size)
的形状,不能够不是view等变形的方法,需要使用output.permute(1,0,2)
,即交换0和1轴,实现上述效果 - 使用双向LSTM的时候,往往会分别使用每个方向最后一次的output,作为当前数据经过双向LSTM的结果
- 即:torch.cat([h_1[-2,:,:],h_1[-1,:,:]],dim=-1)
- 最后表示的size是[batch_size,hidden_size*2]
- 上述内容在GRU中同理
4. 使用LSTM完成文本情感分类
在前面,我们使用了word embedding去实现了toy级别的文本情感分类,那么现在我们在这个模型中加上LSTM层,观察分类结果。
为了达到更好的效果,对之前的模型做了如下修改:
- max_len = 200
- 构建dataset的过程,把数据转化为2分类的问题,pos为1,neg为0,否则25000个样本完成10个类别的划分,数据量是不够的
- 在实例化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的介绍相关推荐
- 2021年大数据Flink(三十):Flink Table API SQL 介绍
目录 Table API & SQL 介绍 为什么需要Table API & SQL Table API& SQL发展历程 架构升级 查询处理器的选 ...
- 线性回归api深度介绍
线性回归api深度介绍 sklearn.linear_model.LinearRegression(fit_intercept=True) 通过正规方程优化 fit_intercept:是否计算偏置 ...
- CompletableFuture API用法介绍(二)
文章目录 一.纯消费 API 1.thenAccep 2.thenAcceptBoth 3.runAfterBoth 4.thenRun(Runnable action) 二.组合API 1.then ...
- spring3 的restful API RequestMapping介绍
原文链接:http://www.javaarch.net/jiagoushi/694.htm spring3 的restful API RequestMapping介绍 在spring mvc中 @R ...
- C++文件操作API函数介绍
转自 http://www.studentblog.net/m/tonycat/archives/2006/26364.html 文件的基本概念 所谓"文件"是指一组相关数据的有序 ...
- 【小程序开发必备】微信小程序常用API全介绍,附示例代码和使用场景
文章目录 1.网络请求相关API 1.1 wx.request 1.2 wx.uploadFile 1.3 wx.downloadFile 1.4 wx.connectSocket 2.页面跳转相关A ...
- 混音器原理及Mixer API函数介绍
混音器原理及Mixer API函数介绍 为了理解Mixer API是如何工作的,首先我们得弄清楚一个典型声卡的硬件组成.因此非常有必要去建立一个声卡模型,此声卡应拥有多个典型的组件并且这些组件都是 ...
- Tyk API网关介绍及安装说明
Tyk API网关介绍及安装说明 Tyk是一个开源的轻量级API网关程序. 什么是API网关 API网关是一个各类不同API的前置服务器.API网关封装了系统内部架构,对外提供统一服务.此外还可以实现 ...
- 强大的 API 监控工具 之 Win32Exts for API Monitor 介绍
强大的 API 监控工具 之 Win32Exts for API Monitor 介绍 Win32Exts for API_Monitor 是Win32Exts项目组提供的一个强大的 ...
- LSTM原理专项介绍
LSTM提出背景 LSTM缓解了RNN中梯度消失的问题,使其可以处理长短时序列.但是LSTM并没有彻底解决梯度消失的问题.LSTM被各大科技公司应用在文字翻译,语音识别等方向,因为其相比RNN,在各个 ...
最新文章
- 设置编码格式为utf8
- 经典 | 吴恩达《机器学习落地应用指南》(30页ppt)
- egret 开发总结
- 如何高效安全的将资源同步到本地数据库
- Cython屏蔽GIL锁实践
- 微服务(Microservices)和服务网格(Service Mesh)架构概念整理
- 超详细!一文告诉你 SparkStreaming 如何整合 Kafka !附代码可实践
- 学用软件:laTex软件初体验
- 罗佳琪的第三次预备作业——虚拟机的安装及Linux的初步学习
- vue3被删除的两个功能
- 卡内基梅隆计算机专业,详解卡内基梅隆大学计算机学院
- python 读取excel 生成json 读取json
- 最近在做支付宝支付,在本地测试一切正常,上传到服务器就遇到报错:
- Qt中SQL语句update同时更新多字段及设置字段值为空的方法
- vray渲染里服务器信息,VRay分布式渲染详细介绍
- The field imgFile exceeds its maximum permitted size of 1048576 bytes.
- git commit 提交信息写错,怎么更改?
- css3效果隔两秒旋转然后停两秒再继续旋转,无限循环
- ​LeetCode刷题实战603:连续空余座位
- python操作txt找到最便宜的素菜_Python線性模型學習筆記