时间序列(Time-Series)Crossformer_EncDec.py代码解析

import torch
import torch.nn as nn
from einops import rearrange, repeat
from layers.SelfAttention_Family import TwoStageAttentionLayer

#用于合并时间序列的不同片段
class SegMerging(nn.Module):
    #初始化方法,参数包含模型维度d_model、窗口大小win_size、以及正则化层默认为LayerNorm
    def __init__(self, d_model, win_size, norm_layer=nn.LayerNorm):
        super().__init__() #调用父类的构造方法进行初始化
        self.d_model = d_model
        self.win_size = win_size
        #定义线性变换层,将合并后的窗口重新投影到原始维度空间
        self.linear_trans = nn.Linear(win_size * d_model, d_model)
        #定义正则化层,标准化输入数据
        self.norm = norm_layer(win_size * d_model)
    #
    def forward(self, x):
        #从输入数据的形状中提取批次大小、时间步长、段数和模型维度
        batch_size, ts_d, seg_num, d_model = x.shape
        #计算需要填充的段数以保证窗口大小
        pad_num = seg_num % self.win_size
        #如果需要填充,则在时间序列的末尾复制最后几个段以进行填充
        if pad_num != 0:
            pad_num = self.win_size - pad_num
            x = torch.cat((x, x[:, :, -pad_num:, :]), dim=-2)
        #以窗口为步长,从每个窗口开始选取片段,并将其添加在seg_to_merge
        seg_to_merge = []
        for i in range(self.win_size):
            seg_to_merge.append(x[:, :, i::self.win_size, :])
        #将列表中的所有片段按最后一个维度(特征维度)拼接
        x = torch.cat(seg_to_merge, -1)
        #对合并后的数据进行正则化
        x = self.norm(x)
        #通过线性变换将数据投影回原来的特征维度
        x = self.linear_trans(x)

        return x

#处理不同尺度时间序列的模块
class scale_block(nn.Module):
    #初始化方法,参数包括模型的配置configs,窗口大小win_size,模型维度d_model,注意力头数n_heads,前馈网络的维度d_ff,模块的深度depth,dropout率,段数seg_num以及一个因子factor。
    def __init__(self, configs, win_size, d_model, n_heads, d_ff, depth, dropout, \
                 seg_num=10, factor=10):
        #调用父类的构造方法进行初始化
        super(scale_block, self).__init__()
        #如果窗口大小大于1,则创建一个合并层,否则设置为None。
        if win_size > 1:
            self.merge_layer = SegMerging(d_model, win_size, nn.LayerNorm)
        else:
            self.merge_layer = None
        #创建模块列表以存储编码层。
        self.encode_layers = nn.ModuleList()
        #向模块列表中添加depth数量的TwoStageAttentionLayer,这是一个包含两阶段注意力机制的层。
        for i in range(depth):
            self.encode_layers.append(TwoStageAttentionLayer(configs, seg_num, factor, d_model, n_heads, \
                                                             d_ff, dropout))
    #定义前向传播方法,接收输入x和额外的参数。
    def forward(self, x, attn_mask=None, tau=None, delta=None):
        #从输入数据的形状中提取时间步长维度。
        _, ts_dim, _, _ = x.shape
        #如果存在合并层,则将输入数据通过合并层。
        if self.merge_layer is not None:
            x = self.merge_layer(x)
        #将数据通过所有编码层。
        for layer in self.encode_layers:
            x = layer(x)

        return x, None

#编码器类
class Encoder(nn.Module):
    #初始化方法,参数为注意力层列表
    def __init__(self, attn_layers):
        #调用父类的构造方法进行初始化
        super(Encoder, self).__init__()
        #将传入的注意力层参数转换为模块列表
        self.encode_blocks = nn.ModuleList(attn_layers)
    #定义前向传播方法
    def forward(self, x):
        #创建列表并添加原始输入x
        encode_x = []
        encode_x.append(x)
        #通过所有编码块迭代,并将每个块的输出添加到列表中。
        for block in self.encode_blocks:
            x, attns = block(x)
            encode_x.append(x)

        return encode_x, None

#解码器层类
class DecoderLayer(nn.Module):
    #初始化方法接收自注意力和交叉注意力层,段长度seg_len,模型维度d_model,可选的前馈网络维度d_ff,以及dropout率。
    def __init__(self, self_attention, cross_attention, seg_len, d_model, d_ff=None, dropout=0.1):
        #调用父类的构造方法进行初始化。
        super(DecoderLayer, self).__init__()
        #存储自注意力和交叉注意力机制。
        self.self_attention = self_attention
        self.cross_attention = cross_attention
        #定义两个正则化层,用于标准化数据
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        #定义dropout层
        self.dropout = nn.Dropout(dropout)
        #创建一个简单的多层感知器(MLP)结构,其中包含GELU激活函数
        self.MLP1 = nn.Sequential(nn.Linear(d_model, d_model),
                                  nn.GELU(),
                                  nn.Linear(d_model, d_model))
        #线性预测层,用于将解码器输出映射到段长度。
        self.linear_pred = nn.Linear(d_model, seg_len)
    #定义前向传播方法
    def forward(self, x, cross):
        #获取批次大小
        batch = x.shape[0]
        #将数据通过自注意力层
        x = self.self_attention(x)
        #使用rearrange函数重组数据以匹配交叉注意力层的期望输入格式
        x = rearrange(x, 'b ts_d out_seg_num d_model -> (b ts_d) out_seg_num d_model')

        #将交叉编码数据也重组以匹配期望的格式
        cross = rearrange(cross, 'b ts_d in_seg_num d_model -> (b ts_d) in_seg_num d_model')
        #通过交叉注意力层,输入是重组后的数据和交叉编码数据
        tmp, attn = self.cross_attention(x, cross, cross, None, None, None,)
        #将注意力层的输出加到输入上,并应用dropout
        x = x + self.dropout(tmp)
        #应用第一个正则化层,并将结果保存在y中。
        y = x = self.norm1(x)
        #将y通过多层感知器。
        y = self.MLP1(y)
        #将MLP的输出与x相加,并应用第二个正则化层。
        dec_output = self.norm2(x + y)
        
        #重新解码输出以恢复原始批次维度。
        dec_output = rearrange(dec_output, '(b ts_d) seg_dec_num d_model -> b ts_d seg_dec_num d_model', b=batch)
        #通过线性预测层生成解码层的预测
        layer_predict = self.linear_pred(dec_output)
        #重新预测输出以匹配期望的输出格式
        layer_predict = rearrange(layer_predict, 'b out_d seg_num seg_len -> b (out_d seg_num) seg_len')

        return dec_output, layer_predict

#解码器类
class Decoder(nn.Module):
    #初始化方法,参数为解码器层列表
    def __init__(self, layers):
        #调用父类的构造方法进行初始化
        super(Decoder, self).__init__()
        #将解码器层转换为模块列表
        self.decode_layers = nn.ModuleList(layers)

    #定义前向传播方法,接收输入x和编码器的输出cross
    def forward(self, x, cross):
        #初始化最终预测为None
        final_predict = None
        i = 0
        #从输入数据的形状中提取时间步长维度
        ts_d = x.shape[1]
        #迭代所有解码器层
        for layer in self.decode_layers:
            #获取当前对应的编码器输出
            cross_enc = cross[i]
            #将数据通过解码器层
            x, layer_predict = layer(x, cross_enc)
            #如果是第一次迭代,将最终预测设置为该层预测,否则将该层预测累加到最终预测上
            if final_predict is None:
                final_predict = layer_predict
            else:
                final_predict = final_predict + layer_predict
            i += 1
        #重新安排最终预测的形状以匹配期望的输出格式
        final_predict = rearrange(final_predict, 'b (out_d seg_num) seg_len -> b (seg_num seg_len) out_d', out_d=ts_d)

        return final_predict
 

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

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

相关文章

GO——recover

定义 panic 改变程序控制流立即停止当前函数剩余代码,调用defer 只会执行当前协程的defer recover 可以终止panic造成的程序崩溃只能在defer中发挥作用 package mainimport ("fmt""time" )func main() {defer func() {fmt.Println("ma…

excel中多行合并后调整行高并打印

首先参考该文,调整全文的行高。 几个小技巧: 1.转换成pdf查看文件格式 2.通过视图--》分页预览,来确定每页的内容(此时页码会以水印的形式显示) 3. 页面布局中的,宽度可以选为自动,因为已经是…

算法工程师的工作:算法范围与技巧

算法工程师,作为计算机科学领域中的核心角色,负责设计和开发高效、可靠的算法。他们的工作涉及广泛的应用领域,从数据结构、机器学习到人工智能等。本文将探讨算法工程师的工作中涉及的算法范围,以及他们所掌握的关键技巧。 一、…

Linux——系统简介

1、从UNIX到LINUX 在目前主流的服务器端操作系统中,UNIX诞生于20世纪60年代末,Windows诞生于20世纪80年代中期,Linux诞生于20世纪90年代初,可以说UNIX是操作系统中的“老大哥”。 1.1、Linux简史 Linux内核最初是由李纳斯托瓦兹…

[TII 2023] 基于压缩感知的多级隐私保护方案

Multilevel Privacy Preservation Scheme Based on Compressed Sensing | IEEE Journals & Magazine | IEEE Xplore 摘要 物联网的广泛应用在给人们带来便利的同时,也引发了人们对数据采集、分析和共享过程中隐私泄露的担忧。本文提出了一种基于压缩感知的多级…

Cesium数据加载

文章目录 0.引言1.影像加载1.1Bing地图1.2天地图1.3ArcGIS在线地图1.4高德地图1.5OSM影像1.6MapBox影像 2.OGC地图服务2.1WMS2.2WMTS2.3TMS 3.GeoJSON数据加载4.KML数据加载5.TIFF数据加载6.点云数据加载7.地形数据加载7.1在线地形数据加载7.2本地地形数据加载 8.倾斜摄影模型数…

[BT]小迪安全2023学习笔记(第15天:PHP开发-登录验证)

第15天 名词解释 Cookie 是小型的文本文件,由网站发送到用户的浏览器,并存储在用户的设备上。Cookie 通常用于存储识别用户的信息,例如用户偏好、登录状态等。每当用户再次访问同一网站时,浏览器会将 Cookie 发送回服务器&#…

10 个值得分享给你前端低代码项目

今天来分享 10 个优秀的前端低代码项目!企业级低代码快速开发平台,包含页面可视化配置、自定义表单、自定义报表、权限管理脚手架应用、前后端代码自动生成;主要特点是低代码开发,可实现复杂CRUD功能仅编写数据模型就能完成前后端…

unity代码创建animationclip,并对指定帧进行像素偏移

这段代码使用菜单按钮的方式,在Unity编辑器中创建AnimationClip,并对每一帧进行像素偏移。在Unity编辑器中,在Project面板中选择一个纹理,然后通过右键菜单选择Assets > Create > AnimationClip With Pixel Offset&#xff…

在CSS中如何寻找第一个元素

ul li:first-child {color: red; } 在CSS中,要找到第一个元素,可以使用:first-child选择器。该选择器可以用于选择父元素下的第一个子元素。例如,要选择一个ul元素下的第一个li元素,可以使用下面的代码: 上面的代码将…

扫雷游戏 bevy 实践(bevy 0.12)-1

经典的扫雷游戏 bevy 实践(bevy 0.12) 网上大多是0.6的 但愿大家能够摸索着 上手 参考资料: Bevy Minesweeper: Introduction - DEV Community (原始教程,0.6版本) https://github.com/leonidv/bevy-m…

在线教育App、H5、微信小程序项目

大型多端项目,uni-app开发 一、首页 二、课程页 以点击购买,购买后可以看到课程内容 种课程音频、视频等,以及专栏,都可以购买后观看 三、电子书 订阅成功后,就可以观看电子书了 选择章节 直播模块: 订阅…

云服务ECS扩容示例

原文可参考:【在Linux操作系统内扩容分区和文件系统_云服务器 ECS(ECS)-阿里云帮助中心】 示例1:扩容MBR分区和ext4文件系统 设备名:/dev/vda(系统盘)1个分区:/dev/vda1文件系统类型:ext4操作…

Linux 一键部署influxd2-telegraf 二进制方式

influxd2前言 influxd2 是 InfluxDB 2.x 版本的后台进程,是一个开源的时序数据库平台,用于存储、查询和可视化时间序列数据。它提供了一个强大的查询语言和 API,可以快速而轻松地处理大量的高性能时序数据。 telegraf 是一个开源的代理程序,它可以收集、处理和传输各种不…

零基础学习数学建模——(四)备战美赛

本篇博客将讲解如何备战美赛。 什么是美赛 美赛,全称是美国大学生数学建模竞赛(MCM/ICM),由美国数学及其应用联合会主办,是最高的国际性数学建模竞赛,也是世界范围内最具影响力的数学建模竞赛。 赛题内容…

CuteHttpFileServer

需求 最近行政同时需要做文件共享,使用windows上的文件共享有些问题,ftp也是有问题,同时需要身份验证功能,找了很久,发现CuteHttpFileServer 这个文件服务器,可以解决这个需求,中间过程中也写过…

生产问题复盘!Swap对GC的影响

Swap 1. 什么是Swap swap 是把一块磁盘空间或者一个本地文件当做内存来使用。可用内存无法满足内存分配请求的时候,把不常用的内存数据存储到磁盘,并在内存中释放这部分内存。当进程再次访问这部分内存的时候,再读取到内存中来。 2. 为什么…

使用Gin框架,快速开发高效的Go Web应用程序

推荐 海鲸AI-GPT4.0国内站点:https://www.atalk-ai.com 前言 在当今的软件开发领域,Go语言以其简洁的语法和出色的性能逐渐成为开发者们的新宠。而Gin框架,则是Go语言中最受欢迎的Web框架之一,它以高性能和易用性著称。本文将带你…

前端常用的时间格式处理

import { fillZero } from /utils/utils export const shortcuts [[最近一周, 7],[最近一个月, 30],[最近三个月, 90],[最近半年, 180],[最近一年, 365] ]/*** dateParams 获取时间对象 * param {Number} value 时间戳*/ export const dateParams (value) > {const …

详讲api网关之kong的基本概念及安装和使用(一)

什么是api网关 前面我们聊过sentinel,用来限流熔断和降级,如果你只有一个服务,用sentinel自然没有问题,但是如果是有多个服务,特别是微服务的兴起,那么每个服务都使用sentinel就给系统维护带来麻烦。那么网…