20211227

lstm和gru的区别

Pytorch实现LSTM案例学习(1)_ch206265的博客-CSDN博客_pytorch搭建lstm

lstm案例

class torch.nn.LSTM(*args, **kwargs)

参数列表

  • input_size:x的特征维度
  • hidden_size:隐藏层的特征维度
  • num_layers:lstm隐层的层数,默认为1
  • bias:False则bih=0和bhh=0. 默认为True
  • batch_first:True则输入输出的数据格式为 (batch, seq, feature)
  • dropout:除最后一层,每一层的输出都进行dropout,默认为: 0
  • bidirectional:True则为双向lstm默认为False
  • 输入:input, (h0, c0)
  • 输出:output, (hn,cn)

输入数据格式: 
input(seq_len, batch, input_size) 
h0(num_layers * num_directions, batch, hidden_size) 
c0(num_layers * num_directions, batch, hidden_size)

输出数据格式: 
output(seq_len, batch, hidden_size * num_directions) 
hn(num_layers * num_directions, batch, hidden_size) 
cn(num_layers * num_directions, batch, hidden_size)

Pytorch里的LSTM单元接受的输入都必须是3维的张量(Tensors).每一维代表的意思不能弄错。

第一维体现的是序列(sequence)结构,也就是序列的个数,用文章来说,就是每个句子的长度,因为是喂给网络模型,一般都设定为确定的长度,也就是我们喂给LSTM神经元的每个句子的长度,当然,如果是其他的带有带有序列形式的数据,则表示一个明确分割单位长度,

例如是如果是股票数据内,这表示特定时间单位内,有多少条数据。这个参数也就是明确这个层中有多少个确定的单元来处理输入的数据。

第二维度体现的是batch_size,也就是一次性喂给网络多少条句子,或者股票数据中的,一次性喂给模型多少是个时间单位的数据,具体到每个时刻,也就是一次性喂给特定时刻处理的单元的单词数或者该时刻应该喂给的股票数据的条数

第三位体现的是输入的元素(elements of input),也就是,每个具体的单词用多少维向量来表示,或者股票数据中 每一个具体的时刻的采集多少具体的值,比如最低价,最高价,均价,5日均价,10均价,等等

H0-Hn是什么意思呢?就是每个时刻中间神经元应该保存的这一时刻的根据输入和上一课的时候的中间状态值应该产生的本时刻的状态值,

这个数据单元是起的作用就是记录这一时刻之前考虑到所有之前输入的状态值,形状应该是和特定时刻的输出一致

c0-cn就是开关,决定每个神经元的隐藏状态值是否会影响的下一时刻的神经元的处理,形状应该和h0-hn一致。

当然如果是双向,和多隐藏层还应该考虑方向和隐藏层的层数。

注:上式中的 q后面跟一个单词,表示该单词的一定维度的向量表示,该维度即是LSTM接受的张量中的第三个维度。

记住这里存在一个尺寸为1的第二维度。此外,如果你希望一次在网络中走完整个序列,你可以将第一个维度的尺寸也设为1。

下面我简单看一下例子:

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optimtorch.manual_seed(1)lstm = nn.LSTM(3, 3)  # 输入单词用一个维度为3的向量表示, 隐藏层的一个维度3,仅有一层的神经元,
#记住就是神经元,这个时候神经层的详细结构还没确定,仅仅是说这个网络可以接受[seq_len,batch_size,3]的数据输入
print(lstm.all_weights)inputs = [torch.randn(1, 3) for _ in range(5)]# 构造一个由5个单单词组成的句子 构造出来的形状是 [5,1,3]也就是明确告诉网络结构我一个句子由5个单词组成,
#每个单词由一个1X3的向量组成,就是这个样子[1,2,3]
#同时确定了网络结构,每个批次只输入一个句子,其中第二维的batch_size很容易迷惑人
#对整个这层来说,是一个批次输入多少个句子,具体但每个神经元,就是一次性喂给神经元多少个单词。
print('Inputs:',inputs)# 初始化隐藏状态
hidden = (torch.randn(1, 1, 3),torch.randn(1, 1, 3))
print('Hidden:',hidden)
for i in inputs:# 将序列的元素逐个输入到LSTM,这里的View是把输入放到第三维,看起来有点古怪,
#回头看看上面的关于LSTM输入的描述,这是固定的格式,以后无论你什么形式的数据,
#都必须放到这个维度。就是在原Tensor的基础之上增加一个序列维和MiniBatch维,
#这里可能还会有迷惑,前面的1是什么意思啊,就是一次把这个输入处理完,
#在输入的过程中不会输出中间结果,这里注意输入的数据的形状一定要和LSTM定义的输入形状一致。# 经过每步操作,hidden 的值包含了隐藏状态的信息out, hidden = lstm(i.view(1, 1, -1), hidden)
print('out1:',out)
print('hidden2:',hidden)
# 另外, 我们还可以一次对整个序列进行训练. LSTM 返回的第一个值表示所有时刻的隐状态值,
# 第二个值表示最近的隐状态值 (因此下面的 "out"的最后一个值和 "hidden" 的值是一样的).
# 之所以这样设计, 是为了通过 "out" 的值来获取所有的隐状态值, 而用 "hidden" 的值来
# 进行序列的反向传播运算, 具体方式就是将它作为参数传入后面的 LSTM 网络.# 增加额外的第二个维度
inputs = torch.cat(inputs).view(len(inputs), 1, -1)
hidden = (torch.randn(1, 1, 3), torch.randn(1, 1, 3))  # clean out hidden state
out, hidden = lstm(inputs, hidden)
print('out2',out)
print('hidden3',hidden)
运行输出:
out2 tensor([[[-0.0187,  0.1713, -0.2944]],[[-0.3521,  0.1026, -0.2971]],[[-0.3191,  0.0781, -0.1957]],[[-0.1634,  0.0941, -0.1637]],[[-0.3368,  0.0959, -0.0538]]])
hidden3 (tensor([[[-0.3368,  0.0959, -0.0538]]]), tensor([[[-0.9825,  0.4715, -0.0633]]]))

接下来我们要做一件事,

就是训练网络帮我我们标注词性,当然实际的自然语言处理我们有很多成功的算法,但是应对新词总会有点麻烦,我们想啊,既然神经网络可以帮我们做了很多神奇的事,那么我们可不可以训练一个网路模型来帮我我们自动的标注词性呢,显然这个思路靠谱,使用神经网络的套路:

  1. 准备训练数据,这一步最是头大的,最好的办法就是找各大机构提供的标准的标注库,实在找不到,自己处理,国内外很多的分词标准库和工具可以用,jieba分词标注是一个不错的选择,使用起来也简单。
  2. 读取数据文件
  3. 分词
  4. 把词语和标注分别放在两个数组里面
  5. 构建词汇表、构建标注表
  6. 把分词结果转换成对应词汇表和标签表中的序号。
  7. 构建网络模型,这里使用Word2Vec预处理一下输入文本
  8. 训练网络
  9. 分析结果

下面按照这个套路上源码:

import jieba.posseg
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# import sysimport gensim
torch.manual_seed(2)
# sys.stdout = open('1.log', 'a')
sent='明天是荣耀运营十周年纪念日。' \'荣耀从两周年纪念日开始,' \'在每年的纪念日这天凌晨零点会开放一个新区。' \'第十版账号卡的销售从三个月前就已经开始。' \'在老区玩的不顺心的老玩家、准备进入荣耀的新手,都已经准备好了新区账号对这个日子翘首以盼。' \'陈果坐到了叶修旁边的机器,随手登录了她的逐烟霞。' \'其他九大区的玩家人气并没有因为第十区的新开而降低多少,' \'越老的区越是如此,实在是因为荣耀的一个账号想经营起来并不容易。' \'陈果的逐烟霞用了五年时间才在普通玩家中算是翘楚,哪舍得轻易抛弃。' \'更何况到最后大家都会冲着十大区的共同地图神之领域去。'
words=jieba.posseg.cut(sent,HMM=True) #分词
processword=[]
tagword=[]
for w in words:processword.append(w.word)tagword.append(w.flag)
#词语和对应的词性做一一对应
texts=[(processword,tagword)]#使用gensim构建本例的词汇表
id2word=gensim.corpora.Dictionary([texts[0][0]])
#每个词分配一个独特的ID
word2id=id2word.token2id#使用gensim构建本例的词性表
id2tag=gensim.corpora.Dictionary([texts[0][1]])
#为每个词性分配ID
tag2id=id2tag.token2iddef sen2id(inputs):return [word2id[word] for word in inputs]def tags2id(inputs):return [tag2id[word] for word in inputs]
#根据词汇表把文本输入转换成对应的词汇表的序号张量
def formart_input(inputs):return torch.tensor(sen2id(inputs),dtype=torch.long)#根据词性表把文本标注输入转换成对应的词汇标注的张量
def formart_tag(inputs):return torch.tensor(tags2id(inputs),dtype=torch.long)
#定义网络结构
class LSTMTagger(torch.nn.Module):def __init__(self,embedding_dim,hidden_dim,voacb_size,target_size):super(LSTMTagger,self).__init__()self.embedding_dim=embedding_dimself.hidden_dim=hidden_dimself.voacb_size=voacb_sizeself.target_size=target_size# 使用Word2Vec预处理一下输入文本self.embedding=nn.Embedding(self.voacb_size,self.embedding_dim)#  LSTM 以 word_embeddings 作为输入, 输出维度为 hidden_dim 的隐状态值self.lstm=nn.LSTM(self.embedding_dim,self.hidden_dim)## 线性层将隐状态空间映射到标注空间self.out2tag=nn.Linear(self.hidden_dim,self.target_size)self.hidden = self.init_hidden()def init_hidden(self):# 开始时刻, 没有隐状态# 关于维度设置的详情,请参考 Pytorch 文档# 各个维度的含义是 (Seguence, minibatch_size, hidden_dim)return (torch.zeros(1, 1, self.hidden_dim),torch.zeros(1, 1, self.hidden_dim))def forward(self,inputs):# 预处理文本转成稠密向量embeds=self.embedding((inputs))#根据文本的稠密向量训练网络out,self.hidden=self.lstm(embeds.view(len(inputs),1,-1),self.hidden)#做出预测tag_space=self.out2tag(out.view(len(inputs),-1))tags=F.log_softmax(tag_space,dim=1)return tagsmodel=LSTMTagger(10,10,len(word2id),len(tag2id))
loss_function=nn.NLLLoss()
optimizer=optim.SGD(model.parameters(),lr=0.1)
#看看随机初始化网络的分析结果
with torch.no_grad():input_s=formart_input(texts[0][0])print(input_s)print(processword)tag_s=model(input_s)for i in range(tag_s.shape[0]):print(tag_s[i])# print(tag_s)
for epoch in range(300):# 再说明下, 实际情况下你不会训练300个周期, 此例中我们只是构造了一些假数据for p ,t in texts:# Step 1. 请记住 Pytorch 会累加梯度# 每次训练前需要清空梯度值model.zero_grad()# 此外还需要清空 LSTM 的隐状态# 将其从上个实例的历史中分离出来# 重新初始化隐藏层数据,避免受之前运行代码的干扰,如果不重新初始化,会有报错。model.hidden = model.init_hidden()# Step 2. 准备网络输入, 将其变为词索引的Tensor 类型数据sentence_in=formart_input(p)tags_in=formart_tag(t)# Step 3. 前向传播tag_s=model(sentence_in)# Step 4. 计算损失和梯度值, 通过调用 optimizer.step() 来更新梯度loss=loss_function(tag_s,tags_in)loss.backward()print('Loss:',loss.item())optimizer.step()#看看训练后的结果
with torch.no_grad():input_s=formart_input(texts[0][0])tag_s=model(input_s)for i in range(tag_s.shape[0]):print(tag_s[i])

Pytorch的LSTM的理解相关推荐

  1. pytorch实现LSTM学习总结

    pytorch实现LSTM学习总结 第一次写csdn,可以通过这样的方式记录一下自己学习过程中遇到的问题. 学习目标: 学习语言模型,以及如何训练一个语言模型 学习torchtext的基本使用方法 构 ...

  2. Deep Dive into Pytorch RNN/LSTM

    RNN/LSTM 1.LSTM及其pytorch实现 1.1 遗忘门 forget gate 1.2 输入门 input gate 1.3 Cell State更新 1.4 Output Gate 2 ...

  3. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  4. 循环神经网络实现文本情感分类之Pytorch中LSTM和GRU模块使用

    循环神经网络实现文本情感分类之Pytorch中LSTM和GRU模块使用 1. Pytorch中LSTM和GRU模块使用 1.1 LSTM介绍 LSTM和GRU都是由torch.nn提供 通过观察文档, ...

  5. Pytorch的backward()相关理解

    Pytorch的backward()相关理解 最近一直在用pytorch做GAN相关的实验,pytorch 框架灵活易用,很适合学术界开展研究工作.  这两天遇到了一些模型参数寻优的问题,才发现自己对 ...

  6. Tensorflow[基础篇]——LSTM的理解与实现

    前言 本文参考了tensorflow github里面的实现的lstm的教程代码6_lstm.ipynb.因为这代码即实现了lstm,也实操了tf的内容,可以说是一箭双雕. 源码地址:https:// ...

  7. Pytorch《LSTM模型》

    前面的博文我们讲了LSTM的原理与分析,这一篇我们用pytorch类LSTM做测试 完整测试代码如下,用于进行MNIST数据集测试,主要学习LSTM类的输入输出维度. 这里定义的LSTM模型是用了三层 ...

  8. LSTM结构理解与python实现

    LSTM结构理解与python实现 上篇博客中提到,简单的RNN结构求解过程中易发生梯度消失或梯度爆炸问题,从而使得较长时间的序列依赖问题无法得到解决,其中一种越来越广泛使用的解决方法就是 Long ...

  9. pytorch中repeat()函数理解

    pytorch中repeat()函数理解 最近在学习过程中遇到了repeat()函数的使用,这里记录一下自己对这个函数的理解. 情况1:repeat参数个数与tensor维数一致时 a = torch ...

最新文章

  1. 使用元学习来进行少样本图像分类
  2. 基于Cobbler实现多版本系统批量部署
  3. module ‘mxnet.symbol‘ has no attribute ‘LSoftmax‘
  4. 全球及中国液压磁路保护器行业发展规划与产销需求预测报告2022版
  5. Android异步任务机制之AsycTask
  6. boost::hana模块实现算术的测试程序
  7. 2021HDU多校10 - 7084 Pty loves string(KMPnext树+主席树+dfs序)
  8. [vue] 你有自己用vue写过UI组件库吗?
  9. 设计有三个窗口的框架结构网页_技术周刊丨钢框架结构直接分析设计与传统设计方法对比研究——恒荷载作用结果对比...
  10. 数据结构—链表-单链表应用-拆分链表
  11. 西瓜书+实战+吴恩达机器学习(十八)降维(主成分分析 PCA)
  12. 辽宁工业大学计算机复试经验,辽宁工业大学车辆工程考研经验
  13. android百度定位代码,android开发:百度地图及定位的演示代码
  14. 文本分类pytorch Bert fine tune
  15. 中级 PHP 知识点汇总
  16. 使用计算机仓储管理,计算机在医药仓库管理中的应用
  17. Android性能优化—TraceView的使用
  18. 2020中国汽车后市场白皮书
  19. 综合评价之熵值法+TOPSIS
  20. 考试系统设计oracle,在线考试系统的设计与实现|毕业设计源代码|论文开题报告|Oracle...

热门文章

  1. 2022-2028年中国鸡血石产业市场研究及前瞻分析报告
  2. 2022-2028年中国硅质原料行业全景调研及投资前景展望报告
  3. Go 学习笔记(82)— Go 第三方库之 viper(解析配置文件、热更新配置文件)
  4. SpringBoot (二) :全局异常处理设置
  5. bert-as-service使用
  6. 信息熵及其相关概念--数学
  7. TensorFlow文本情感分析实现
  8. HiCar SDK概述
  9. 客快物流大数据项目(六):Docker与虚拟机的形象比喻及组件介绍
  10. 2021年大数据Flink(二十七):Flink 容错机制 Checkpoint