1. 什么是LSTM

在你阅读这篇文章时候,你都是基于自己已经拥有的对先前所见词的理解来推断当前词的真实含义。我们不会将所有的东西都全部丢弃,然后用空白的大脑进行思考。我们的思想拥有持久性。LSTM就是具备了这一特性。

这篇将介绍另⼀种常⽤的⻔控循环神经⽹络:**⻓短期记忆(long short-term memory,LSTM)[1]。**它⽐⻔控循环单元的结构稍微复杂⼀点,也是为了解决在RNN网络中梯度衰减的问题,是GRU的一种扩展。

可以先理解GRU的过程,在来理解LSTM会容易许多,链接地址:三步理解--门控循环单元(GRU)

LSTM 中引⼊了3个⻔,即输⼊⻔(input gate)、遗忘⻔(forget gate)和输出⻔(output gate),以及与隐藏状态形状相同的记忆细胞(某些⽂献把记忆细胞当成⼀种特殊的隐藏状态),从而记录额外的信息。

2. 输⼊⻔、遗忘⻔和输出⻔

与⻔控循环单元中的重置⻔和更新⻔⼀样,⻓短期记忆的⻔的输⼊均为当前时间步输⼊Xt与上⼀时间步隐藏状态Ht−1,输出由激活函数为sigmoid函数的全连接层计算得到。如此⼀来,这3个⻔元素的值域均为[0, 1]。如下图所示:

具体来说,假设隐藏单元个数为 h,给定时间步 t 的小批量输⼊ (样本数为n,输⼊个数为d)和上⼀时间步隐藏状态 。三个门的公式如下:

输入门: 

遗忘门: 

输出门: 

3. 候选记忆细胞

接下来,⻓短期记忆需要计算候选记忆细胞 。它的计算与上⾯介绍的3个⻔类似,但使⽤了值域在[−1, 1]的tanh函数作为激活函数,如下图所示:

具体来说,时间步t的候选记忆细胞计算如下:

4. 记忆细胞

我们可以通过元素值域在[0, 1]的输⼊⻔、遗忘⻔和输出⻔来控制隐藏状态中信息的流动,这⼀般也是通过使⽤按元素乘法(符号为⊙)来实现的。当前时间步记忆细胞的计算组合了上⼀时间步记忆细胞和当前时间步候选记忆细胞的信息,并通过遗忘⻔和输⼊⻔来控制信息的流动:

如下图所⽰,遗忘⻔控制上⼀时间步的记忆细胞Ct−1中的信息是否传递到当前时间步,而输⼊⻔则控制当前时间步的输⼊Xt通过候选记忆细胞C˜t如何流⼊当前时间步的记忆细胞。如果遗忘⻔⼀直近似1且输⼊⻔⼀直近似0,过去的记忆细胞将⼀直通过时间保存并传递⾄当前时间步。这个设计可以应对循环神经⽹络中的梯度衰减问题,并更好地捕捉时间序列中时间步距离较⼤的依赖关系。

5. 隐藏状态

有了记忆细胞以后,接下来我们还可以通过输出⻔来控制从记忆细胞到隐藏状态Ht的信 息的流动:

这⾥的tanh函数确保隐藏状态元素值在-1到1之间。需要注意的是,当输出⻔近似1时,记忆细胞信息将传递到隐藏状态供输出层使⽤;当输出⻔近似0时,记忆细胞信息只⾃⼰保留。下图展⽰了⻓短期记忆中隐藏状态的全部计算:

6. LSTM与GRU的区别

LSTM与GRU二者结构十分相似,不同在于

  1. 新的记忆都是根据之前状态及输入进行计算,但是GRU中有一个重置门控制之前状态的进入量,而在LSTM里没有类似门;
  2. 产生新的状态方式不同,LSTM有两个不同的门,分别是遗忘门(forget gate)和输入门(input gate),而GRU只有一种更新门(update gate);
  3. LSTM对新产生的状态可以通过输出门(output gate)进行调节,而GRU对输出无任何调节。
  4. GRU的优点是这是个更加简单的模型,所以更容易创建一个更大的网络,而且它只有两个门,在计算性上也运行得更快,然后它可以扩大模型的规模。
  5. LSTM更加强大和灵活,因为它有三个门而不是两个。

7. LSTM可以使用别的激活函数吗?

关于激活函数的选取,在LSTM中,遗忘门、输入门和输出门使用Sigmoid函数作为激活函数;在生成候选记忆时,使用双曲正切函数Tanh作为激活函数。

值得注意的是,这两个激活函数都是饱和的,也就是说在输入达到一定值的情况下,输出就不会发生明显变化了。如果是用非饱和的激活函数,例如ReLU,那么将难以实现门控的效果。

Sigmoid函数的输出在0~1之间,符合门控的物理定义。且当输入较大或较小时,其输出会非常接近1或0,从而保证该门开或关。在生成候选记忆时,使用Tanh函数,是因为其输出在−1~1之间,这与大多数场景下特征分布是0中心的吻合。此外,Tanh函数在输入为0附近相比Sigmoid函数有更大的梯度,通常使模型收敛更快。

激活函数的选择也不是一成不变的,但要选择合理的激活函数。

8. 代码实现

构建单层LSTM网络对MNIST数据集分类

这里的输入x当成28个时间段,每段内容为28个值,使用unstack将原始的输入28×28调整成具有28个元素的list

每个元素为1×28的数组。这28个时序一次送入RNN中,如图下图所示:

由于是批次操作,所以每次都取该批次中所有图片的一行作为一个时间序列输入。

理解了这个转换之后,构建网络就变得很容易了,先建立一个包含128个cell的类lstm_cell,然后将变形后的x1放进去生成节点outputs,最后通过全连接生成pred,最后使用softmax进行分类。

'''
本程序实现用LSTM对MNIST进行图片分类
'''import torch
import numpy as np
import torch.nn as nn
import torch.utils.data as Data
import torchvision
import matplotlib.pyplot as plt# Hyper parameter
EPOCH = 1
LR = 0.001    # learning rate
BATCH_SIZE = 50# Mnist digit dataset
train_data = torchvision.datasets.MNIST(root='/Users/wangpeng/Desktop/all/CS/Courses/Deep Learning/mofan_PyTorch/mnist/',    # mnist has been downloaded before, use it directlytrain=True,    # this is training datatransform=torchvision.transforms.ToTensor(),    # Converts a PIL.Image or numpy.ndarray to# torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]download=False,
)# print(train_data.data.size())       # (60000, 28, 28)
# print(train_data.targets.size())    # (60000)
# plot one image
# plt.imshow(train_data.data[0].numpy(), cmap='gray')
# plt.title('{:d}'.format(train_data.targets[0]))
# plt.show()# Data Loader for easy mini-batch return in training, the image batch shape will be (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)test_data = torchvision.datasets.MNIST(root='/Users/wangpeng/Desktop/all/CS/Courses/Deep Learning/mofan_PyTorch/mnist/',train=False,  # this is training data
)
# print(test_data.data.size())       # (10000, 28, 28)
# print(test_data.targets.size())    # (10000)
# pick 2000 samples to speed up testing
test_x = test_data.data.type(torch.FloatTensor)[:2000]/255    # shape (2000, 28, 28), value in range(0,1)
test_y = test_data.targets[:2000]class LSTMnet(nn.Module):def __init__(self, in_dim, hidden_dim, n_layer, n_class):super(LSTMnet, self).__init__()self.n_layer = n_layerself.hidden_dim = hidden_dimself.lstm = nn.LSTM(in_dim, hidden_dim, n_layer, batch_first=True)self.linear = nn.Linear(hidden_dim, n_class)def forward(self, x):                  # x's shape (batch_size, 序列长度, 序列中每个数据的长度)out, _ = self.lstm(x)              # out's shape (batch_size, 序列长度, hidden_dim)out = out[:, -1, :]                # 中间的序列长度取-1,表示取序列中的最后一个数据,这个数据长度为hidden_dim,# 得到的out的shape为(batch_size, hidden_dim)out = self.linear(out)             # 经过线性层后,out的shape为(batch_size, n_class)return outmodel = LSTMnet(28, 64, 2, 10)             # 图片大小28*28,lstm的每个隐藏层64个节点,2层隐藏层
if torch.cuda.is_available():model = model.cuda()optimizer = torch.optim.Adam(model.parameters(), lr=LR)
criterion = nn.CrossEntropyLoss()# training and testing
for epoch in range(EPOCH):for iteration, (train_x, train_y) in enumerate(train_loader):    # train_x's shape (BATCH_SIZE,1,28,28)train_x = train_x.squeeze()        # after squeeze, train_x's shape (BATCH_SIZE,28,28),# 第一个28是序列长度,第二个28是序列中每个数据的长度。output = model(train_x)loss = criterion(output, train_y)  # cross entropy lossoptimizer.zero_grad()              # clear gradients for this training steploss.backward()                    # backpropagation, compute gradientsoptimizer.step()                   # apply gradientsif iteration % 100 == 0:test_output = model(test_x)predict_y = torch.max(test_output, 1)[1].numpy()accuracy = float((predict_y == test_y.numpy()).astype(int).sum()) / float(test_y.size(0))print('epoch:{:<2d} | iteration:{:<4d} | loss:{:<6.4f} | accuracy:{:<4.2f}'.format(epoch, iteration, loss, accuracy))# print 10 predictions from test data
test_out = model(test_x[:10])
pred_y = torch.max(test_out, dim=1)[1].data.numpy()
print('The predict number is:')
print(pred_y)
print('The real number is:')
print(test_y[:10].numpy())

长短期记忆(LSTM)相关推荐

  1. 花书+吴恩达深度学习(十七)序列模型之长短期记忆 LSTM 和门控循环单元 GRU

    目录 0. 前言 1. 长短期记忆 LSTM 2. 门控循环单元 GRU 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔~我会非常开心的~ 花书+吴恩达深度学习(十五)序列模型之循环神经网络 ...

  2. 忆阻器交叉开关阵列中的长短期记忆(LSTM)神经网络

    忆阻器交叉开关阵列中的长短期记忆(LSTM)神经网络 原文:Long short-term memory networks in memristor crossbar arrays 作者:CanLi. ...

  3. 动手学PyTorch | (35) 长短期记忆(LSTM)

    本节将介绍另一种常⽤的⻔控循环神经网络:长短期记忆(long short-term memory,LSTM).它⽐⻔控循环单元的结构稍微复杂一点. 目录 1. 长短期记忆 2. 读取数据集 3. 从0 ...

  4. torch学习 (三十二):周杰伦歌词数据集与长短期记忆 (LSTM)

    文章目录 1 引入 2 长短期记忆 2.1 输入门.遗忘门和输出门 2.2 候选记忆细胞 2.3 记忆细胞 2.4 隐藏状态 3 代码 致谢 1 引入   本文介绍一种常用的门控循环神经网络:长短期记 ...

  5. 循环神经网络(RNN)之长短期记忆(LSTM)

    长短期记忆(Long Short Term Memory)跟上篇的循环神经网络(RNN)之门控循环单元(GRU),两者比较的话,LSTM稍微更复杂一点,但很类似,对整个隐藏单元来讲可以说增加了一个记忆 ...

  6. 理解长短期记忆(LSTM) 神经网络

    声明:本文翻译自colah的博客,原文地址:Understanding LSTM NETWORK 递归神经网络 人类并不是从混沌状态开始他们的思考.就像你读这篇文章时,你是建立在你之前对文字的理解上. ...

  7. 长短期记忆(LSTM)相关知识

    文章目录 LSTM结构 遗忘门 输入门 决定给细胞状态C添加哪些新的信息 更新旧的细胞信息 输出门 LSTM小结 如何实现长期依赖? 如何避免梯度消失/爆炸? 双向LSTM(Bi-LSTM) GRU ...

  8. 如何判断LSTM模型的过度拟合和欠拟合——长短期记忆(LSTM)系列_LSTM的建模方法(3)

    导读: 本文主要讲了一些模型中一个常见的问题,训练不足和过度拟合. 过度拟合指的是由于训练数据过少,或者对训练集训练的次数过多,导致模型的结果不是找到所有数据的一般共有特性,而是仅对训练数据进行了特征 ...

  9. 【DL】长短期记忆网络(LSTM)

    导航 LSTM原理 GRU原理 Seq2Seq架构 编码信息损失 参考资料 LSTM原理 一般RNN中仅有一个隐藏状态单元hth_tht​,且不同时刻的隐藏状态单元的参数是共享的,这种结构导致了RNN ...

最新文章

  1. 用mpvue实现的微信小程序版cnode社区
  2. 步步高java短信恢复_步步高智能手机自带的程序不见了怎么找回
  3. 如何在Windows系统上使用Object Detection API训练自己的数据?
  4. android模糊检索_【android学习笔记】ormlite学习之模糊搜索like
  5. java 高飞_高飞(土木与水利工程学院)老师 - 合肥工业大学
  6. 分析ERP上线时可能存在的失误
  7. 5种获取RSS全文输出的方法
  8. 预处理,编译,汇编,链接程序的区别
  9. 2020【第十一届蓝桥杯省赛】 C/C++ B组 (第一场)
  10. 丢手帕问题 (约瑟夫问题)Java实现
  11. python dictionay(字典 )基本用法
  12. 两小时学会ajax,全程无废话,直接上代码,追求速度的来
  13. 酒桌上的学问(搜集整理帖)
  14. 怎么样可以对腾讯云IM-SDK集成(web端)完成IM登录
  15. 数据分析师职业发展的几个层次,具体是什么做什么的
  16. Google快讯使用小记
  17. Mybatis001_JDBC
  18. python面向对象实例王者荣耀_用python的requests第三方模块抓取王者荣耀所有英雄的皮肤实例...
  19. 态度决定一切《跟任何人都聊得来》
  20. 语法分析程序--编译原理

热门文章

  1. 基于单片机交通灯控制的c语言程序设计,基于单片机控制的交通灯毕业设计
  2. MAE TransMix
  3. arcgis制作格网图
  4. 直观理解--马氏距离
  5. ionic3应该善用组件和指令 (实用、赞)
  6. 条件概率与事件的相互独立性
  7. 2021双非计算机保研之路(经验之谈)
  8. NetworkX学习及使用
  9. 怎样设定绩效考核指标
  10. 新手使用Docker教程