关于LSTM

理论

LSTM是什么
Lstm是RNN的一个变体,可以在一定程度上解决梯度消失和梯度爆炸这两个问题。
LSTM和基线RNN并没有特别大的结构不同,但是它们用了不同的函数来计算隐状态。
对比
RNN:
所有RNN都具有一种重复神经网络模块的链式的形式。在标准的RNN中,这个重复的模块只有一个非常简单的结构,例如一个tanh层。
激活函数 Tanh 作用在于帮助调节流经网络的值,使得数值始终限制在 -1 和 1 之间。
在这里插入图片描述
LSTM:
在这里插入图片描述

上图中,σ表示的Sigmoid 激活函数与 tanh 函数类似,不同之处在于 sigmoid 是把值压缩到0-1 之间而不是 -1~1 之间。这样的设置有助于更新或忘记信息:
因为任何数乘以0都得0,这部分信息就会被剔除掉
任何数乘以1都是它本身 即信息被保存
LSTM详细结构
1、忘记门
在这里插入图片描述
这个门决定了从细胞状态中丢弃什么信息。该忘记门会读取上一个输出ht−1,和当前输入xt,做一个Sigmoid 的非线性映射,然后输出一个向量ft(该向量每一个维度的值都在0到1之间,1表示完全保留,0表示完全舍弃,相当于记住了重要的,忘记了无关紧要的),最后与细胞状态Ct−1相乘。
2、输入门
在这里插入图片描述
sigmoid层称“输入门层”决定什么值我们将要更新;一个tanh层创建一个新的候选值向量,会被加入到状态中
3、细胞更新
在这里插入图片描述
4、输出门
在这里插入图片描述
首先,我们运行一个sigmoid层来确定细胞状态的哪个部分将输出出去。
接着,我们把细胞状态通过tanh进行处理(得到一个在-1到1之间的值)并将它和sigmoid门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。
LSTM变体:GRU
它将忘记门和输入门合成了一个单一的更新门。同样还混合了细胞状态和隐藏状态,和其他一些改动。最终的模型比标准的LSTM模型要简单,也是非常流行的变体。
在这里插入图片描述

应用

torch.nn.LSTM()
总共有7个参数 前3个是必须传入的
1、input_size:输入的特征维数,即每一行输入的元素的个数。
2、hidden_size:隐藏层的维数,即隐藏层节点的个数。
3、num_layers:LSTM堆叠的层数,默认值是1,如果是2,则第二个LSTM接收第一个LSTM的计算结果。
4、bias: 隐层状态是否带bias,默认为true。bias是偏置值,或者偏移值。
5、 batch_first: 输入输出的第一维是否为 batch_size,默认值 False。因为 Torch 中,人们习惯使用Torch中带有的dataset,dataloader向神经网络模型连续输入数据,这里面就有一个 batch_size 的参数,表示一次输入多少个数据。 在 LSTM 模型中,输入数据必须是一批数据,为了区分LSTM中的批量数据和dataloader中的批量数据是否相同意义,LSTM 模型就通过这个参数的设定来区分。 如果是相同意义的,就设置为True,如果不同意义的,设置为False。 torch.LSTM 中 batch_size 维度默认是放在第二维度,故此参数设置可以将 batch_size 放在第一维度。如:input 默认是(4,1,5),中间的 1 是 batch_size,指定batch_first=True后就是(1,4,5)。所以,如果你的输入数据是二维数据的话,就应该将 batch_first 设置为True;
6、 dropout: 默认值0。
7、 bidirectional: 是否是双向 RNN,默认为:false,若为 true,则:num_directions=2,否则为1。
pytorch中nn.LSTM的输入格式

输入数据格式:
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)

假设有3个句子,每个句子5个单词,每个单词用10维表示,那么对应的维度应该是(5,3,10)
H0-Hn是什么意思呢?就是每个时刻中间神经元应该保存的这一时刻的根据输入和上一课的时候的中间状态值应该产生的本时刻的状态值
这个数据单元是起的作用就是记录这一时刻之前考虑到所有之前输入的状态值,形状应该是和特定时刻的输出一致
c0-cn就是开关,决定每个神经元的隐藏状态值是否会影响的下一时刻的神经元的处理,形状应该和h0-hn一致。

#LSTM应用
import torch.nn as nn
import torch

batch_size = 10  # 句子的数量
seq_len = 20  # 每个句子的长度
vocab_size = 100  # 词典中词语的总数
embedding_dim = 30  # 用长度为30的向量表示一个词语

hidden_size = 18  # 隐层中lstm的个数
num_layer = 1  # 多少个隐藏层

# 构造一个batch的数据
input = torch.randint(low=0,high=100,size=[batch_size,seq_len])  # [10,20]
print(input)

# 数据经过embedding处理
embedding = nn.Embedding(vocab_size,embedding_dim)  #[100,30]
input_embeded = embedding(input)  # [10,20,30]

# 把embedding之后的数据传入lstm
lstm = nn.LSTM(input_size=embedding_dim,hidden_size=hidden_size,num_layers=num_layer,batch_first=True)
output,(h_n,c_n) = lstm(input_embeded)
print('output',output,output.size())  # output的shape=(batch_size,seq_length,num_directions*hidden_size),#torch.Size([10, 20, 18])

print('*'*100)
print('h_n',h_n)  # h_n.shape==(num_directions * num_layers,batch,hidden_size)
print(h_n.size())  # torch.Size([1, 10, 18])  
print('*'*100)
print('c_n',c_n)  # c_n.shape==h_n.shape
print(c_n.size())  # torch.Size([1, 10, 18])

参考文章:https://blog.csdn.net/v_JULY_v/article/details/89894058?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169061902416800182177370%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=169061902416800182177370&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-2-89894058-null-null.142v91insertT0,239v12control2&utm_term=LSTM&spm=1018.2226.3001.4187

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值