远程项目调试-informer2020

news2024/9/22 15:36:40

informer2020

     Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting(原文)

Informer 是一个基于Transformer的模型,是为了应对长依赖关系而开发的。本文的主要主题是序列预测。序列预测可以在任何具有不断变化的数据的地方找到,例如股票市场等。尽管人工智能在大多数现实世界应用中都至关重要,但这并不容易;事实上,它需要一个具有高预测能力的稳健模型,可以捕捉长期依赖关系
在这里插入图片描述

图 1. (a) LSTF 可以覆盖比短序列预测更长的时间段,这对政策规划和投资保护至关重要。 (b) 现有方法的预测能力限制了 LSTF 的性能。 例如,从长度 = 48 开始,MSE 上升到不可接受的高水平,推理速度迅速下降
Transformer被认为是深度学习时代的革命性技术,它使预测更加可靠和准确。然而,Transformer 也存在一些问题,导致它们无法直接应用于长序列时间序列预测 (LSTF),例如二次时间复杂度、高内存使用率以及编码器-解码器架构的固有限制。这导致开发一种基于 Transformer 的高效模型,称为Informer。在本文中,我将详细展示此 Informer 所取得的进展。 ## Transformer

首先,让我对 Transformers 做一个总结,以防你不了解它。(对于那些熟悉 Transformers 的人,你可以跳过本节)

Transformer 是一种新兴的深度学习模型,其出现的频率正在不断上升。它们采用了自注意力机制,在 NLP 和计算机视觉等具有挑战性的任务中表现出了模型性能的显著提升。Transformer 架构可以分为两个部分,即编码器和解码器,如下图 :<ce

图 2. Transformer 架构

Transformer 的重点在于其不受局部性限制;也就是说,与其他流行模型(如 CNN)相比,Transformer 不受局部性限制。此外,我们没有在 Transformer 中提出任何 CNN 架构;相反,我们在 Transformer 中使用基于注意力机制的结构,这使我们能够获得更好的结果。

注意力机制架构可以概括为图 3:
在这里插入图片描述

图 3.(左)缩放点积注意力机制。(右)多头注意力机制由多个并行运行的注意力层组成
Scaled Dot-Product Attention 的函数为 Eq. 1

在这里插入图片描述

式1

Q(查询)、K(键)和V(向量)是我们注意力的输入。

有关 transformer 的完整基本实现,可以查阅相关论文。下面开始介绍informer

Informer 架构

ProbSparse自注意力机制:
在这个通知器中,我们不使用公式 1,而是使用公式 2,让每个键只关注u 个主要查询:
在这里插入图片描述

式2

在这里插入图片描述

式3
## Informer 架构

编码器:在内存使用限制下处理较长的序列输入

编码器的设计方式是提取长序列输入的鲁棒长程依赖关系。图 4 显示了编码器的示意架构:
在这里插入图片描述

图 4. Informer 编码器中的单个堆栈。(1)水平堆栈代表图 5 中的单个编码器副本。(2)所示的堆栈是接收整个输入序列的主堆栈。然后,第二个堆栈取输入的一半切片,后续堆栈重复(3)红色层是点积矩阵,它们通过在每一层上应用自注意力提取来实现级联减少。(4)将所有堆栈的特征图连接起来作为编码器的输出
``由于ProbSparse自注意力机制的存在,编码器的特征图上出现了额外的V值组合。蒸馏操作用于对具有主导特征的优秀组合进行评分,并在下一层构建集中的自注意力特征图。

从图4可以看出,该结构由多个Attention块、Conv1d和MaxPooling层组成,用于对输入数据进行编码。通过将输入分成两半来构建主堆栈的副本,​​可以提高蒸馏操作的可靠性。此外,自注意力蒸馏层的数量不断减少。在编码器的末端,研究人员连接了Feature Map,将编码器的输出引导至解码器

class ConvLayer(nn.Module):
    def __init__(self, c_in):
        super(ConvLayer, self).__init__()
        padding = 1 if torch.__version__>='1.5.0' else 2
        self.downConv = nn.Conv1d(in_channels=c_in,out_channels=c_in,kernel_size=3,padding=padding,padding_mode='circular')
        self.norm = nn.BatchNorm1d(c_in)
        self.activation = nn.ELU()
        self.maxPool = nn.MaxPool1d(kernel_size=3, stride=2, padding=1)

    def forward(self, x):
        x = self.downConv(x.permute(0, 2, 1))
        x = self.norm(x)
        x = self.activation(x)
        x = self.maxPool(x)
        x = x.transpose(1,2)
        return x

class EncoderLayer(nn.Module):
    def __init__(self, attention, d_model, d_ff=None, dropout=0.1, activation="relu"):
        super(EncoderLayer, self).__init__()d_ff = d_ff or 4*d_model
        self.attention = attention
        self.conv1 = nn.Conv1d(in_channels=d_model, out_channels=d_ff, kernel_size=1)
        self.conv2 = nn.Conv1d(in_channels=d_ff, out_channels=d_model, kernel_size=1)
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.dropout = nn.Dropout(dropout)
        self.activation = F.relu if activation == "relu" else F.gelu

    def forward(self, x, attn_mask=None):
        new_x, attn = self.attention(x, x, x,attn_mask = attn_mask)
        x = x + self.dropout(new_x)
        y = x = self.norm1(x)
        y = self.dropout(self.activation(self.conv1(y.transpose(-1,1))))
        y = self.dropout(self.conv2(y).transpose(-1,1))
        return self.norm2(x+y), attn

class Encoder(nn.Module):
    def __init__(self, attn_layers, conv_layers=None, norm_layer=None):
        super(Encoder, self).__init__()
        self.attn_layers = nn.ModuleList(attn_layers)
        self.conv_layers = nn.ModuleList(conv_layers) if conv_layers is not None else None
        self.norm = norm_layer

    def forward(self, x, attn_mask=None):
        # x [B, L, D]
        attns = []
        if self.conv_layers is not None:
            for attn_layer, conv_layer in zip(self.attn_layers, self.conv_layers):
                x, attn = attn_layer(x, attn_mask=attn_mask)
                x = conv_layer(x)
                attns.append(attn)
            x, attn = self.attn_layers[-1](x, attn_mask=attn_mask)
            attns.append(attn)
        else:
            for attn_layer in self.attn_layers:
                x, attn = attn_layer(x, attn_mask=attn_mask)
                attns.append(attn)
        if self.norm is not None:
            x = self.norm(x)
        return x, attns

class EncoderStack(nn.Module):
    def __init__(self, encoders, inp_lens):
        super(EncoderStack, self).__init__()
        self.encoders = nn.ModuleList(encoders)
        self.inp_lens = inp_lens

    def forward(self, x, attn_mask=None):
        # x [B, L, D]
        x_stack = []; attns = []
        for i_len, encoder in zip(self.inp_lens, self.encoders):
            inp_len = x.shape[1]//(2**i_len)
            x_s, attn = encoder(x[:, -inp_len:, :])
            x_stack.append(x_s); attns.append(attn)
        x_stack = torch.cat(x_stack, -2)
        
        return x_stack,attns

Informer 架构

解码器:通过一个前向过程生成长序列输出

解码器结构并不复杂;它是标准解码器结构。它包括两个相同的多头注意力层的堆栈。但是,生成推理的提出是为了缓解长预测中的速度下降,如图 5 所示:
在这里插入图片描述

图 5. Informer 模型概览。左图:编码器接收大量长序列输入(绿色系列)。我们用提出的ProbSparse注意力机制取代了规范的自注意力机制。蓝色梯形是自注意力提炼操作,用于提取主导注意力,从而大幅减小网络规模。层堆叠副本可提高鲁棒性。右图:解码器接收长序列输入,将目标元素填充为零,测量特征图的加权注意力组成,并立即以生成式预测输出元素(橙色系列)
解码器的馈送方式是通过获得以下方程(等式 4):

在这里插入图片描述

式4
我们不采用特定的标志作为标记,而是在输入序列中采样一个长度为 L(token) 的序列,就像输出序列之前的早期切片一样。
class DecoderLayer(nn.Module):
    def __init__(self, self_attention, cross_attention, d_model, d_ff=None,dropout=0.1, activation="relu"):
        super(DecoderLayer, self).__init__()
        d_ff = d_ff or 4*d_model
        self.self_attention = self_attention
        self.cross_attention = cross_attention
        self.conv1 = nn.Conv1d(in_channels=d_model, out_channels=d_ff, kernel_size=1)
        self.conv2 = nn.Conv1d(in_channels=d_ff, out_channels=d_model, kernel_size=1)
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.norm3 = nn.LayerNorm(d_model)
        self.dropout = nn.Dropout(dropout)
        self.activation = F.relu if activation == "relu" else F.gelu

    def forward(self, x, cross, x_mask=None, cross_mask=None):
        x = x + self.dropout(self.self_attention(x, x, x,attn_mask=x_mask)[0])
        x = self.norm1(x)
        x = x + self.dropout(self.cross_attention(x, cross, cross,attn_mask=cross_mask)[0])
        
        y = x = self.norm2(x)
        y = self.dropout(self.activation(self.conv1(y.transpose(-1,1))))
        y = self.dropout(self.conv2(y).transpose(-1,1))
        return self.norm3(x+y)

class Decoder(nn.Module):
    def __init__(self, layers, norm_layer=None):
        super(Decoder, self).__init__()
        self.layers = nn.ModuleList(layers)
        self.norm = norm_layer
    def forward(self, x, cross, x_mask=None, cross_mask=None):
        for layer in self.layers:
            x = layer(x, cross, x_mask=x_mask, cross_mask=cross_mask)
        if self.norm is not None:
            x = self.norm(x)
        return x

接下来是代码调试过程

主要就是安装环境,数据集,如果数据集不是用项目提供的数据集,可能还要经过一些处理,最好是处理成跟提供的数据集类似的,这样是最快的,当然也可以改代码来适应自己的数据集
还有就是当自己的数据集出现效果不好,指标差的情况,可以调整参数,多次训练。可以改变三个重要的长度参数:延长输入长度(48、96、168、240、336、480、624、720)、编码器输入长度(78、96、168、240、480、624、720)和编码器输入长度(96、168、240、336、480、720)
还有就是学习率和batch_size的调整。

运行方法

首先使用git命名将项目下载到本地
命令为git clone:
git clone https://github.com/zhouhaoyi/Informer2020.git
后面这个连接地址取得的方法:搜索Informer2020,点code,复制出现的链接,右边有复制按钮
然后cd Informer2020, cd是进入该目录,使用git clone命令会将项目下载到 Informer2020目录。
接下来需要创建虚拟环境,我使用的是conda来创建虚拟环境,命令为:
conda create -n informer python=3.8,然后输入y,虚拟环境即可创建完成。
infomer可以进行更改,是该虚拟环境的名称
然后激活该环境:conda activate informer
接下来要安装依赖,可以使用命令pip install -r requirements.txt,等待安装完成即可
在搭建好环境后,需要下载数据集,也可以使用自己的数据集,不过可能需要更改一些代码。
原文使用的数据集为ETT数据集,下载了数据集后,新建一个datasets目录,复制到该目录。
然后可以用vscode打开Informer2020目录,使用以下命令运行该项目:

# ETTh1
python -u main_informer.py --model informer --data ETTh1 --attn prob --freq h

# ETTh2
python -u main_informer.py --model informer --data ETTh2 --attn prob --freq h

# ETTm1
python -u main_informer.py --model informer --data ETTm1 --attn prob --freq t

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1950824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

做短视频素材哪里找?去哪里下载?自媒体下载素材网站分享

自媒体视频创作&#xff1a;高质量素材网站大公开&#xff01; 大家好&#xff0c;我是一名热情的短视频创作者。今天&#xff0c;我要与大家分享一些寻找优质视频素材的秘诀。无论是新手还是老手&#xff0c;这些建议都能帮助你的视频在众多平台中脱颖而出&#xff0c;吸引更…

系统移植(四)u-boot移植 ② basic版本

文章目录 一、u-boot移植&#xff08;一&#xff09;生成u-boot源码1. 配置交叉编译器&#xff0c;修改u-boot源码目录下的MAKEFILE文件4. 执行make <board_name>_defconfig命令&#xff0c;配置u-boot源码5. make menuconfig---图形化界面配置6. 根据DK1板子的设备树文件…

ISP 代理提供商:互联网安全的关键参与者

简介&#xff1a;互联网安全的演变态势 互联网改变了我们互动、工作和开展业务的方式&#xff0c;但也带来了与安全性和可访问性相关的重大挑战。在这个数字时代&#xff0c;互联网服务提供商 (ISP) 代理提供商在解决这些问题方面发挥着关键作用。他们提供的基本服务不仅可以增…

PDF解锁网站

https://smallpdf.com/cn/unlock-pdfhttps://smallpdf.com/cn/unlock-pdfhttps://www.freemypdf.comhttps://www.freemypdf.com

LVGL使用上一个不方便的问题记录

slider这个控件&#xff0c;应该画在蓝色框的里面&#xff0c;源码实现将中心画在蓝色框上&#xff0c;导致总会有两边超出的情况出现&#xff0c;真想修改源码&#xff0c;作者不知道咋想的&#xff1f;&#xff1f;&#xff1f;

vue3 Router 点击index中的按钮,查看相应的详情信息,并且传递id,及其路由的定义方法。

1、路由的定义 结构如下: 2、路由定义代码&#xff1a; {path: tabs,name: TabsDemo,component: () > import(/views/demo/feat/tabs/index.vue),meta: {title: t(routes.demo.feat.tabs),hideChildrenInMenu: true,},children: [{path: detail/:id,name: TabDetail,compon…

封装和桥接Unity 协程体系

简介 协程&#xff08;Coroutine&#xff09;在C#中是一种特殊的函数&#xff0c;它允许开发者编写可以暂停执行并在未来某个时刻恢复执行的代码块。协程通常用于实现异步操作&#xff0c;如延时执行、等待某个事件发生、或者分段执行复杂的任务。在Unity游戏引擎中&#xff0c…

Cuda编程模型中常见的错误检测方法

Cuda编程模型中常见的错误检测方法 1 CUDA错误检测简介2 直接嵌入检测函数2.1 检测函数介绍2.2 使用示例 3 封装在.cuh头文件中嵌入3.1 创建 error.cuh 头文件3.2 在 CUDA 程序中包含 error.cuh 并调用 CHECK 宏3.3 使用示例 1 CUDA错误检测简介 CUDA编程模型中的错误检测是确…

【C++】选择结构案例-三只小猪称体重

案例问题 假设有三只小猪A、B、C&#xff0c;在输入三者体重后希望能输出他们各自的体重并测出谁最重 思路 先让A与B相比较&#xff0c;如果A重&#xff0c;则让A和C相比较&#xff0c;如果A重则输出A最重&#xff0c;否则输出C最重 在最开始的条件&#xff08;AB相比较&am…

JQuery简单实现ul li点击菜单项被选中的菜单项保持高亮状态(导航ul li点击切换样式)

效果&#xff1a; JS&#xff1a; $(function () {//遍历list&#xff08;一般为ul li&#xff09;$("#menu a").each(function () {//给当前项添加点击事件&#xff08;点击后切换样式&#xff09;$(this).bind(click,function () {// 移除其他所有项的active类$(&…

Sokit(TCP/UDP调试工具)

下载&#xff1a;http://www.winwin7.com/soft/56522.html#xiazai Sokit中文版是一款免费开源的TCP / UDP 测试&#xff08;调试&#xff09;工具&#xff0c;它主要可以用于接收和发送TCP/UDP数据包&#xff0c;让你更深的了解网络状况&#xff0c;能够有效地接收、发送、转…

Linux中的进程1

进程的概念 程序&#xff1a;二进制文件 进程&#xff1a;启动的程序 所有的数据都在内存中 需要占据更多的系统资源 cpu&#xff0c;物理内存&#xff08;RAM&#xff09; 并行和并发 并发&#xff1a;在操作系统中&#xff0c;是指一个时间段中有几个程序都处于已启动…

干货讲解 | 在线教育行业如何搭建帮助中心

引言 随着互联网技术的飞速发展&#xff0c;在线教育已成为教育领域不可或缺的一部分&#xff0c;它打破了传统教育的时空限制&#xff0c;让知识传播更加高效、便捷。然而&#xff0c;在享受在线教育带来的便利时&#xff0c;用户也面临着操作复杂、功能理解不透彻、遇到问题…

Java语言程序设计——篇七(2)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 封装性与多态 封装性与访问修饰符类的访问权限类成员的访问权限 &#x1f320;防止类扩展和方法覆盖实战演练 抽象类实战演练 对象转换实战演练…

github的Codespaces是什么

目录 github的Codespaces是什么 一、定义与功能 二、特点与优势 三、工作原理 四、使用场景与限制 github的Codespaces是什么 GitHub的Codespaces是一个基于云的即时开发环境,它利用容器技术为开发者提供一个完全配置好的开发环境,以便他们能够直接在浏览器或通过Visua…

《中国数据库前世今生》观影——认识1980年起步阶段

引出 中国数据库的前世今生观影——认识1980年的起步阶段 20 世纪 60 年代国外就有了商业数据库&#xff0c;20 世纪 80 年代我国才有了第一批数据库专业人才。不要小看这 20 年的差距&#xff0c;它可能需要几代数据库人用一生去追。2024 年了&#xff0c;中国跨过数据库这座大…

【Android】Fragment的数据传递

碎片和活动之间的通信 Activity向Fragment 通过方法传递 构造方法 将碎片动态地加载到活动当中&#xff0c;先得到一个碎片&#xff0c;再将其放到活动当中。就想到碎片的替代方法&#xff0c;将我们所要传输的数据直接放到新创建的碎片里面&#xff0c;替换到原来的碎片。…

【C++】C++应用案例-大整数相加

实际应用中&#xff0c;有时会遇到非常大的整数&#xff0c;可能会超过long、甚至long long的范围。这时就需要用不限长度的字符串保存数据&#xff0c;然后进行计算。 最简单的需求就是“大整数相加”&#xff0c;即给定两个字符串形式的非负大整数 num1 和num2 &#xff0c;计…

深入理解SQL中的INNER JOIN操作

本文介绍了INNER JOIN的定义、使用场景、计算方法及与其他JOIN的比较。INNER JOIN是关系数据库中常用的操作&#xff0c;用于返回两个表中匹配的行&#xff0c;只有在连接条件满足时才返回数据。本文详细解释了INNER JOIN的语法及其在一对多、多对多关系中的应用&#xff0c;通…

【YOLOv5/v7改进系列】引入中心化特征金字塔的EVC模块

一、导言 现有的特征金字塔方法过于关注层间特征交互而忽视了层内特征的调控。尽管有些方法尝试通过注意力机制或视觉变换器来学习紧凑的层内特征表示&#xff0c;但这些方法往往忽略了对密集预测任务非常重要的被忽视的角落区域。 为了解决这个问题&#xff0c;作者提出了CF…