使用Keras实现 基于注意力机制(Attention)的 LSTM 时间序列预测

时隔半年多,毕设男孩终于重操旧业,回到了LSTM进行时间序列预测和异常检测的路上。如果有阅读过我之前的博客,可以发现使用LSTM作单类的时间序列异常检测也是基于对于时间序列的预测进行登堂入室LSTM:使用LSTM进行简单的时间序列异常检测本次我们要进行的是使用注意力机制+LSTM进行时间序列预测,项目地址为KerasAttentionMechanism首先我们把它git…

大家好,又见面了,我是你们的朋友全栈君。

时隔半年多,毕设男孩终于重操旧业,回到了 LSTM进行时间序列预测和异常检测的路上。

如果有阅读过我之前的博客,可以发现使用 LSTM作单类的时间序列异常检测也是基于对于时间序列的预测进行 登堂入室LSTM:使用LSTM进行简单的时间序列异常检测

本次我们要进行的是 使用 注意力机制 + LSTM 进行时间序列预测,项目地址为Keras Attention Mechanism

对于时间步的注意力机制

首先我们把它git clone 到本地,然后配置好所需环境 笔者的 tensorflow版本为1.6.0 Keras 版本为 2.0.2
打开文件夹,我们主要需要的是attention_lstm.py 以及 attention_utils.py 脚本

项目中生成数据的函数为

def get_data_recurrent(n, time_steps, input_dim, attention_column=10):
    """ Data generation. x is purely random except that it's first value equals the target y. In practice, the network should learn that the target = x[attention_column]. Therefore, most of its attention should be focused on the value addressed by attention_column. :param n: the number of samples to retrieve. :param time_steps: the number of time steps of your series. :param input_dim: the number of dimensions of each element in the series. :param attention_column: the column linked to the target. Everything else is purely random. :return: x: model inputs, y: model targets """
    x = np.random.standard_normal(size=(n, time_steps, input_dim))
    y = np.random.randint(low=0, high=2, size=(n, 1))
    x[:, attention_column, :] = np.tile(y[:], (1, input_dim))
    return x, y

默认的 n = 30000, input_dim = 2 ,timesteps = 20。生成的数据为:

shape
x 30000 x 20 x 2
y 30000 x 1

其中 x 的第11个 timestep 两维的数据 与y相同,其他timestep 维的数据为随机数。

所以当我们使用这样的数据去进行 注意力机制 LSTM 的训练,我们希望得到的结果是 注意力层 主要关注第11个timestep 而对其他timestep 的关注度较低。

直接运行 attention_lstm.py 脚本
此时的网络结构为:
在这里插入图片描述
可以看到是在 LSTM 层之后使用了注意力机制

最后会汇总画一张图
在这里插入图片描述
可以看到 可以看到注意力的权重主要汇总在了第11个timestep,说明注意力机制很成功

对于维的注意力机制

上述的例子 是将注意力机制使用在了 timestep 上,决定哪个时间步对于结果的影响较大。
而如果我们想将 注意力机制使用在维上呢? 比如使用多维去预测一维的数据,我们想使用注意力机制
决定哪些维对于预测维起关键作用。

比较简单的方法就是将输入数据 reshape 一下 将timesteps 与 input_dim 维对换 再运行就可以了,因为本代码的设置就是对 输入的第2维加入注意力机制.

进阶的方法就是 自写一下 attention_3d_block 函数:

def attention_3d_block(inputs):
    # inputs.shape = (batch_size, time_steps, input_dim)
    input_dim = int(inputs.shape[2])
    a = inputs
    #a = Permute((2, 1))(inputs)
    #a = Reshape((input_dim, TIME_STEPS))(a) # this line is not useful. It's just to know which dimension is what.
    a = Dense(input_dim, activation='softmax')(a)
    if SINGLE_ATTENTION_VECTOR:
        a = Lambda(lambda x: K.mean(x, axis=1), name='dim_reduction')(a)
        a = RepeatVector(input_dim)(a)
    a_probs = Permute((1, 2), name='attention_vec')(a)
    #a_probs = a
    output_attention_mul = merge([inputs, a_probs], name='attention_mul', mode='mul')
    return output_attention_mul

其实严格来讲我们所做的改变不多,作者使用了 Permute层对于数据进行了 第2和第3维的对换,我们则没有进行对换操作。

接下来 再在attention_utils.py 脚本中写一个产生数据集的新函数:

def get_data_recurrent2(n, time_steps, input_dim, attention_dim=5):
    """ 假设 input_dim = 10 time_steps = 6 产生一个 x 6 x 10 的数据 其中每步的第 6 维 与 y相同 """
    x = np.random.standard_normal(size=(n, time_steps, input_dim))
    y = np.random.randint(low=0, high=2, size=(n, 1))
    x[:,:,attention_dim] =  np.tile(y[:], (1, time_steps))

    return x,y

试着产生一组数据 get_data_recurrent2(1,6,10)
在这里插入图片描述

然后我们稍微改动一下main函数进行新的训练。迭代十次后结果为:
在这里插入图片描述
可以看到,第6维的权重比较大。
如果我们对于timesteps的注意力画一个汇总图,即改动一下

  attention_vector = np.mean(get_activations(m, testing_inputs_1,print_shape_only=False,layer_name='attention_vec')[0], axis=2).squeeze()

可以看到对于timesteps的注意力是相同的(其实如果对于开头时间步的注意力机制,对输入维的注意力画一个汇总图,也是相同的)
在这里插入图片描述

对于时间步和输入维的注意力机制

待补充

注:参考 keras-attention-mechanism
以及 Keras中文文档

代码已上传到我的github

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125920.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 类似于吾爱激活成功教程的免费论坛_哔哩哔哩吾爱激活成功教程

    类似于吾爱激活成功教程的免费论坛_哔哩哔哩吾爱激活成功教程吾爱激活成功教程吧http://www.52pjb.net/网站收集了众多软件,类似于软件博客这种,同行业的还有胡萝卜周、易激活成功教程、心海这类的,如果你喜欢这种风格的软件下载博客,那么它绝对是首选,当然也是不要钱的,也没有什么赞助收费这类的盈利,站长完全是用爱发电!不过缺点是有些资源需要用网盘下载,毕竟是激活成功教程软件,也是可以理解的!吾爱激活成功教程论坛他也是目前国内最大的软件激活成功教程论坛,而且网友都很热心,也是国内下载氛围最好的软件下载网站论坛,也还不错。正版中国是一个分享正版软件限时免费..

    2022年10月13日
    0
  • 超详细,手把手 教你 SQLyog 安装教程[通俗易懂]

    超详细,手把手 教你 SQLyog 安装教程[通俗易懂]1.点击SQLyog.exe,如下图2.点击ok,如下图3.点击下一步4.接收协议,点击下一步5.下一步6.更改安装路径,点击安装7.下一步,完成8.注册,需要密钥,名字随意密钥:dd987f34-f358-4894-bd0f-21f3f04be9c19.注册完成,如下图9.新建连接,并随意起个名字10.输入密码,连接数据库11.连接成功之后,就可以使用了…

    2022年5月28日
    1.3K
  • Java IO流处理 面试题汇总

    Java IO流处理 面试题汇总说明:本节内容来源于网络汇总输入输出流是相对于内存而言的!1、面试题汇总(1)java中有几种类型的流?字符流和字节流。字节流继承inputStream和OutputStream,字符流继承自InputSteamReader和OutputStreamWriter。(2)谈谈JavaIO里面的常见类,字节流,字符流、接口、实现类、方法阻塞答:输入流就…

    2022年6月14日
    24
  • windows日志转发到服务器_windows查看日志

    windows日志转发到服务器_windows查看日志配置windows日志事件转发详细教程

    2022年9月8日
    1
  • fragment与activity生命周期方法是一致的_android的生命周期

    fragment与activity生命周期方法是一致的_android的生命周期如果我们在Fragment和它的宿主Activity的生命周期中都加上Log日志,你能顺利写出他们的执行顺序吗?我们先来看一张Google官方的图片:咋一听,Activity生命周期有七个方法,Fragment生命周期有十一个方法,貌似挺复杂的,其实我们只需要明白到底是谁带领着谁去执行生命周期的方法,就能很快弄明白这个问题。在创建的过程中,是Activity带领Fragment执行生命周期中

    2022年8月16日
    3
  • Kali 更新源(国内镜像)

    Kali 更新源(国内镜像)1.更新软件源sudovim/etc/apt/sources.list2.选择比较合适的源(选择一个即可)#中科大debhttp://mirrors.ustc.edu.cn/kalikali-rollingmainnon-freecontribdeb-srchttp://mirrors.ustc.edu.cn/kalikali-rollingmainnon-freecontrib#阿里云debhttp://mirrors.aliyun.com/kalikali-ro

    2022年5月8日
    166

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号