深度学习(2)LSTM长短期记忆网络

欢迎来到theFlyer的博客—希望你有不一样的感悟

前言:这次内容是LSTM,主要讲解了LSTM的前向传播和一个飞机流量的代码,若无基础建议先看下循环神经网络RNN。

目录

一. LSTM提出原因

RNN存在的问题

记忆最大的问题在于遗忘性,我们能更加清楚记得最近发生的事情而遗忘很久之前的事情。循环神经网络同样有这样的问题。循环神经网络可以解决短时依赖问题。相关的信息和预测的词位置之间的间隔是非常小的,RNN 可以学会使用先前的信息.

这里写图片描述

若记忆信息和预测位置之间跨度太大,循环神经网络就越来越难学到这些信息。

这里写图片描述

问题存在原因

在RNN中,采用了Sigmoid函数,它的导数值域范围是(0,1/4]内,每次反向传播都会以1/4的速度递减,时间越远梯度减小越明显。 例:若当前时刻为t,在(t-3)时刻时,梯度将减少至少(0.25*0.25*0.25=1/64),这就是原始RNN无法处理长距离依赖的原因。LSTM则克服了梯度消失的缺点,对于捕获长时间的记忆信息效果非常显著。

这里写图片描述

梯度消失:上图的t-3时刻开始,梯度已经几乎减少到0。从这个时刻开始再往之前走,得到的梯度(几乎为零)就不会对最终的梯度值有任何贡献,这就相当于无论t-3时刻之前的网络状态h是什么,在训练中都不会对权重数组W的更新产生影响,也就是网络事实上已经忽略了t-3时刻之前的状态

二. LSTM模型

1RNN与LSTM

1.1RNN

在标准的 RNN 中,这个重复的模块只有一个非常简单的结构

这里写图片描述

1.2LSTM

在下面的图例中,每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入。粉色的圈代表 pointwise 的操作,诸如向量的和,而黄色的矩阵就是学习到的神经网络层。合在一起的线表示向量的连接,分开的线表示内容被复制,然后分发到不同的位置。

这里写图片描述

1.3LSTM与RNN

长短时记忆网络的思路比较简单。原始RNN的隐藏层只有一个状态,即h,它对于短期的输入非常敏感。那么,假如我们再增加一个状态,即c,让它来保存长期的状态。新增加的状态c,称为单元状态(cell state)。

这里写图片描述

2存储长期信息

2.1引入simple RNN

这里写图片描述

为介绍如何存储长期信息,引入simple RNN。

2.2如何存储新的信息

这里写图片描述

把新信息放到长期状态C,有两种操作,乘法操作,加法操作。
乘法操作更多的是作为一种对信息进行某种控制的操作(比如任意数与0相乘后直接消失,相当于关闭操作;任意数与大于1的数相乘后会被放大规模等),而加法操作则是新信息叠加旧信息的操作。

2.3乘法操作

这里写图片描述
这里写图片描述
这里写图片描述

通过以上模型的构建,可以发现直接将历史记忆乘进长时记忆单元只会让情况更糟糕,这也说明了乘性更新并不是简单的信息叠加,而是控制。

2.4加法操作

这里写图片描述

直接将历史记忆乘进长时记忆单元只会让情况更糟糕,这也说明了乘性更新并不是简单的信息叠加,而是控制。加法操作则是新信息叠加旧信息的操作。

3LSTM结构

3.1门(gate)

这里写图片描述

门的使用,就是用门的输出向量按元素乘以我们需要控制的那个向量。因为门的输出是0到1之间的实数向量,那么,当门输出为0时,任何向量与之相乘都会得到0向量,这就相当于什么都不能通过;输出为1时,任何向量与之相乘都不会有任何改变,这就相当于什么都可以通过。而这里sigmoid函数的值域是(0,1) ,所以门的状态都是半开半闭的。

3.2遗忘门

这里写图片描述

通过将上一隐藏层的输出信息与当前的输入进行线性组合后,利用激活函数,将函数值压缩,得到一个大小在0和1之间的阈值,当函数值越接近1时,表示记忆体保留的信息越多。当函数值越接近0时,表示记忆体丢弃的信息就越多。

3.3输入门

这里写图片描述

输入门决定了当前时刻的输入信息,有多少信息将添加到记忆信息流中,与遗忘门计算公式几乎一致,输入门同样通过一个激活函数来实现。

3.4候选门

这里写图片描述

可以把候选门的输出理解为近期信息,有当前的输入xt,和上一时刻隐藏层的状态ht-1。

这里写图片描述

新信息是否被记忆是一个控制操作,应该使用乘法操作。因此在新信息前加一个控制阀门。
遗忘门是用来控制记忆消失程度的,因此也要用乘性运算。
然后在采用之前提到为把把新信息放到长期状态C中的加法操作。

3.5输出门

这里写图片描述

输出门,它控制着有多少记忆信息将被用于下一阶段的更新中。

3.6LSTM整体模型

这里写图片描述

输出门,它控制着有多少记忆信息将被用于下一阶段的更新中。

三. LSTM用于时间序列分析

1.1目的

用前几个月的飞机流量来预测当月的流量。

读入数据是2010年的飞机月流量
这里写图片描述

1.2模型

数据预处理,将数据中 na 的数据去掉,然后将数据标准化到 0 ~ 1 之间。


# 数据预处理
data_csv = data_csv.dropna()
dataset = data_csv.values
dataset = dataset.astype('float32')
max_value = np.max(dataset)
min_value = np.min(dataset)
scalar = max_value - min_value
dataset = list(map(lambda x: x / scalar, dataset))

进行数据集的创建,可以把前两个月流量数据作为输入,当月流量作为标签。为了进一步测试可以把数据划分为训练集、测试集。这里主要看下LSTM模型。

"""pytorch"""
# 定义模型
class lstm_reg(nn.Module):
    def __init__(self, input_size, hidden_size, output_size=1, num_layers=2):
        super(lstm_reg, self).__init__()

        self.rnn = nn.LSTM(input_size, hidden_size, num_layers) # rnn
        self.reg = nn.Linear(hidden_size, output_size) # 回归

    def forward(self, x):
        x, _ = self.rnn(x) # (seq, batch, hidden)
        s, b, h = x.shape
        x = x.view(s*b, h) # 转换成线性层的输入格式
        x = self.reg(x)
        x = x.view(s, b, -1)
        return x

net = lstm_reg(2, 4)

criterion = nn.MSELoss()
optimizer = torch.optim.Adam(net.parameters(), lr=1e-2)

定义好网络结构,输入的维度是 2,因为使用两个月的流量作为输入,隐藏层的维度可以任意指定,这里指定为 4

预测结果如下
这里写图片描述

这里蓝色的是真实的数据集,红色的是预测的结果,可以看到,使用 lstm 能够得到比较相近的结果,预测的趋势也与真实的数据集是相同的.

代码及数据下载
参考
注1: 内容参考了博文LSTM
注2: 代码参考了书籍

后记:孔曰成仁,孟曰取义,惟其义尽,所以仁至。读圣贤书,所学何事,而今而后,庶几无愧。

这里写图片描述欢迎关注个人公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值