当前位置: 首页 > news >正文

【预测】-双注意LSTM自动编码器记录

预测-双注意LSTM自动编码器

  • 1 预测-双注意LSTM自动编码器
    • 1.1 复现环境配置
    • 1.2 数据流记录
      • 1.2.1 **构建Dataset**
        • (1) **`X` 的取数**
        • (2) **`y` 的取数**
        • (3) **`target` 的取数**
      • 1.2.2 **举例说明**
        • (1)**`X` 的取数**
        • (2)**`y` 的取数**
        • (3)**`target` 的取数**
      • 1.2.3 **`y` 取数的问题**
      • **修正后的代码**
      • 1.2.4 **总结**
      • 1.2.5 数据流总结:
      • 1.2.6 数据流图示:
      • 1.2.7 参考:
  • 2 数据维度变化流程
    • 2.1 流程图
    • 2.2 总结

1 预测-双注意LSTM自动编码器

复现github链接:https://github.com/JulesBelveze/time-series-autoencoder.git
论文:A Dual-Stage Attention-Based Recurrent Neural Network for Time Series Prediction:https://arxiv.org/abs/1704.02971

1.1 复现环境配置

python版本:python3.8.20
cuda版本:cuda111
包版本环境参考:

Package              Version      Editable project location
-------------------- ------------ ---------------------------
build                1.2.2.post1
CacheControl         0.14.2
certifi              2025.1.31
charset-normalizer   3.4.1
cleo                 2.1.0
colorama             0.4.6
contourpy            1.1.1
crashtest            0.4.1
cycler               0.10.0
distlib              0.3.9
dulwich              0.21.7
fastjsonschema       2.21.1
filelock             3.16.1
fonttools            4.56.0
future               0.18.2
idna                 3.10
importlib_metadata   8.5.0
importlib_resources  6.4.5
installer            0.7.0
jaraco.classes       3.4.0
joblib               0.15.1
keyring              24.3.1
kiwisolver           1.2.0
matplotlib           3.2.1
more-itertools       10.5.0
msgpack              1.1.0
numpy                1.21.0
packaging            24.2
pandas               1.1.5
pexpect              4.9.0
pillow               10.4.0
pip                  24.3.1
pkginfo              1.12.1.2
platformdirs         4.3.6
poetry               1.8.5
poetry-core          1.9.1
poetry-plugin-export 1.8.0
protobuf             5.29.3
ptyprocess           0.7.0
pyparsing            2.4.7
pyproject_hooks      1.2.0
python-dateutil      2.8.1
pytz                 2025.1
pywin32-ctypes       0.2.3
rapidfuzz            3.9.7
requests             2.32.3
requests-toolbelt    1.0.0
scikit-learn         0.23.1
scipy                1.4.1
setuptools           75.3.0
shellingham          1.5.4
six                  1.15.0
sklearn              0.0
tensorboardX         2.6.2.2
threadpoolctl        2.1.0
tomli                2.2.1
tomlkit              0.13.2
torch                1.9.1+cu111
torchaudio           0.9.1
torchvision          0.10.1+cu111
tqdm                 4.46.1
trove-classifiers    2025.2.18.16
tsa                  0.1.0        D:\temp\Pytorch双注意LSTM自动编码器
typing_extensions    4.12.2
urllib3              2.2.3
virtualenv           20.29.2
wheel                0.45.1
zipp                 3.20.2

注:

vscode配置:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Debugger: Current File with Arguments",
            "type": "debugpy",
            "request": "launch",
            "program": "${file}",
            "cwd":"${fileDirname}",
            "console": "integratedTerminal",
            // "args": [
            //     "--ckpt", "output/checkpoint-5000.ckpt"  // 添加 --ckpt 参数及其值
            // ]
        }
    ]
}

1.2 数据流记录

源代码所用数据字段:

| 列名          | 含义               | 单位     |
| ------------- | ------------------ | -------- |
| Date_Time     | 日期和时间         | -        |
| CO(GT)        | 一氧化碳浓度       | mg/m³    |
| PT08.S1(CO)   | 一氧化碳传感器响应值 | 无量纲  |
| NMHC(GT)      | 非甲烷烃浓度       | µg/m³   |
| C6H6(GT)      | 苯浓度             | µg/m³   |
| PT08.S2(NMHC) | 非甲烷烃传感器响应值 | 无量纲 |
| NOx(GT)       | 氮氧化物浓度       | µg/m³   |
| PT08.S3(NOx)  | 氮氧化物传感器响应值 | 无量纲 |
| NO2(GT)       | 二氧化氮浓度       | µg/m³   |
| PT08.S4(NO2)  | 二氧化氮传感器响应值 | 无量纲 |
| PT08.S5(O3)   | 臭氧传感器响应值    | 无量纲  |
| T             | 温度               | °C      |
| RH            | 相对湿度           | %       |
| AH            | 绝对湿度           | g/m³    |

将时间序列数据转换为适合时间序列预测的格式,具体来说,它通过滑动窗口的方式从输入数据 X 和标签 y 中提取特征和标签,并生成一个 TensorDataset。提取特征和标签,预测的是后面的预测窗口长度的标签。下面我将详细解释 Xytarget 的取数逻辑,并指出 y 取数可能存在的问题。


1.2.1 构建Dataset

(1) X 的取数
  • X 是输入特征数据,形状为 (nb_obs, nb_features),其中 nb_obs 是样本数量,nb_features 是特征数量。
  • 通过滑动窗口的方式,从 X 中提取长度为 seq_length 的序列:
    features.append(torch.FloatTensor(X[i:i + self.seq_length, :]).unsqueeze(0))
    
    • 例如,如果 seq_length = 10,则每次提取 X[i:i+10, :],即从第 i 个时间步开始的 10 个时间步的特征数据。
    • unsqueeze(0) 是为了增加一个批次维度。
(2) y 的取数
  • y 是目标值(标签),通常是与 X 对应的输出值。
  • 代码中从 y 中提取的是滞后一期的历史值(y[i-1:i+self.seq_length-1]):
    y_hist.append(torch.FloatTensor(y[i - 1:i + self.seq_length - 1]).unsqueeze(0))
    
    • 例如,如果 seq_length = 10,则提取的是 y[i-1:i+9],即从第 i-1 个时间步开始的 10 个时间步的标签值。
    • 这里 y[i-1] 的使用可能有问题,因为 y[i-1] 是前一个时间步的值,而不是当前时间步的值。如果 y 是当前时间步的标签,那么这里应该直接使用 y[i:i+self.seq_length]
(3) target 的取数
  • target 是预测的目标值,即未来 prediction_window 个时间步的标签值:
    target.append(torch.FloatTensor(y[i + self.seq_length:i + self.seq_length + self.prediction_window]))
    
    • 例如,如果 seq_length = 10prediction_window = 5,则提取的是 y[i+10:i+15],即从第 i+10 个时间步开始的 5 个时间步的标签值。

1.2.2 举例说明

假设有以下数据:

  • Xy 的长度为 20。
  • seq_length = 3prediction_window = 2
(1)X 的取数
  • i = 1 时,提取 X[1:4, :]
  • i = 2 时,提取 X[2:5, :]
  • 以此类推。
(2)y 的取数
  • i = 1 时,提取 y[0:3](即 y[i-1:i+seq_length-1])。
  • i = 2 时,提取 y[1:4]
  • 以此类推。
(3)target 的取数
  • i = 1 时,提取 y[4:6](即 y[i+seq_length:i+seq_length+prediction_window])。
  • i = 2 时,提取 y[5:7]
  • 以此类推。

1.2.3 y 取数的问题

在代码中,y 的取数逻辑是:

y_hist.append(torch.FloatTensor(y[i - 1:i + self.seq_length - 1]).unsqueeze(0))

这里使用了 y[i-1],即前一个时间步的值。如果 y 是当前时间步的标签,那么这里应该直接使用 y[i:i+self.seq_length],而不是 y[i-1:i+self.seq_length-1]。修正后的代码应该是:

y_hist.append(torch.FloatTensor(y[i:i + self.seq_length]).unsqueeze(0))

修正后的代码

def frame_series(self, X, y=None):
    '''
    Function used to prepare the data for time series prediction
    :param X: set of features
    :param y: targeted value to predict
    :return: TensorDataset
    '''
    nb_obs, nb_features = X.shape
    features, target, y_hist = [], [], []

    for i in range(1, nb_obs - self.seq_length - self.prediction_window):
        features.append(torch.FloatTensor(X[i:i + self.seq_length, :]).unsqueeze(0))
        # 修正后的 y 取数逻辑
        y_hist.append(torch.FloatTensor(y[i:i + self.seq_length]).unsqueeze(0))

    features_var, y_hist_var = torch.cat(features), torch.cat(y_hist)

    if y is not None:
        for i in range(1, nb_obs - self.seq_length - self.prediction_window):
            target.append(
                torch.FloatTensor(y[i + self.seq_length:i + self.seq_length + self.prediction_window]))
        target_var = torch.cat(target)
        return TensorDataset(features_var, y_hist_var, target_var)

    return TensorDataset(features_var)

1.2.4 总结

  • X 的取数是滑动窗口提取特征序列。
  • y 的取数逻辑存在问题,不应使用 y[i-1],而应直接使用 y[i:i+self.seq_length]
  • target 的取数是提取未来 prediction_window 个时间步的标签值。

这段代码的数据流可以分为以下几个步骤:

  1. 数据预处理

    • 调用 self.preprocess_data() 方法,生成训练集和测试集的特征和标签:X_train, X_test, y_train, y_test
    • X_train 中获取特征的数量 nb_features
  2. 数据集封装

    • 调用 self.frame_series(X_train, y_train) 方法,将训练集的特征和标签封装成一个 train_dataset 对象。
    • 调用 self.frame_series(X_test, y_test) 方法,将测试集的特征和标签封装成一个 test_dataset 对象。
  3. DataLoader 创建

    • 使用 DataLoader 类创建 train_iter,用于加载训练数据集。参数包括 batch_size(批次大小)、shuffle=False(不打乱数据)、drop_last=True(丢弃最后一个不完整的批次)。
    • 使用 DataLoader 类创建 test_iter,用于加载测试数据集。参数与 train_iter 相同。
  4. 返回结果

    • 返回 train_iter(训练数据加载器)、test_iter(测试数据加载器)和 nb_features(特征数量)。

1.2.5 数据流总结:

  • 输入:原始数据通过 self.preprocess_data() 进行预处理,生成特征和标签。
  • 处理:特征和标签被封装成 Dataset 对象,然后通过 DataLoader 进行批次加载。
  • 输出:返回训练和测试的 DataLoader 对象,以及特征数量。

1.2.6 数据流图示:

原始数据 → preprocess_data() → (X_train, X_test, y_train, y_test) → frame_series() → (train_dataset, test_dataset) → DataLoader() → (train_iter, test_iter)

1.2.7 参考:

  • DataLoader 是 PyTorch 中用于批量加载数据的工具,支持多线程加载、数据打乱等功能。
  • Dataset 是 PyTorch 中用于封装数据集的基类,通常需要实现 __len____getitem__ 方法。

为了更好地理解数据维度的变化情况,我们可以通过一个具体的例子来逐步分析代码中的数据维度变化。假设我们有一个时间序列数据集,包含以下列:

  • date: 时间戳
  • feature1: 数值特征
  • feature2: 数值特征
  • category: 类别特征
  • target: 目标值

2 数据维度变化流程

  1. 原始数据 (data):

    • 假设数据集有 1000 行,5 列(date, feature1, feature2, category, target)。
    • 维度:(1000, 5)
  2. 预处理 (preprocess_data):

    • X = data.drop('target', axis=1):去掉目标列,剩下 4 列。
      • 维度:(1000, 4)
    • y = data['target']:目标列。
      • 维度:(1000,)
    • X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, shuffle=False)
      • X_train 维度:(800, 4)
      • X_test 维度:(200, 4)
      • y_train 维度:(800,)
      • y_test 维度:(200,)
    • X_train = preprocessor.fit_transform(X_train):经过 ColumnTransformer 处理,假设 category 列被编码为 3 个新列。
      • 维度:(800, 5)feature1, feature2, category_encoded_1, category_encoded_2, category_encoded_3
    • X_test = preprocessor.transform(X_test)
      • 维度:(200, 5)
  3. 时间序列帧化 (frame_series):

    • 假设 seq_length = 10prediction_window = 1
    • nb_obs, nb_features = X_train.shape
      • nb_obs = 800, nb_features = 5
    • featuresy_hist 的生成:
      • 对于 i 从 1 到 800 - 10 - 1 = 789,每次取 10 个时间步的数据。
      • features 维度:(789, 10, 5)
      • y_hist 维度:(789, 10)
    • target 的生成:
      • 对于 i 从 1 到 789,每次取 1 个时间步的目标值。
      • target 维度:(789, 1)
    • TensorDataset 的生成:
      • features_var 维度:(789, 10, 5)
      • y_hist_var 维度:(789, 10)
      • target_var 维度:(789, 1)
  4. DataLoader (get_loaders):

    • train_iter = DataLoader(train_dataset, batch_size=32, shuffle=False, drop_last=True)
      • 每个 batch 的维度:(32, 10, 5)(特征),(32, 10)(历史目标),(32, 1)(目标)
    • test_iter = DataLoader(test_dataset, batch_size=32, shuffle=False, drop_last=True)
      • 每个 batch 的维度:(32, 10, 5)(特征),(32, 10)(历史目标),(32, 1)(目标)

2.1 流程图

原始数据 (1000, 5)
       |
       v
预处理 (X_train: 800, 5, y_train: 800)
       |
       v
时间序列帧化 (features: 789, 10, 5, y_hist: 789, 10, target: 789, 1)
       |
       v
DataLoader (batch_size=32, features: 32, 10, 5, y_hist: 32, 10, target: 32, 1)

2.2 总结

通过上述步骤,可以看到数据从原始形式逐步转换为适合时间序列模型训练的格式。每个步骤中的数据维度变化如下:

  1. 原始数据:(1000, 5)
  2. 预处理后:(800, 5)(训练集特征),(800,)(训练集目标)
  3. 时间序列帧化后:(789, 10, 5)(特征),(789, 10)(历史目标),(789, 1)(目标)
  4. DataLoader 中:(32, 10, 5)(特征),(32, 10)(历史目标),(32, 1)(目标)

相关文章:

  • 职坐标机器学习编程实战:调试优化与自动化测试精要
  • 【C语言】指针篇
  • Python | 机器学习中最常用的超参数及使用示例
  • window系统中的start命令详解
  • SSM架构 +Nginx+FFmpeg实现rtsp流转hls流,在前端html上实现视频播放
  • RSA-OAEP填充方案与定时攻击防护
  • 人工智能之数学基础:对线性代数中逆矩阵的思考?
  • springboot011基于springboot的课程作业管理系统(源码+包运行+LW+技术指导)
  • Android中AIDL和HIDL的区别
  • 智慧校园总体方案
  • React Native国际化实践(react-i18next)
  • Centos的ElasticSearch安装教程
  • 退化环境定位(四):基于强度的感知定位方法
  • 云计算VS网络安全,应该怎么选?
  • hooks useModule自定义hooks (二次封装AgGridReact ag-table)自定义表头,自定义表头搜索
  • 浪涌测试方法与保护电路
  • Halcon 算子 一维码检测识别、项目案例
  • 任务10:三层交换机配置
  • 从零开始实现大语言模型(十四):高阶训练技巧
  • 国内外网络安全政策动态(2025年2月)
  • 织梦做的网站能做seo吗/产品推广公司
  • cc域名做网站好吗/平台推广公司
  • 网站建设经费/google海外推广
  • 慈溪做网站哪家好/百度公司招聘岗位
  • 基因网站开发/志鸿优化设计
  • 网站上面的logo怎么做/什么平台推广效果最好